From c51a9844b869fd7cd69e5cc7658d34f61a865185 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 1 Nov 2023 06:12:42 +0100 Subject: Merging upstream version 19.0.1. Signed-off-by: Daniel Baumann --- docs/sqlglot/expressions.html | 17397 +++++++++++++++++++++------------------- 1 file changed, 9127 insertions(+), 8270 deletions(-) (limited to 'docs/sqlglot/expressions.html') diff --git a/docs/sqlglot/expressions.html b/docs/sqlglot/expressions.html index e0ba581..2ffc27f 100644 --- a/docs/sqlglot/expressions.html +++ b/docs/sqlglot/expressions.html @@ -1969,6 +1969,30 @@ + +
  • + PartitionBoundSpec + + +
  • +
  • + PartitionedOfProperty + +
  • RemoteWithConnectionModelProperty @@ -3800,6 +3824,12 @@
  • arg_types
  • +
  • + UNABBREVIATED_UNIT_NAME +
  • +
  • + VAR_LIKE +
  • unit
  • @@ -3919,6 +3949,42 @@ + +
  • + ArgMax + + +
  • +
  • + ArgMin + + +
  • +
  • + ApproxTopK + +
  • Flatten @@ -5303,6 +5369,12 @@
  • arg_types
  • +
  • + keys +
  • +
  • + values +
  • key
  • @@ -8483,4309 +8555,4379 @@ SQL expressions, such as select.

    2145 arg_types = {"this": True} 2146 2147 -2148class RemoteWithConnectionModelProperty(Property): -2149 arg_types = {"this": True} -2150 -2151 -2152class ReturnsProperty(Property): -2153 arg_types = {"this": True, "is_table": False, "table": False} -2154 -2155 -2156class RowFormatProperty(Property): -2157 arg_types = {"this": True} +2148# https://www.postgresql.org/docs/current/sql-createtable.html +2149class PartitionBoundSpec(Expression): +2150 # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...) +2151 arg_types = { +2152 "this": False, +2153 "expression": False, +2154 "from_expressions": False, +2155 "to_expressions": False, +2156 } +2157 2158 -2159 -2160class RowFormatDelimitedProperty(Property): -2161 # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml -2162 arg_types = { -2163 "fields": False, -2164 "escaped": False, -2165 "collection_items": False, -2166 "map_keys": False, -2167 "lines": False, -2168 "null": False, -2169 "serde": False, -2170 } +2159class PartitionedOfProperty(Property): +2160 # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT +2161 arg_types = {"this": True, "expression": True} +2162 +2163 +2164class RemoteWithConnectionModelProperty(Property): +2165 arg_types = {"this": True} +2166 +2167 +2168class ReturnsProperty(Property): +2169 arg_types = {"this": True, "is_table": False, "table": False} +2170 2171 -2172 -2173class RowFormatSerdeProperty(Property): -2174 arg_types = {"this": True, "serde_properties": False} +2172class RowFormatProperty(Property): +2173 arg_types = {"this": True} +2174 2175 -2176 -2177# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html -2178class QueryTransform(Expression): -2179 arg_types = { -2180 "expressions": True, -2181 "command_script": True, -2182 "schema": False, -2183 "row_format_before": False, -2184 "record_writer": False, -2185 "row_format_after": False, -2186 "record_reader": False, -2187 } +2176class RowFormatDelimitedProperty(Property): +2177 # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml +2178 arg_types = { +2179 "fields": False, +2180 "escaped": False, +2181 "collection_items": False, +2182 "map_keys": False, +2183 "lines": False, +2184 "null": False, +2185 "serde": False, +2186 } +2187 2188 -2189 -2190class SampleProperty(Property): -2191 arg_types = {"this": True} +2189class RowFormatSerdeProperty(Property): +2190 arg_types = {"this": True, "serde_properties": False} +2191 2192 -2193 -2194class SchemaCommentProperty(Property): -2195 arg_types = {"this": True} -2196 -2197 -2198class SerdeProperties(Property): -2199 arg_types = {"expressions": True} -2200 -2201 -2202class SetProperty(Property): -2203 arg_types = {"multi": True} +2193# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html +2194class QueryTransform(Expression): +2195 arg_types = { +2196 "expressions": True, +2197 "command_script": True, +2198 "schema": False, +2199 "row_format_before": False, +2200 "record_writer": False, +2201 "row_format_after": False, +2202 "record_reader": False, +2203 } 2204 2205 -2206class SettingsProperty(Property): -2207 arg_types = {"expressions": True} +2206class SampleProperty(Property): +2207 arg_types = {"this": True} 2208 2209 -2210class SortKeyProperty(Property): -2211 arg_types = {"this": True, "compound": False} +2210class SchemaCommentProperty(Property): +2211 arg_types = {"this": True} 2212 2213 -2214class SqlSecurityProperty(Property): -2215 arg_types = {"definer": True} +2214class SerdeProperties(Property): +2215 arg_types = {"expressions": True} 2216 2217 -2218class StabilityProperty(Property): -2219 arg_types = {"this": True} +2218class SetProperty(Property): +2219 arg_types = {"multi": True} 2220 2221 -2222class TemporaryProperty(Property): -2223 arg_types = {} +2222class SettingsProperty(Property): +2223 arg_types = {"expressions": True} 2224 2225 -2226class TransformModelProperty(Property): -2227 arg_types = {"expressions": True} +2226class SortKeyProperty(Property): +2227 arg_types = {"this": True, "compound": False} 2228 2229 -2230class TransientProperty(Property): -2231 arg_types = {"this": False} +2230class SqlSecurityProperty(Property): +2231 arg_types = {"definer": True} 2232 2233 -2234class VolatileProperty(Property): -2235 arg_types = {"this": False} +2234class StabilityProperty(Property): +2235 arg_types = {"this": True} 2236 2237 -2238class WithDataProperty(Property): -2239 arg_types = {"no": True, "statistics": False} +2238class TemporaryProperty(Property): +2239 arg_types = {} 2240 2241 -2242class WithJournalTableProperty(Property): -2243 arg_types = {"this": True} +2242class TransformModelProperty(Property): +2243 arg_types = {"expressions": True} 2244 2245 -2246class Properties(Expression): -2247 arg_types = {"expressions": True} +2246class TransientProperty(Property): +2247 arg_types = {"this": False} 2248 -2249 NAME_TO_PROPERTY = { -2250 "ALGORITHM": AlgorithmProperty, -2251 "AUTO_INCREMENT": AutoIncrementProperty, -2252 "CHARACTER SET": CharacterSetProperty, -2253 "CLUSTERED_BY": ClusteredByProperty, -2254 "COLLATE": CollateProperty, -2255 "COMMENT": SchemaCommentProperty, -2256 "DEFINER": DefinerProperty, -2257 "DISTKEY": DistKeyProperty, -2258 "DISTSTYLE": DistStyleProperty, -2259 "ENGINE": EngineProperty, -2260 "EXECUTE AS": ExecuteAsProperty, -2261 "FORMAT": FileFormatProperty, -2262 "LANGUAGE": LanguageProperty, -2263 "LOCATION": LocationProperty, -2264 "PARTITIONED_BY": PartitionedByProperty, -2265 "RETURNS": ReturnsProperty, -2266 "ROW_FORMAT": RowFormatProperty, -2267 "SORTKEY": SortKeyProperty, -2268 } -2269 -2270 PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()} -2271 -2272 # CREATE property locations -2273 # Form: schema specified -2274 # create [POST_CREATE] -2275 # table a [POST_NAME] -2276 # (b int) [POST_SCHEMA] -2277 # with ([POST_WITH]) -2278 # index (b) [POST_INDEX] -2279 # -2280 # Form: alias selection -2281 # create [POST_CREATE] -2282 # table a [POST_NAME] -2283 # as [POST_ALIAS] (select * from b) [POST_EXPRESSION] -2284 # index (c) [POST_INDEX] -2285 class Location(AutoName): -2286 POST_CREATE = auto() -2287 POST_NAME = auto() -2288 POST_SCHEMA = auto() -2289 POST_WITH = auto() -2290 POST_ALIAS = auto() -2291 POST_EXPRESSION = auto() -2292 POST_INDEX = auto() -2293 UNSUPPORTED = auto() -2294 -2295 @classmethod -2296 def from_dict(cls, properties_dict: t.Dict) -> Properties: -2297 expressions = [] -2298 for key, value in properties_dict.items(): -2299 property_cls = cls.NAME_TO_PROPERTY.get(key.upper()) -2300 if property_cls: -2301 expressions.append(property_cls(this=convert(value))) -2302 else: -2303 expressions.append(Property(this=Literal.string(key), value=convert(value))) -2304 -2305 return cls(expressions=expressions) -2306 -2307 -2308class Qualify(Expression): -2309 pass +2249 +2250class VolatileProperty(Property): +2251 arg_types = {"this": False} +2252 +2253 +2254class WithDataProperty(Property): +2255 arg_types = {"no": True, "statistics": False} +2256 +2257 +2258class WithJournalTableProperty(Property): +2259 arg_types = {"this": True} +2260 +2261 +2262class Properties(Expression): +2263 arg_types = {"expressions": True} +2264 +2265 NAME_TO_PROPERTY = { +2266 "ALGORITHM": AlgorithmProperty, +2267 "AUTO_INCREMENT": AutoIncrementProperty, +2268 "CHARACTER SET": CharacterSetProperty, +2269 "CLUSTERED_BY": ClusteredByProperty, +2270 "COLLATE": CollateProperty, +2271 "COMMENT": SchemaCommentProperty, +2272 "DEFINER": DefinerProperty, +2273 "DISTKEY": DistKeyProperty, +2274 "DISTSTYLE": DistStyleProperty, +2275 "ENGINE": EngineProperty, +2276 "EXECUTE AS": ExecuteAsProperty, +2277 "FORMAT": FileFormatProperty, +2278 "LANGUAGE": LanguageProperty, +2279 "LOCATION": LocationProperty, +2280 "PARTITIONED_BY": PartitionedByProperty, +2281 "RETURNS": ReturnsProperty, +2282 "ROW_FORMAT": RowFormatProperty, +2283 "SORTKEY": SortKeyProperty, +2284 } +2285 +2286 PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()} +2287 +2288 # CREATE property locations +2289 # Form: schema specified +2290 # create [POST_CREATE] +2291 # table a [POST_NAME] +2292 # (b int) [POST_SCHEMA] +2293 # with ([POST_WITH]) +2294 # index (b) [POST_INDEX] +2295 # +2296 # Form: alias selection +2297 # create [POST_CREATE] +2298 # table a [POST_NAME] +2299 # as [POST_ALIAS] (select * from b) [POST_EXPRESSION] +2300 # index (c) [POST_INDEX] +2301 class Location(AutoName): +2302 POST_CREATE = auto() +2303 POST_NAME = auto() +2304 POST_SCHEMA = auto() +2305 POST_WITH = auto() +2306 POST_ALIAS = auto() +2307 POST_EXPRESSION = auto() +2308 POST_INDEX = auto() +2309 UNSUPPORTED = auto() 2310 -2311 -2312class InputOutputFormat(Expression): -2313 arg_types = {"input_format": False, "output_format": False} -2314 -2315 -2316# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql -2317class Return(Expression): -2318 pass -2319 +2311 @classmethod +2312 def from_dict(cls, properties_dict: t.Dict) -> Properties: +2313 expressions = [] +2314 for key, value in properties_dict.items(): +2315 property_cls = cls.NAME_TO_PROPERTY.get(key.upper()) +2316 if property_cls: +2317 expressions.append(property_cls(this=convert(value))) +2318 else: +2319 expressions.append(Property(this=Literal.string(key), value=convert(value))) 2320 -2321class Reference(Expression): -2322 arg_types = {"this": True, "expressions": False, "options": False} +2321 return cls(expressions=expressions) +2322 2323 -2324 -2325class Tuple(Expression): -2326 arg_types = {"expressions": False} +2324class Qualify(Expression): +2325 pass +2326 2327 -2328 def isin( -2329 self, -2330 *expressions: t.Any, -2331 query: t.Optional[ExpOrStr] = None, -2332 unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None, -2333 copy: bool = True, -2334 **opts, -2335 ) -> In: -2336 return In( -2337 this=maybe_copy(self, copy), -2338 expressions=[convert(e, copy=copy) for e in expressions], -2339 query=maybe_parse(query, copy=copy, **opts) if query else None, -2340 unnest=Unnest( -2341 expressions=[ -2342 maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest) -2343 ] -2344 ) -2345 if unnest -2346 else None, -2347 ) -2348 -2349 -2350class Subqueryable(Unionable): -2351 def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery: -2352 """ -2353 Convert this expression to an aliased expression that can be used as a Subquery. -2354 -2355 Example: -2356 >>> subquery = Select().select("x").from_("tbl").subquery() -2357 >>> Select().select("x").from_(subquery).sql() -2358 'SELECT x FROM (SELECT x FROM tbl)' -2359 -2360 Args: -2361 alias (str | Identifier): an optional alias for the subquery -2362 copy (bool): if `False`, modify this expression instance in-place. -2363 -2364 Returns: -2365 Alias: the subquery -2366 """ -2367 instance = maybe_copy(self, copy) -2368 if not isinstance(alias, Expression): -2369 alias = TableAlias(this=to_identifier(alias)) if alias else None +2328class InputOutputFormat(Expression): +2329 arg_types = {"input_format": False, "output_format": False} +2330 +2331 +2332# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql +2333class Return(Expression): +2334 pass +2335 +2336 +2337class Reference(Expression): +2338 arg_types = {"this": True, "expressions": False, "options": False} +2339 +2340 +2341class Tuple(Expression): +2342 arg_types = {"expressions": False} +2343 +2344 def isin( +2345 self, +2346 *expressions: t.Any, +2347 query: t.Optional[ExpOrStr] = None, +2348 unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None, +2349 copy: bool = True, +2350 **opts, +2351 ) -> In: +2352 return In( +2353 this=maybe_copy(self, copy), +2354 expressions=[convert(e, copy=copy) for e in expressions], +2355 query=maybe_parse(query, copy=copy, **opts) if query else None, +2356 unnest=Unnest( +2357 expressions=[ +2358 maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest) +2359 ] +2360 ) +2361 if unnest +2362 else None, +2363 ) +2364 +2365 +2366class Subqueryable(Unionable): +2367 def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery: +2368 """ +2369 Convert this expression to an aliased expression that can be used as a Subquery. 2370 -2371 return Subquery(this=instance, alias=alias) -2372 -2373 def limit( -2374 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts -2375 ) -> Select: -2376 raise NotImplementedError -2377 -2378 @property -2379 def ctes(self): -2380 with_ = self.args.get("with") -2381 if not with_: -2382 return [] -2383 return with_.expressions -2384 -2385 @property -2386 def selects(self) -> t.List[Expression]: -2387 raise NotImplementedError("Subqueryable objects must implement `selects`") +2371 Example: +2372 >>> subquery = Select().select("x").from_("tbl").subquery() +2373 >>> Select().select("x").from_(subquery).sql() +2374 'SELECT x FROM (SELECT x FROM tbl)' +2375 +2376 Args: +2377 alias (str | Identifier): an optional alias for the subquery +2378 copy (bool): if `False`, modify this expression instance in-place. +2379 +2380 Returns: +2381 Alias: the subquery +2382 """ +2383 instance = maybe_copy(self, copy) +2384 if not isinstance(alias, Expression): +2385 alias = TableAlias(this=to_identifier(alias)) if alias else None +2386 +2387 return Subquery(this=instance, alias=alias) 2388 -2389 @property -2390 def named_selects(self) -> t.List[str]: -2391 raise NotImplementedError("Subqueryable objects must implement `named_selects`") -2392 -2393 def select( -2394 self, -2395 *expressions: t.Optional[ExpOrStr], -2396 append: bool = True, -2397 dialect: DialectType = None, -2398 copy: bool = True, -2399 **opts, -2400 ) -> Subqueryable: -2401 raise NotImplementedError("Subqueryable objects must implement `select`") -2402 -2403 def with_( -2404 self, -2405 alias: ExpOrStr, -2406 as_: ExpOrStr, -2407 recursive: t.Optional[bool] = None, -2408 append: bool = True, -2409 dialect: DialectType = None, -2410 copy: bool = True, -2411 **opts, -2412 ) -> Subqueryable: -2413 """ -2414 Append to or set the common table expressions. -2415 -2416 Example: -2417 >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql() -2418 'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2' -2419 -2420 Args: -2421 alias: the SQL code string to parse as the table name. -2422 If an `Expression` instance is passed, this is used as-is. -2423 as_: the SQL code string to parse as the table expression. -2424 If an `Expression` instance is passed, it will be used as-is. -2425 recursive: set the RECURSIVE part of the expression. Defaults to `False`. -2426 append: if `True`, add to any existing expressions. -2427 Otherwise, this resets the expressions. -2428 dialect: the dialect used to parse the input expression. -2429 copy: if `False`, modify this expression instance in-place. -2430 opts: other options to use to parse the input expressions. +2389 def limit( +2390 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts +2391 ) -> Select: +2392 raise NotImplementedError +2393 +2394 @property +2395 def ctes(self): +2396 with_ = self.args.get("with") +2397 if not with_: +2398 return [] +2399 return with_.expressions +2400 +2401 @property +2402 def selects(self) -> t.List[Expression]: +2403 raise NotImplementedError("Subqueryable objects must implement `selects`") +2404 +2405 @property +2406 def named_selects(self) -> t.List[str]: +2407 raise NotImplementedError("Subqueryable objects must implement `named_selects`") +2408 +2409 def select( +2410 self, +2411 *expressions: t.Optional[ExpOrStr], +2412 append: bool = True, +2413 dialect: DialectType = None, +2414 copy: bool = True, +2415 **opts, +2416 ) -> Subqueryable: +2417 raise NotImplementedError("Subqueryable objects must implement `select`") +2418 +2419 def with_( +2420 self, +2421 alias: ExpOrStr, +2422 as_: ExpOrStr, +2423 recursive: t.Optional[bool] = None, +2424 append: bool = True, +2425 dialect: DialectType = None, +2426 copy: bool = True, +2427 **opts, +2428 ) -> Subqueryable: +2429 """ +2430 Append to or set the common table expressions. 2431 -2432 Returns: -2433 The modified expression. -2434 """ -2435 return _apply_cte_builder( -2436 self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts -2437 ) -2438 -2439 -2440QUERY_MODIFIERS = { -2441 "match": False, -2442 "laterals": False, -2443 "joins": False, -2444 "connect": False, -2445 "pivots": False, -2446 "where": False, -2447 "group": False, -2448 "having": False, -2449 "qualify": False, -2450 "windows": False, -2451 "distribute": False, -2452 "sort": False, -2453 "cluster": False, -2454 "order": False, -2455 "limit": False, -2456 "offset": False, -2457 "locks": False, -2458 "sample": False, -2459 "settings": False, -2460 "format": False, -2461} -2462 -2463 -2464# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16 -2465class WithTableHint(Expression): -2466 arg_types = {"expressions": True} -2467 -2468 -2469# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html -2470class IndexTableHint(Expression): -2471 arg_types = {"this": True, "expressions": False, "target": False} -2472 -2473 -2474class Table(Expression): -2475 arg_types = { -2476 "this": True, -2477 "alias": False, -2478 "db": False, -2479 "catalog": False, -2480 "laterals": False, -2481 "joins": False, -2482 "pivots": False, -2483 "hints": False, -2484 "system_time": False, -2485 "version": False, -2486 "format": False, -2487 "pattern": False, -2488 "index": False, -2489 } -2490 -2491 @property -2492 def name(self) -> str: -2493 if isinstance(self.this, Func): -2494 return "" -2495 return self.this.name -2496 -2497 @property -2498 def db(self) -> str: -2499 return self.text("db") -2500 -2501 @property -2502 def catalog(self) -> str: -2503 return self.text("catalog") -2504 -2505 @property -2506 def selects(self) -> t.List[Expression]: -2507 return [] -2508 -2509 @property -2510 def named_selects(self) -> t.List[str]: -2511 return [] -2512 -2513 @property -2514 def parts(self) -> t.List[Expression]: -2515 """Return the parts of a table in order catalog, db, table.""" -2516 parts: t.List[Expression] = [] +2432 Example: +2433 >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql() +2434 'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2' +2435 +2436 Args: +2437 alias: the SQL code string to parse as the table name. +2438 If an `Expression` instance is passed, this is used as-is. +2439 as_: the SQL code string to parse as the table expression. +2440 If an `Expression` instance is passed, it will be used as-is. +2441 recursive: set the RECURSIVE part of the expression. Defaults to `False`. +2442 append: if `True`, add to any existing expressions. +2443 Otherwise, this resets the expressions. +2444 dialect: the dialect used to parse the input expression. +2445 copy: if `False`, modify this expression instance in-place. +2446 opts: other options to use to parse the input expressions. +2447 +2448 Returns: +2449 The modified expression. +2450 """ +2451 return _apply_cte_builder( +2452 self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts +2453 ) +2454 +2455 +2456QUERY_MODIFIERS = { +2457 "match": False, +2458 "laterals": False, +2459 "joins": False, +2460 "connect": False, +2461 "pivots": False, +2462 "where": False, +2463 "group": False, +2464 "having": False, +2465 "qualify": False, +2466 "windows": False, +2467 "distribute": False, +2468 "sort": False, +2469 "cluster": False, +2470 "order": False, +2471 "limit": False, +2472 "offset": False, +2473 "locks": False, +2474 "sample": False, +2475 "settings": False, +2476 "format": False, +2477} +2478 +2479 +2480# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16 +2481class WithTableHint(Expression): +2482 arg_types = {"expressions": True} +2483 +2484 +2485# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html +2486class IndexTableHint(Expression): +2487 arg_types = {"this": True, "expressions": False, "target": False} +2488 +2489 +2490class Table(Expression): +2491 arg_types = { +2492 "this": True, +2493 "alias": False, +2494 "db": False, +2495 "catalog": False, +2496 "laterals": False, +2497 "joins": False, +2498 "pivots": False, +2499 "hints": False, +2500 "system_time": False, +2501 "version": False, +2502 "format": False, +2503 "pattern": False, +2504 "index": False, +2505 "ordinality": False, +2506 } +2507 +2508 @property +2509 def name(self) -> str: +2510 if isinstance(self.this, Func): +2511 return "" +2512 return self.this.name +2513 +2514 @property +2515 def db(self) -> str: +2516 return self.text("db") 2517 -2518 for arg in ("catalog", "db", "this"): -2519 part = self.args.get(arg) -2520 -2521 if isinstance(part, Dot): -2522 parts.extend(part.flatten()) -2523 elif isinstance(part, Expression): -2524 parts.append(part) +2518 @property +2519 def catalog(self) -> str: +2520 return self.text("catalog") +2521 +2522 @property +2523 def selects(self) -> t.List[Expression]: +2524 return [] 2525 -2526 return parts -2527 -2528 -2529class Union(Subqueryable): -2530 arg_types = { -2531 "with": False, -2532 "this": True, -2533 "expression": True, -2534 "distinct": False, -2535 "by_name": False, -2536 **QUERY_MODIFIERS, -2537 } -2538 -2539 def limit( -2540 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts -2541 ) -> Select: -2542 """ -2543 Set the LIMIT expression. +2526 @property +2527 def named_selects(self) -> t.List[str]: +2528 return [] +2529 +2530 @property +2531 def parts(self) -> t.List[Expression]: +2532 """Return the parts of a table in order catalog, db, table.""" +2533 parts: t.List[Expression] = [] +2534 +2535 for arg in ("catalog", "db", "this"): +2536 part = self.args.get(arg) +2537 +2538 if isinstance(part, Dot): +2539 parts.extend(part.flatten()) +2540 elif isinstance(part, Expression): +2541 parts.append(part) +2542 +2543 return parts 2544 -2545 Example: -2546 >>> select("1").union(select("1")).limit(1).sql() -2547 'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1' -2548 -2549 Args: -2550 expression: the SQL code string to parse. -2551 This can also be an integer. -2552 If a `Limit` instance is passed, this is used as-is. -2553 If another `Expression` instance is passed, it will be wrapped in a `Limit`. -2554 dialect: the dialect used to parse the input expression. -2555 copy: if `False`, modify this expression instance in-place. -2556 opts: other options to use to parse the input expressions. -2557 -2558 Returns: -2559 The limited subqueryable. -2560 """ -2561 return ( -2562 select("*") -2563 .from_(self.subquery(alias="_l_0", copy=copy)) -2564 .limit(expression, dialect=dialect, copy=False, **opts) -2565 ) -2566 -2567 def select( -2568 self, -2569 *expressions: t.Optional[ExpOrStr], -2570 append: bool = True, -2571 dialect: DialectType = None, -2572 copy: bool = True, -2573 **opts, -2574 ) -> Union: -2575 """Append to or set the SELECT of the union recursively. -2576 -2577 Example: -2578 >>> from sqlglot import parse_one -2579 >>> parse_one("select a from x union select a from y union select a from z").select("b").sql() -2580 'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z' -2581 -2582 Args: -2583 *expressions: the SQL code strings to parse. -2584 If an `Expression` instance is passed, it will be used as-is. -2585 append: if `True`, add to any existing expressions. -2586 Otherwise, this resets the expressions. -2587 dialect: the dialect used to parse the input expressions. -2588 copy: if `False`, modify this expression instance in-place. -2589 opts: other options to use to parse the input expressions. -2590 -2591 Returns: -2592 Union: the modified expression. -2593 """ -2594 this = self.copy() if copy else self -2595 this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts) -2596 this.expression.unnest().select( -2597 *expressions, append=append, dialect=dialect, copy=False, **opts -2598 ) -2599 return this -2600 -2601 @property -2602 def named_selects(self) -> t.List[str]: -2603 return self.this.unnest().named_selects -2604 -2605 @property -2606 def is_star(self) -> bool: -2607 return self.this.is_star or self.expression.is_star -2608 -2609 @property -2610 def selects(self) -> t.List[Expression]: -2611 return self.this.unnest().selects -2612 -2613 @property -2614 def left(self) -> Expression: -2615 return self.this -2616 -2617 @property -2618 def right(self) -> Expression: -2619 return self.expression -2620 +2545 +2546class Union(Subqueryable): +2547 arg_types = { +2548 "with": False, +2549 "this": True, +2550 "expression": True, +2551 "distinct": False, +2552 "by_name": False, +2553 **QUERY_MODIFIERS, +2554 } +2555 +2556 def limit( +2557 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts +2558 ) -> Select: +2559 """ +2560 Set the LIMIT expression. +2561 +2562 Example: +2563 >>> select("1").union(select("1")).limit(1).sql() +2564 'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1' +2565 +2566 Args: +2567 expression: the SQL code string to parse. +2568 This can also be an integer. +2569 If a `Limit` instance is passed, this is used as-is. +2570 If another `Expression` instance is passed, it will be wrapped in a `Limit`. +2571 dialect: the dialect used to parse the input expression. +2572 copy: if `False`, modify this expression instance in-place. +2573 opts: other options to use to parse the input expressions. +2574 +2575 Returns: +2576 The limited subqueryable. +2577 """ +2578 return ( +2579 select("*") +2580 .from_(self.subquery(alias="_l_0", copy=copy)) +2581 .limit(expression, dialect=dialect, copy=False, **opts) +2582 ) +2583 +2584 def select( +2585 self, +2586 *expressions: t.Optional[ExpOrStr], +2587 append: bool = True, +2588 dialect: DialectType = None, +2589 copy: bool = True, +2590 **opts, +2591 ) -> Union: +2592 """Append to or set the SELECT of the union recursively. +2593 +2594 Example: +2595 >>> from sqlglot import parse_one +2596 >>> parse_one("select a from x union select a from y union select a from z").select("b").sql() +2597 'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z' +2598 +2599 Args: +2600 *expressions: the SQL code strings to parse. +2601 If an `Expression` instance is passed, it will be used as-is. +2602 append: if `True`, add to any existing expressions. +2603 Otherwise, this resets the expressions. +2604 dialect: the dialect used to parse the input expressions. +2605 copy: if `False`, modify this expression instance in-place. +2606 opts: other options to use to parse the input expressions. +2607 +2608 Returns: +2609 Union: the modified expression. +2610 """ +2611 this = self.copy() if copy else self +2612 this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts) +2613 this.expression.unnest().select( +2614 *expressions, append=append, dialect=dialect, copy=False, **opts +2615 ) +2616 return this +2617 +2618 @property +2619 def named_selects(self) -> t.List[str]: +2620 return self.this.unnest().named_selects 2621 -2622class Except(Union): -2623 pass -2624 +2622 @property +2623 def is_star(self) -> bool: +2624 return self.this.is_star or self.expression.is_star 2625 -2626class Intersect(Union): -2627 pass -2628 +2626 @property +2627 def selects(self) -> t.List[Expression]: +2628 return self.this.unnest().selects 2629 -2630class Unnest(UDTF): -2631 arg_types = { -2632 "expressions": True, -2633 "alias": False, -2634 "offset": False, -2635 } -2636 +2630 @property +2631 def left(self) -> Expression: +2632 return self.this +2633 +2634 @property +2635 def right(self) -> Expression: +2636 return self.expression 2637 -2638class Update(Expression): -2639 arg_types = { -2640 "with": False, -2641 "this": False, -2642 "expressions": True, -2643 "from": False, -2644 "where": False, -2645 "returning": False, -2646 "order": False, -2647 "limit": False, -2648 } -2649 -2650 -2651class Values(UDTF): -2652 arg_types = { -2653 "expressions": True, -2654 "ordinality": False, -2655 "alias": False, -2656 } -2657 -2658 -2659class Var(Expression): -2660 pass -2661 -2662 -2663class Version(Expression): -2664 """ -2665 Time travel, iceberg, bigquery etc -2666 https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots -2667 https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html -2668 https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of -2669 https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16 -2670 this is either TIMESTAMP or VERSION -2671 kind is ("AS OF", "BETWEEN") -2672 """ -2673 -2674 arg_types = {"this": True, "kind": True, "expression": False} +2638 +2639class Except(Union): +2640 pass +2641 +2642 +2643class Intersect(Union): +2644 pass +2645 +2646 +2647class Unnest(UDTF): +2648 arg_types = { +2649 "expressions": True, +2650 "alias": False, +2651 "offset": False, +2652 } +2653 +2654 +2655class Update(Expression): +2656 arg_types = { +2657 "with": False, +2658 "this": False, +2659 "expressions": True, +2660 "from": False, +2661 "where": False, +2662 "returning": False, +2663 "order": False, +2664 "limit": False, +2665 } +2666 +2667 +2668class Values(UDTF): +2669 arg_types = {"expressions": True, "alias": False} +2670 +2671 +2672class Var(Expression): +2673 pass +2674 2675 -2676 -2677class Schema(Expression): -2678 arg_types = {"this": False, "expressions": False} -2679 -2680 -2681# https://dev.mysql.com/doc/refman/8.0/en/select.html -2682# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html -2683class Lock(Expression): -2684 arg_types = {"update": True, "expressions": False, "wait": False} -2685 +2676class Version(Expression): +2677 """ +2678 Time travel, iceberg, bigquery etc +2679 https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots +2680 https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html +2681 https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of +2682 https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16 +2683 this is either TIMESTAMP or VERSION +2684 kind is ("AS OF", "BETWEEN") +2685 """ 2686 -2687class Select(Subqueryable): -2688 arg_types = { -2689 "with": False, -2690 "kind": False, -2691 "expressions": False, -2692 "hint": False, -2693 "distinct": False, -2694 "into": False, -2695 "from": False, -2696 **QUERY_MODIFIERS, -2697 } +2687 arg_types = {"this": True, "kind": True, "expression": False} +2688 +2689 +2690class Schema(Expression): +2691 arg_types = {"this": False, "expressions": False} +2692 +2693 +2694# https://dev.mysql.com/doc/refman/8.0/en/select.html +2695# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html +2696class Lock(Expression): +2697 arg_types = {"update": True, "expressions": False, "wait": False} 2698 -2699 def from_( -2700 self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts -2701 ) -> Select: -2702 """ -2703 Set the FROM expression. -2704 -2705 Example: -2706 >>> Select().from_("tbl").select("x").sql() -2707 'SELECT x FROM tbl' -2708 -2709 Args: -2710 expression : the SQL code strings to parse. -2711 If a `From` instance is passed, this is used as-is. -2712 If another `Expression` instance is passed, it will be wrapped in a `From`. -2713 dialect: the dialect used to parse the input expression. -2714 copy: if `False`, modify this expression instance in-place. -2715 opts: other options to use to parse the input expressions. -2716 -2717 Returns: -2718 The modified Select expression. -2719 """ -2720 return _apply_builder( -2721 expression=expression, -2722 instance=self, -2723 arg="from", -2724 into=From, -2725 prefix="FROM", -2726 dialect=dialect, -2727 copy=copy, -2728 **opts, -2729 ) -2730 -2731 def group_by( -2732 self, -2733 *expressions: t.Optional[ExpOrStr], -2734 append: bool = True, -2735 dialect: DialectType = None, -2736 copy: bool = True, -2737 **opts, -2738 ) -> Select: -2739 """ -2740 Set the GROUP BY expression. -2741 -2742 Example: -2743 >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql() -2744 'SELECT x, COUNT(1) FROM tbl GROUP BY x' -2745 -2746 Args: -2747 *expressions: the SQL code strings to parse. -2748 If a `Group` instance is passed, this is used as-is. -2749 If another `Expression` instance is passed, it will be wrapped in a `Group`. -2750 If nothing is passed in then a group by is not applied to the expression -2751 append: if `True`, add to any existing expressions. -2752 Otherwise, this flattens all the `Group` expression into a single expression. -2753 dialect: the dialect used to parse the input expression. -2754 copy: if `False`, modify this expression instance in-place. -2755 opts: other options to use to parse the input expressions. -2756 -2757 Returns: -2758 The modified Select expression. -2759 """ -2760 if not expressions: -2761 return self if not copy else self.copy() -2762 -2763 return _apply_child_list_builder( -2764 *expressions, -2765 instance=self, -2766 arg="group", -2767 append=append, -2768 copy=copy, -2769 prefix="GROUP BY", -2770 into=Group, -2771 dialect=dialect, -2772 **opts, -2773 ) -2774 -2775 def order_by( -2776 self, -2777 *expressions: t.Optional[ExpOrStr], -2778 append: bool = True, -2779 dialect: DialectType = None, -2780 copy: bool = True, -2781 **opts, -2782 ) -> Select: -2783 """ -2784 Set the ORDER BY expression. -2785 -2786 Example: -2787 >>> Select().from_("tbl").select("x").order_by("x DESC").sql() -2788 'SELECT x FROM tbl ORDER BY x DESC' -2789 -2790 Args: -2791 *expressions: the SQL code strings to parse. -2792 If a `Group` instance is passed, this is used as-is. -2793 If another `Expression` instance is passed, it will be wrapped in a `Order`. -2794 append: if `True`, add to any existing expressions. -2795 Otherwise, this flattens all the `Order` expression into a single expression. -2796 dialect: the dialect used to parse the input expression. -2797 copy: if `False`, modify this expression instance in-place. -2798 opts: other options to use to parse the input expressions. -2799 -2800 Returns: -2801 The modified Select expression. -2802 """ -2803 return _apply_child_list_builder( -2804 *expressions, -2805 instance=self, -2806 arg="order", -2807 append=append, -2808 copy=copy, -2809 prefix="ORDER BY", -2810 into=Order, -2811 dialect=dialect, -2812 **opts, -2813 ) -2814 -2815 def sort_by( -2816 self, -2817 *expressions: t.Optional[ExpOrStr], -2818 append: bool = True, -2819 dialect: DialectType = None, -2820 copy: bool = True, -2821 **opts, -2822 ) -> Select: -2823 """ -2824 Set the SORT BY expression. -2825 -2826 Example: -2827 >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive") -2828 'SELECT x FROM tbl SORT BY x DESC' -2829 -2830 Args: -2831 *expressions: the SQL code strings to parse. -2832 If a `Group` instance is passed, this is used as-is. -2833 If another `Expression` instance is passed, it will be wrapped in a `SORT`. -2834 append: if `True`, add to any existing expressions. -2835 Otherwise, this flattens all the `Order` expression into a single expression. -2836 dialect: the dialect used to parse the input expression. -2837 copy: if `False`, modify this expression instance in-place. -2838 opts: other options to use to parse the input expressions. -2839 -2840 Returns: -2841 The modified Select expression. -2842 """ -2843 return _apply_child_list_builder( -2844 *expressions, -2845 instance=self, -2846 arg="sort", -2847 append=append, -2848 copy=copy, -2849 prefix="SORT BY", -2850 into=Sort, -2851 dialect=dialect, -2852 **opts, -2853 ) -2854 -2855 def cluster_by( -2856 self, -2857 *expressions: t.Optional[ExpOrStr], -2858 append: bool = True, -2859 dialect: DialectType = None, -2860 copy: bool = True, -2861 **opts, -2862 ) -> Select: -2863 """ -2864 Set the CLUSTER BY expression. -2865 -2866 Example: -2867 >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive") -2868 'SELECT x FROM tbl CLUSTER BY x DESC' -2869 -2870 Args: -2871 *expressions: the SQL code strings to parse. -2872 If a `Group` instance is passed, this is used as-is. -2873 If another `Expression` instance is passed, it will be wrapped in a `Cluster`. -2874 append: if `True`, add to any existing expressions. -2875 Otherwise, this flattens all the `Order` expression into a single expression. -2876 dialect: the dialect used to parse the input expression. -2877 copy: if `False`, modify this expression instance in-place. -2878 opts: other options to use to parse the input expressions. -2879 -2880 Returns: -2881 The modified Select expression. -2882 """ -2883 return _apply_child_list_builder( -2884 *expressions, -2885 instance=self, -2886 arg="cluster", -2887 append=append, -2888 copy=copy, -2889 prefix="CLUSTER BY", -2890 into=Cluster, -2891 dialect=dialect, -2892 **opts, -2893 ) -2894 -2895 def limit( -2896 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts -2897 ) -> Select: -2898 """ -2899 Set the LIMIT expression. -2900 -2901 Example: -2902 >>> Select().from_("tbl").select("x").limit(10).sql() -2903 'SELECT x FROM tbl LIMIT 10' -2904 -2905 Args: -2906 expression: the SQL code string to parse. -2907 This can also be an integer. -2908 If a `Limit` instance is passed, this is used as-is. -2909 If another `Expression` instance is passed, it will be wrapped in a `Limit`. -2910 dialect: the dialect used to parse the input expression. -2911 copy: if `False`, modify this expression instance in-place. -2912 opts: other options to use to parse the input expressions. +2699 +2700class Select(Subqueryable): +2701 arg_types = { +2702 "with": False, +2703 "kind": False, +2704 "expressions": False, +2705 "hint": False, +2706 "distinct": False, +2707 "into": False, +2708 "from": False, +2709 **QUERY_MODIFIERS, +2710 } +2711 +2712 def from_( +2713 self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts +2714 ) -> Select: +2715 """ +2716 Set the FROM expression. +2717 +2718 Example: +2719 >>> Select().from_("tbl").select("x").sql() +2720 'SELECT x FROM tbl' +2721 +2722 Args: +2723 expression : the SQL code strings to parse. +2724 If a `From` instance is passed, this is used as-is. +2725 If another `Expression` instance is passed, it will be wrapped in a `From`. +2726 dialect: the dialect used to parse the input expression. +2727 copy: if `False`, modify this expression instance in-place. +2728 opts: other options to use to parse the input expressions. +2729 +2730 Returns: +2731 The modified Select expression. +2732 """ +2733 return _apply_builder( +2734 expression=expression, +2735 instance=self, +2736 arg="from", +2737 into=From, +2738 prefix="FROM", +2739 dialect=dialect, +2740 copy=copy, +2741 **opts, +2742 ) +2743 +2744 def group_by( +2745 self, +2746 *expressions: t.Optional[ExpOrStr], +2747 append: bool = True, +2748 dialect: DialectType = None, +2749 copy: bool = True, +2750 **opts, +2751 ) -> Select: +2752 """ +2753 Set the GROUP BY expression. +2754 +2755 Example: +2756 >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql() +2757 'SELECT x, COUNT(1) FROM tbl GROUP BY x' +2758 +2759 Args: +2760 *expressions: the SQL code strings to parse. +2761 If a `Group` instance is passed, this is used as-is. +2762 If another `Expression` instance is passed, it will be wrapped in a `Group`. +2763 If nothing is passed in then a group by is not applied to the expression +2764 append: if `True`, add to any existing expressions. +2765 Otherwise, this flattens all the `Group` expression into a single expression. +2766 dialect: the dialect used to parse the input expression. +2767 copy: if `False`, modify this expression instance in-place. +2768 opts: other options to use to parse the input expressions. +2769 +2770 Returns: +2771 The modified Select expression. +2772 """ +2773 if not expressions: +2774 return self if not copy else self.copy() +2775 +2776 return _apply_child_list_builder( +2777 *expressions, +2778 instance=self, +2779 arg="group", +2780 append=append, +2781 copy=copy, +2782 prefix="GROUP BY", +2783 into=Group, +2784 dialect=dialect, +2785 **opts, +2786 ) +2787 +2788 def order_by( +2789 self, +2790 *expressions: t.Optional[ExpOrStr], +2791 append: bool = True, +2792 dialect: DialectType = None, +2793 copy: bool = True, +2794 **opts, +2795 ) -> Select: +2796 """ +2797 Set the ORDER BY expression. +2798 +2799 Example: +2800 >>> Select().from_("tbl").select("x").order_by("x DESC").sql() +2801 'SELECT x FROM tbl ORDER BY x DESC' +2802 +2803 Args: +2804 *expressions: the SQL code strings to parse. +2805 If a `Group` instance is passed, this is used as-is. +2806 If another `Expression` instance is passed, it will be wrapped in a `Order`. +2807 append: if `True`, add to any existing expressions. +2808 Otherwise, this flattens all the `Order` expression into a single expression. +2809 dialect: the dialect used to parse the input expression. +2810 copy: if `False`, modify this expression instance in-place. +2811 opts: other options to use to parse the input expressions. +2812 +2813 Returns: +2814 The modified Select expression. +2815 """ +2816 return _apply_child_list_builder( +2817 *expressions, +2818 instance=self, +2819 arg="order", +2820 append=append, +2821 copy=copy, +2822 prefix="ORDER BY", +2823 into=Order, +2824 dialect=dialect, +2825 **opts, +2826 ) +2827 +2828 def sort_by( +2829 self, +2830 *expressions: t.Optional[ExpOrStr], +2831 append: bool = True, +2832 dialect: DialectType = None, +2833 copy: bool = True, +2834 **opts, +2835 ) -> Select: +2836 """ +2837 Set the SORT BY expression. +2838 +2839 Example: +2840 >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive") +2841 'SELECT x FROM tbl SORT BY x DESC' +2842 +2843 Args: +2844 *expressions: the SQL code strings to parse. +2845 If a `Group` instance is passed, this is used as-is. +2846 If another `Expression` instance is passed, it will be wrapped in a `SORT`. +2847 append: if `True`, add to any existing expressions. +2848 Otherwise, this flattens all the `Order` expression into a single expression. +2849 dialect: the dialect used to parse the input expression. +2850 copy: if `False`, modify this expression instance in-place. +2851 opts: other options to use to parse the input expressions. +2852 +2853 Returns: +2854 The modified Select expression. +2855 """ +2856 return _apply_child_list_builder( +2857 *expressions, +2858 instance=self, +2859 arg="sort", +2860 append=append, +2861 copy=copy, +2862 prefix="SORT BY", +2863 into=Sort, +2864 dialect=dialect, +2865 **opts, +2866 ) +2867 +2868 def cluster_by( +2869 self, +2870 *expressions: t.Optional[ExpOrStr], +2871 append: bool = True, +2872 dialect: DialectType = None, +2873 copy: bool = True, +2874 **opts, +2875 ) -> Select: +2876 """ +2877 Set the CLUSTER BY expression. +2878 +2879 Example: +2880 >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive") +2881 'SELECT x FROM tbl CLUSTER BY x DESC' +2882 +2883 Args: +2884 *expressions: the SQL code strings to parse. +2885 If a `Group` instance is passed, this is used as-is. +2886 If another `Expression` instance is passed, it will be wrapped in a `Cluster`. +2887 append: if `True`, add to any existing expressions. +2888 Otherwise, this flattens all the `Order` expression into a single expression. +2889 dialect: the dialect used to parse the input expression. +2890 copy: if `False`, modify this expression instance in-place. +2891 opts: other options to use to parse the input expressions. +2892 +2893 Returns: +2894 The modified Select expression. +2895 """ +2896 return _apply_child_list_builder( +2897 *expressions, +2898 instance=self, +2899 arg="cluster", +2900 append=append, +2901 copy=copy, +2902 prefix="CLUSTER BY", +2903 into=Cluster, +2904 dialect=dialect, +2905 **opts, +2906 ) +2907 +2908 def limit( +2909 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts +2910 ) -> Select: +2911 """ +2912 Set the LIMIT expression. 2913 -2914 Returns: -2915 Select: the modified expression. -2916 """ -2917 return _apply_builder( -2918 expression=expression, -2919 instance=self, -2920 arg="limit", -2921 into=Limit, -2922 prefix="LIMIT", -2923 dialect=dialect, -2924 copy=copy, -2925 into_arg="expression", -2926 **opts, -2927 ) -2928 -2929 def offset( -2930 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts -2931 ) -> Select: -2932 """ -2933 Set the OFFSET expression. -2934 -2935 Example: -2936 >>> Select().from_("tbl").select("x").offset(10).sql() -2937 'SELECT x FROM tbl OFFSET 10' -2938 -2939 Args: -2940 expression: the SQL code string to parse. -2941 This can also be an integer. -2942 If a `Offset` instance is passed, this is used as-is. -2943 If another `Expression` instance is passed, it will be wrapped in a `Offset`. -2944 dialect: the dialect used to parse the input expression. -2945 copy: if `False`, modify this expression instance in-place. -2946 opts: other options to use to parse the input expressions. +2914 Example: +2915 >>> Select().from_("tbl").select("x").limit(10).sql() +2916 'SELECT x FROM tbl LIMIT 10' +2917 +2918 Args: +2919 expression: the SQL code string to parse. +2920 This can also be an integer. +2921 If a `Limit` instance is passed, this is used as-is. +2922 If another `Expression` instance is passed, it will be wrapped in a `Limit`. +2923 dialect: the dialect used to parse the input expression. +2924 copy: if `False`, modify this expression instance in-place. +2925 opts: other options to use to parse the input expressions. +2926 +2927 Returns: +2928 Select: the modified expression. +2929 """ +2930 return _apply_builder( +2931 expression=expression, +2932 instance=self, +2933 arg="limit", +2934 into=Limit, +2935 prefix="LIMIT", +2936 dialect=dialect, +2937 copy=copy, +2938 into_arg="expression", +2939 **opts, +2940 ) +2941 +2942 def offset( +2943 self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts +2944 ) -> Select: +2945 """ +2946 Set the OFFSET expression. 2947 -2948 Returns: -2949 The modified Select expression. -2950 """ -2951 return _apply_builder( -2952 expression=expression, -2953 instance=self, -2954 arg="offset", -2955 into=Offset, -2956 prefix="OFFSET", -2957 dialect=dialect, -2958 copy=copy, -2959 into_arg="expression", -2960 **opts, -2961 ) -2962 -2963 def select( -2964 self, -2965 *expressions: t.Optional[ExpOrStr], -2966 append: bool = True, -2967 dialect: DialectType = None, -2968 copy: bool = True, -2969 **opts, -2970 ) -> Select: -2971 """ -2972 Append to or set the SELECT expressions. -2973 -2974 Example: -2975 >>> Select().select("x", "y").sql() -2976 'SELECT x, y' -2977 -2978 Args: -2979 *expressions: the SQL code strings to parse. -2980 If an `Expression` instance is passed, it will be used as-is. -2981 append: if `True`, add to any existing expressions. -2982 Otherwise, this resets the expressions. -2983 dialect: the dialect used to parse the input expressions. -2984 copy: if `False`, modify this expression instance in-place. -2985 opts: other options to use to parse the input expressions. +2948 Example: +2949 >>> Select().from_("tbl").select("x").offset(10).sql() +2950 'SELECT x FROM tbl OFFSET 10' +2951 +2952 Args: +2953 expression: the SQL code string to parse. +2954 This can also be an integer. +2955 If a `Offset` instance is passed, this is used as-is. +2956 If another `Expression` instance is passed, it will be wrapped in a `Offset`. +2957 dialect: the dialect used to parse the input expression. +2958 copy: if `False`, modify this expression instance in-place. +2959 opts: other options to use to parse the input expressions. +2960 +2961 Returns: +2962 The modified Select expression. +2963 """ +2964 return _apply_builder( +2965 expression=expression, +2966 instance=self, +2967 arg="offset", +2968 into=Offset, +2969 prefix="OFFSET", +2970 dialect=dialect, +2971 copy=copy, +2972 into_arg="expression", +2973 **opts, +2974 ) +2975 +2976 def select( +2977 self, +2978 *expressions: t.Optional[ExpOrStr], +2979 append: bool = True, +2980 dialect: DialectType = None, +2981 copy: bool = True, +2982 **opts, +2983 ) -> Select: +2984 """ +2985 Append to or set the SELECT expressions. 2986 -2987 Returns: -2988 The modified Select expression. -2989 """ -2990 return _apply_list_builder( -2991 *expressions, -2992 instance=self, -2993 arg="expressions", -2994 append=append, -2995 dialect=dialect, -2996 copy=copy, -2997 **opts, -2998 ) +2987 Example: +2988 >>> Select().select("x", "y").sql() +2989 'SELECT x, y' +2990 +2991 Args: +2992 *expressions: the SQL code strings to parse. +2993 If an `Expression` instance is passed, it will be used as-is. +2994 append: if `True`, add to any existing expressions. +2995 Otherwise, this resets the expressions. +2996 dialect: the dialect used to parse the input expressions. +2997 copy: if `False`, modify this expression instance in-place. +2998 opts: other options to use to parse the input expressions. 2999 -3000 def lateral( -3001 self, -3002 *expressions: t.Optional[ExpOrStr], -3003 append: bool = True, -3004 dialect: DialectType = None, -3005 copy: bool = True, -3006 **opts, -3007 ) -> Select: -3008 """ -3009 Append to or set the LATERAL expressions. -3010 -3011 Example: -3012 >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql() -3013 'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z' -3014 -3015 Args: -3016 *expressions: the SQL code strings to parse. -3017 If an `Expression` instance is passed, it will be used as-is. -3018 append: if `True`, add to any existing expressions. -3019 Otherwise, this resets the expressions. -3020 dialect: the dialect used to parse the input expressions. -3021 copy: if `False`, modify this expression instance in-place. -3022 opts: other options to use to parse the input expressions. +3000 Returns: +3001 The modified Select expression. +3002 """ +3003 return _apply_list_builder( +3004 *expressions, +3005 instance=self, +3006 arg="expressions", +3007 append=append, +3008 dialect=dialect, +3009 copy=copy, +3010 **opts, +3011 ) +3012 +3013 def lateral( +3014 self, +3015 *expressions: t.Optional[ExpOrStr], +3016 append: bool = True, +3017 dialect: DialectType = None, +3018 copy: bool = True, +3019 **opts, +3020 ) -> Select: +3021 """ +3022 Append to or set the LATERAL expressions. 3023 -3024 Returns: -3025 The modified Select expression. -3026 """ -3027 return _apply_list_builder( -3028 *expressions, -3029 instance=self, -3030 arg="laterals", -3031 append=append, -3032 into=Lateral, -3033 prefix="LATERAL VIEW", -3034 dialect=dialect, -3035 copy=copy, -3036 **opts, -3037 ) -3038 -3039 def join( -3040 self, -3041 expression: ExpOrStr, -3042 on: t.Optional[ExpOrStr] = None, -3043 using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None, -3044 append: bool = True, -3045 join_type: t.Optional[str] = None, -3046 join_alias: t.Optional[Identifier | str] = None, -3047 dialect: DialectType = None, -3048 copy: bool = True, -3049 **opts, -3050 ) -> Select: -3051 """ -3052 Append to or set the JOIN expressions. -3053 -3054 Example: -3055 >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql() -3056 'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y' -3057 -3058 >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql() -3059 'SELECT 1 FROM a JOIN b USING (x, y, z)' -3060 -3061 Use `join_type` to change the type of join: -3062 -3063 >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql() -3064 'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y' -3065 -3066 Args: -3067 expression: the SQL code string to parse. -3068 If an `Expression` instance is passed, it will be used as-is. -3069 on: optionally specify the join "on" criteria as a SQL string. -3070 If an `Expression` instance is passed, it will be used as-is. -3071 using: optionally specify the join "using" criteria as a SQL string. -3072 If an `Expression` instance is passed, it will be used as-is. -3073 append: if `True`, add to any existing expressions. -3074 Otherwise, this resets the expressions. -3075 join_type: if set, alter the parsed join type. -3076 join_alias: an optional alias for the joined source. -3077 dialect: the dialect used to parse the input expressions. -3078 copy: if `False`, modify this expression instance in-place. -3079 opts: other options to use to parse the input expressions. -3080 -3081 Returns: -3082 Select: the modified expression. -3083 """ -3084 parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts} -3085 -3086 try: -3087 expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args) -3088 except ParseError: -3089 expression = maybe_parse(expression, into=(Join, Expression), **parse_args) -3090 -3091 join = expression if isinstance(expression, Join) else Join(this=expression) -3092 -3093 if isinstance(join.this, Select): -3094 join.this.replace(join.this.subquery()) -3095 -3096 if join_type: -3097 method: t.Optional[Token] -3098 side: t.Optional[Token] -3099 kind: t.Optional[Token] -3100 -3101 method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args) # type: ignore -3102 -3103 if method: -3104 join.set("method", method.text) -3105 if side: -3106 join.set("side", side.text) -3107 if kind: -3108 join.set("kind", kind.text) -3109 -3110 if on: -3111 on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts) -3112 join.set("on", on) +3024 Example: +3025 >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql() +3026 'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z' +3027 +3028 Args: +3029 *expressions: the SQL code strings to parse. +3030 If an `Expression` instance is passed, it will be used as-is. +3031 append: if `True`, add to any existing expressions. +3032 Otherwise, this resets the expressions. +3033 dialect: the dialect used to parse the input expressions. +3034 copy: if `False`, modify this expression instance in-place. +3035 opts: other options to use to parse the input expressions. +3036 +3037 Returns: +3038 The modified Select expression. +3039 """ +3040 return _apply_list_builder( +3041 *expressions, +3042 instance=self, +3043 arg="laterals", +3044 append=append, +3045 into=Lateral, +3046 prefix="LATERAL VIEW", +3047 dialect=dialect, +3048 copy=copy, +3049 **opts, +3050 ) +3051 +3052 def join( +3053 self, +3054 expression: ExpOrStr, +3055 on: t.Optional[ExpOrStr] = None, +3056 using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None, +3057 append: bool = True, +3058 join_type: t.Optional[str] = None, +3059 join_alias: t.Optional[Identifier | str] = None, +3060 dialect: DialectType = None, +3061 copy: bool = True, +3062 **opts, +3063 ) -> Select: +3064 """ +3065 Append to or set the JOIN expressions. +3066 +3067 Example: +3068 >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql() +3069 'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y' +3070 +3071 >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql() +3072 'SELECT 1 FROM a JOIN b USING (x, y, z)' +3073 +3074 Use `join_type` to change the type of join: +3075 +3076 >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql() +3077 'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y' +3078 +3079 Args: +3080 expression: the SQL code string to parse. +3081 If an `Expression` instance is passed, it will be used as-is. +3082 on: optionally specify the join "on" criteria as a SQL string. +3083 If an `Expression` instance is passed, it will be used as-is. +3084 using: optionally specify the join "using" criteria as a SQL string. +3085 If an `Expression` instance is passed, it will be used as-is. +3086 append: if `True`, add to any existing expressions. +3087 Otherwise, this resets the expressions. +3088 join_type: if set, alter the parsed join type. +3089 join_alias: an optional alias for the joined source. +3090 dialect: the dialect used to parse the input expressions. +3091 copy: if `False`, modify this expression instance in-place. +3092 opts: other options to use to parse the input expressions. +3093 +3094 Returns: +3095 Select: the modified expression. +3096 """ +3097 parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts} +3098 +3099 try: +3100 expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args) +3101 except ParseError: +3102 expression = maybe_parse(expression, into=(Join, Expression), **parse_args) +3103 +3104 join = expression if isinstance(expression, Join) else Join(this=expression) +3105 +3106 if isinstance(join.this, Select): +3107 join.this.replace(join.this.subquery()) +3108 +3109 if join_type: +3110 method: t.Optional[Token] +3111 side: t.Optional[Token] +3112 kind: t.Optional[Token] 3113 -3114 if using: -3115 join = _apply_list_builder( -3116 *ensure_list(using), -3117 instance=join, -3118 arg="using", -3119 append=append, -3120 copy=copy, -3121 into=Identifier, -3122 **opts, -3123 ) -3124 -3125 if join_alias: -3126 join.set("this", alias_(join.this, join_alias, table=True)) -3127 -3128 return _apply_list_builder( -3129 join, -3130 instance=self, -3131 arg="joins", -3132 append=append, -3133 copy=copy, -3134 **opts, -3135 ) -3136 -3137 def where( -3138 self, -3139 *expressions: t.Optional[ExpOrStr], -3140 append: bool = True, -3141 dialect: DialectType = None, -3142 copy: bool = True, -3143 **opts, -3144 ) -> Select: -3145 """ -3146 Append to or set the WHERE expressions. -3147 -3148 Example: -3149 >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql() -3150 "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'" -3151 -3152 Args: -3153 *expressions: the SQL code strings to parse. -3154 If an `Expression` instance is passed, it will be used as-is. -3155 Multiple expressions are combined with an AND operator. -3156 append: if `True`, AND the new expressions to any existing expression. -3157 Otherwise, this resets the expression. -3158 dialect: the dialect used to parse the input expressions. -3159 copy: if `False`, modify this expression instance in-place. -3160 opts: other options to use to parse the input expressions. -3161 -3162 Returns: -3163 Select: the modified expression. -3164 """ -3165 return _apply_conjunction_builder( -3166 *expressions, -3167 instance=self, -3168 arg="where", -3169 append=append, -3170 into=Where, -3171 dialect=dialect, -3172 copy=copy, -3173 **opts, -3174 ) -3175 -3176 def having( -3177 self, -3178 *expressions: t.Optional[ExpOrStr], -3179 append: bool = True, -3180 dialect: DialectType = None, -3181 copy: bool = True, -3182 **opts, -3183 ) -> Select: -3184 """ -3185 Append to or set the HAVING expressions. -3186 -3187 Example: -3188 >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql() -3189 'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3' -3190 -3191 Args: -3192 *expressions: the SQL code strings to parse. -3193 If an `Expression` instance is passed, it will be used as-is. -3194 Multiple expressions are combined with an AND operator. -3195 append: if `True`, AND the new expressions to any existing expression. -3196 Otherwise, this resets the expression. -3197 dialect: the dialect used to parse the input expressions. -3198 copy: if `False`, modify this expression instance in-place. -3199 opts: other options to use to parse the input expressions. -3200 -3201 Returns: -3202 The modified Select expression. -3203 """ -3204 return _apply_conjunction_builder( -3205 *expressions, -3206 instance=self, -3207 arg="having", -3208 append=append, -3209 into=Having, -3210 dialect=dialect, -3211 copy=copy, -3212 **opts, -3213 ) -3214 -3215 def window( -3216 self, -3217 *expressions: t.Optional[ExpOrStr], -3218 append: bool = True, -3219 dialect: DialectType = None, -3220 copy: bool = True, -3221 **opts, -3222 ) -> Select: -3223 return _apply_list_builder( -3224 *expressions, -3225 instance=self, -3226 arg="windows", -3227 append=append, -3228 into=Window, -3229 dialect=dialect, -3230 copy=copy, -3231 **opts, -3232 ) -3233 -3234 def qualify( -3235 self, -3236 *expressions: t.Optional[ExpOrStr], -3237 append: bool = True, -3238 dialect: DialectType = None, -3239 copy: bool = True, -3240 **opts, -3241 ) -> Select: -3242 return _apply_conjunction_builder( -3243 *expressions, -3244 instance=self, -3245 arg="qualify", -3246 append=append, -3247 into=Qualify, -3248 dialect=dialect, -3249 copy=copy, -3250 **opts, -3251 ) -3252 -3253 def distinct( -3254 self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True -3255 ) -> Select: -3256 """ -3257 Set the OFFSET expression. -3258 -3259 Example: -3260 >>> Select().from_("tbl").select("x").distinct().sql() -3261 'SELECT DISTINCT x FROM tbl' -3262 -3263 Args: -3264 ons: the expressions to distinct on -3265 distinct: whether the Select should be distinct -3266 copy: if `False`, modify this expression instance in-place. -3267 -3268 Returns: -3269 Select: the modified expression. -3270 """ -3271 instance = maybe_copy(self, copy) -3272 on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None -3273 instance.set("distinct", Distinct(on=on) if distinct else None) -3274 return instance +3114 method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args) # type: ignore +3115 +3116 if method: +3117 join.set("method", method.text) +3118 if side: +3119 join.set("side", side.text) +3120 if kind: +3121 join.set("kind", kind.text) +3122 +3123 if on: +3124 on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts) +3125 join.set("on", on) +3126 +3127 if using: +3128 join = _apply_list_builder( +3129 *ensure_list(using), +3130 instance=join, +3131 arg="using", +3132 append=append, +3133 copy=copy, +3134 into=Identifier, +3135 **opts, +3136 ) +3137 +3138 if join_alias: +3139 join.set("this", alias_(join.this, join_alias, table=True)) +3140 +3141 return _apply_list_builder( +3142 join, +3143 instance=self, +3144 arg="joins", +3145 append=append, +3146 copy=copy, +3147 **opts, +3148 ) +3149 +3150 def where( +3151 self, +3152 *expressions: t.Optional[ExpOrStr], +3153 append: bool = True, +3154 dialect: DialectType = None, +3155 copy: bool = True, +3156 **opts, +3157 ) -> Select: +3158 """ +3159 Append to or set the WHERE expressions. +3160 +3161 Example: +3162 >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql() +3163 "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'" +3164 +3165 Args: +3166 *expressions: the SQL code strings to parse. +3167 If an `Expression` instance is passed, it will be used as-is. +3168 Multiple expressions are combined with an AND operator. +3169 append: if `True`, AND the new expressions to any existing expression. +3170 Otherwise, this resets the expression. +3171 dialect: the dialect used to parse the input expressions. +3172 copy: if `False`, modify this expression instance in-place. +3173 opts: other options to use to parse the input expressions. +3174 +3175 Returns: +3176 Select: the modified expression. +3177 """ +3178 return _apply_conjunction_builder( +3179 *expressions, +3180 instance=self, +3181 arg="where", +3182 append=append, +3183 into=Where, +3184 dialect=dialect, +3185 copy=copy, +3186 **opts, +3187 ) +3188 +3189 def having( +3190 self, +3191 *expressions: t.Optional[ExpOrStr], +3192 append: bool = True, +3193 dialect: DialectType = None, +3194 copy: bool = True, +3195 **opts, +3196 ) -> Select: +3197 """ +3198 Append to or set the HAVING expressions. +3199 +3200 Example: +3201 >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql() +3202 'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3' +3203 +3204 Args: +3205 *expressions: the SQL code strings to parse. +3206 If an `Expression` instance is passed, it will be used as-is. +3207 Multiple expressions are combined with an AND operator. +3208 append: if `True`, AND the new expressions to any existing expression. +3209 Otherwise, this resets the expression. +3210 dialect: the dialect used to parse the input expressions. +3211 copy: if `False`, modify this expression instance in-place. +3212 opts: other options to use to parse the input expressions. +3213 +3214 Returns: +3215 The modified Select expression. +3216 """ +3217 return _apply_conjunction_builder( +3218 *expressions, +3219 instance=self, +3220 arg="having", +3221 append=append, +3222 into=Having, +3223 dialect=dialect, +3224 copy=copy, +3225 **opts, +3226 ) +3227 +3228 def window( +3229 self, +3230 *expressions: t.Optional[ExpOrStr], +3231 append: bool = True, +3232 dialect: DialectType = None, +3233 copy: bool = True, +3234 **opts, +3235 ) -> Select: +3236 return _apply_list_builder( +3237 *expressions, +3238 instance=self, +3239 arg="windows", +3240 append=append, +3241 into=Window, +3242 dialect=dialect, +3243 copy=copy, +3244 **opts, +3245 ) +3246 +3247 def qualify( +3248 self, +3249 *expressions: t.Optional[ExpOrStr], +3250 append: bool = True, +3251 dialect: DialectType = None, +3252 copy: bool = True, +3253 **opts, +3254 ) -> Select: +3255 return _apply_conjunction_builder( +3256 *expressions, +3257 instance=self, +3258 arg="qualify", +3259 append=append, +3260 into=Qualify, +3261 dialect=dialect, +3262 copy=copy, +3263 **opts, +3264 ) +3265 +3266 def distinct( +3267 self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True +3268 ) -> Select: +3269 """ +3270 Set the OFFSET expression. +3271 +3272 Example: +3273 >>> Select().from_("tbl").select("x").distinct().sql() +3274 'SELECT DISTINCT x FROM tbl' 3275 -3276 def ctas( -3277 self, -3278 table: ExpOrStr, -3279 properties: t.Optional[t.Dict] = None, -3280 dialect: DialectType = None, -3281 copy: bool = True, -3282 **opts, -3283 ) -> Create: -3284 """ -3285 Convert this expression to a CREATE TABLE AS statement. -3286 -3287 Example: -3288 >>> Select().select("*").from_("tbl").ctas("x").sql() -3289 'CREATE TABLE x AS SELECT * FROM tbl' -3290 -3291 Args: -3292 table: the SQL code string to parse as the table name. -3293 If another `Expression` instance is passed, it will be used as-is. -3294 properties: an optional mapping of table properties -3295 dialect: the dialect used to parse the input table. -3296 copy: if `False`, modify this expression instance in-place. -3297 opts: other options to use to parse the input table. -3298 -3299 Returns: -3300 The new Create expression. -3301 """ -3302 instance = maybe_copy(self, copy) -3303 table_expression = maybe_parse( -3304 table, -3305 into=Table, -3306 dialect=dialect, -3307 **opts, -3308 ) -3309 properties_expression = None -3310 if properties: -3311 properties_expression = Properties.from_dict(properties) -3312 -3313 return Create( -3314 this=table_expression, -3315 kind="table", -3316 expression=instance, -3317 properties=properties_expression, -3318 ) -3319 -3320 def lock(self, update: bool = True, copy: bool = True) -> Select: -3321 """ -3322 Set the locking read mode for this expression. -3323 -3324 Examples: -3325 >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql") -3326 "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE" -3327 -3328 >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql") -3329 "SELECT x FROM tbl WHERE x = 'a' FOR SHARE" -3330 -3331 Args: -3332 update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`. -3333 copy: if `False`, modify this expression instance in-place. -3334 -3335 Returns: -3336 The modified expression. -3337 """ -3338 inst = maybe_copy(self, copy) -3339 inst.set("locks", [Lock(update=update)]) +3276 Args: +3277 ons: the expressions to distinct on +3278 distinct: whether the Select should be distinct +3279 copy: if `False`, modify this expression instance in-place. +3280 +3281 Returns: +3282 Select: the modified expression. +3283 """ +3284 instance = maybe_copy(self, copy) +3285 on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None +3286 instance.set("distinct", Distinct(on=on) if distinct else None) +3287 return instance +3288 +3289 def ctas( +3290 self, +3291 table: ExpOrStr, +3292 properties: t.Optional[t.Dict] = None, +3293 dialect: DialectType = None, +3294 copy: bool = True, +3295 **opts, +3296 ) -> Create: +3297 """ +3298 Convert this expression to a CREATE TABLE AS statement. +3299 +3300 Example: +3301 >>> Select().select("*").from_("tbl").ctas("x").sql() +3302 'CREATE TABLE x AS SELECT * FROM tbl' +3303 +3304 Args: +3305 table: the SQL code string to parse as the table name. +3306 If another `Expression` instance is passed, it will be used as-is. +3307 properties: an optional mapping of table properties +3308 dialect: the dialect used to parse the input table. +3309 copy: if `False`, modify this expression instance in-place. +3310 opts: other options to use to parse the input table. +3311 +3312 Returns: +3313 The new Create expression. +3314 """ +3315 instance = maybe_copy(self, copy) +3316 table_expression = maybe_parse( +3317 table, +3318 into=Table, +3319 dialect=dialect, +3320 **opts, +3321 ) +3322 properties_expression = None +3323 if properties: +3324 properties_expression = Properties.from_dict(properties) +3325 +3326 return Create( +3327 this=table_expression, +3328 kind="table", +3329 expression=instance, +3330 properties=properties_expression, +3331 ) +3332 +3333 def lock(self, update: bool = True, copy: bool = True) -> Select: +3334 """ +3335 Set the locking read mode for this expression. +3336 +3337 Examples: +3338 >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql") +3339 "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE" 3340 -3341 return inst -3342 -3343 def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select: -3344 """ -3345 Set hints for this expression. -3346 -3347 Examples: -3348 >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark") -3349 'SELECT /*+ BROADCAST(y) */ x FROM tbl' -3350 -3351 Args: -3352 hints: The SQL code strings to parse as the hints. -3353 If an `Expression` instance is passed, it will be used as-is. -3354 dialect: The dialect used to parse the hints. -3355 copy: If `False`, modify this expression instance in-place. -3356 -3357 Returns: -3358 The modified expression. -3359 """ -3360 inst = maybe_copy(self, copy) -3361 inst.set( -3362 "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints]) -3363 ) -3364 -3365 return inst -3366 -3367 @property -3368 def named_selects(self) -> t.List[str]: -3369 return [e.output_name for e in self.expressions if e.alias_or_name] -3370 -3371 @property -3372 def is_star(self) -> bool: -3373 return any(expression.is_star for expression in self.expressions) -3374 -3375 @property -3376 def selects(self) -> t.List[Expression]: -3377 return self.expressions -3378 +3341 >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql") +3342 "SELECT x FROM tbl WHERE x = 'a' FOR SHARE" +3343 +3344 Args: +3345 update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`. +3346 copy: if `False`, modify this expression instance in-place. +3347 +3348 Returns: +3349 The modified expression. +3350 """ +3351 inst = maybe_copy(self, copy) +3352 inst.set("locks", [Lock(update=update)]) +3353 +3354 return inst +3355 +3356 def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select: +3357 """ +3358 Set hints for this expression. +3359 +3360 Examples: +3361 >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark") +3362 'SELECT /*+ BROADCAST(y) */ x FROM tbl' +3363 +3364 Args: +3365 hints: The SQL code strings to parse as the hints. +3366 If an `Expression` instance is passed, it will be used as-is. +3367 dialect: The dialect used to parse the hints. +3368 copy: If `False`, modify this expression instance in-place. +3369 +3370 Returns: +3371 The modified expression. +3372 """ +3373 inst = maybe_copy(self, copy) +3374 inst.set( +3375 "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints]) +3376 ) +3377 +3378 return inst 3379 -3380class Subquery(DerivedTable, Unionable): -3381 arg_types = { -3382 "this": True, -3383 "alias": False, -3384 "with": False, -3385 **QUERY_MODIFIERS, -3386 } +3380 @property +3381 def named_selects(self) -> t.List[str]: +3382 return [e.output_name for e in self.expressions if e.alias_or_name] +3383 +3384 @property +3385 def is_star(self) -> bool: +3386 return any(expression.is_star for expression in self.expressions) 3387 -3388 def unnest(self): -3389 """ -3390 Returns the first non subquery. -3391 """ -3392 expression = self -3393 while isinstance(expression, Subquery): -3394 expression = expression.this -3395 return expression -3396 -3397 def unwrap(self) -> Subquery: -3398 expression = self -3399 while expression.same_parent and expression.is_wrapper: -3400 expression = t.cast(Subquery, expression.parent) -3401 return expression -3402 -3403 @property -3404 def is_wrapper(self) -> bool: -3405 """ -3406 Whether this Subquery acts as a simple wrapper around another expression. -3407 -3408 SELECT * FROM (((SELECT * FROM t))) -3409 ^ -3410 This corresponds to a "wrapper" Subquery node -3411 """ -3412 return all(v is None for k, v in self.args.items() if k != "this") -3413 -3414 @property -3415 def is_star(self) -> bool: -3416 return self.this.is_star -3417 -3418 @property -3419 def output_name(self) -> str: -3420 return self.alias -3421 -3422 -3423class TableSample(Expression): -3424 arg_types = { -3425 "this": False, -3426 "expressions": False, -3427 "method": False, -3428 "bucket_numerator": False, -3429 "bucket_denominator": False, -3430 "bucket_field": False, -3431 "percent": False, -3432 "rows": False, -3433 "size": False, -3434 "seed": False, -3435 "kind": False, -3436 } -3437 -3438 -3439class Tag(Expression): -3440 """Tags are used for generating arbitrary sql like SELECT <span>x</span>.""" -3441 -3442 arg_types = { -3443 "this": False, -3444 "prefix": False, -3445 "postfix": False, -3446 } -3447 -3448 -3449# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax -3450# https://duckdb.org/docs/sql/statements/pivot -3451class Pivot(Expression): -3452 arg_types = { -3453 "this": False, -3454 "alias": False, -3455 "expressions": False, -3456 "field": False, -3457 "unpivot": False, -3458 "using": False, -3459 "group": False, -3460 "columns": False, -3461 "include_nulls": False, -3462 } -3463 -3464 -3465class Window(Condition): -3466 arg_types = { -3467 "this": True, -3468 "partition_by": False, -3469 "order": False, -3470 "spec": False, -3471 "alias": False, -3472 "over": False, -3473 "first": False, -3474 } -3475 +3388 @property +3389 def selects(self) -> t.List[Expression]: +3390 return self.expressions +3391 +3392 +3393class Subquery(DerivedTable, Unionable): +3394 arg_types = { +3395 "this": True, +3396 "alias": False, +3397 "with": False, +3398 **QUERY_MODIFIERS, +3399 } +3400 +3401 def unnest(self): +3402 """ +3403 Returns the first non subquery. +3404 """ +3405 expression = self +3406 while isinstance(expression, Subquery): +3407 expression = expression.this +3408 return expression +3409 +3410 def unwrap(self) -> Subquery: +3411 expression = self +3412 while expression.same_parent and expression.is_wrapper: +3413 expression = t.cast(Subquery, expression.parent) +3414 return expression +3415 +3416 @property +3417 def is_wrapper(self) -> bool: +3418 """ +3419 Whether this Subquery acts as a simple wrapper around another expression. +3420 +3421 SELECT * FROM (((SELECT * FROM t))) +3422 ^ +3423 This corresponds to a "wrapper" Subquery node +3424 """ +3425 return all(v is None for k, v in self.args.items() if k != "this") +3426 +3427 @property +3428 def is_star(self) -> bool: +3429 return self.this.is_star +3430 +3431 @property +3432 def output_name(self) -> str: +3433 return self.alias +3434 +3435 +3436class TableSample(Expression): +3437 arg_types = { +3438 "this": False, +3439 "expressions": False, +3440 "method": False, +3441 "bucket_numerator": False, +3442 "bucket_denominator": False, +3443 "bucket_field": False, +3444 "percent": False, +3445 "rows": False, +3446 "size": False, +3447 "seed": False, +3448 "kind": False, +3449 } +3450 +3451 +3452class Tag(Expression): +3453 """Tags are used for generating arbitrary sql like SELECT <span>x</span>.""" +3454 +3455 arg_types = { +3456 "this": False, +3457 "prefix": False, +3458 "postfix": False, +3459 } +3460 +3461 +3462# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax +3463# https://duckdb.org/docs/sql/statements/pivot +3464class Pivot(Expression): +3465 arg_types = { +3466 "this": False, +3467 "alias": False, +3468 "expressions": False, +3469 "field": False, +3470 "unpivot": False, +3471 "using": False, +3472 "group": False, +3473 "columns": False, +3474 "include_nulls": False, +3475 } 3476 -3477class WindowSpec(Expression): -3478 arg_types = { -3479 "kind": False, -3480 "start": False, -3481 "start_side": False, -3482 "end": False, -3483 "end_side": False, -3484 } -3485 -3486 -3487class Where(Expression): -3488 pass +3477 +3478class Window(Condition): +3479 arg_types = { +3480 "this": True, +3481 "partition_by": False, +3482 "order": False, +3483 "spec": False, +3484 "alias": False, +3485 "over": False, +3486 "first": False, +3487 } +3488 3489 -3490 -3491class Star(Expression): -3492 arg_types = {"except": False, "replace": False} -3493 -3494 @property -3495 def name(self) -> str: -3496 return "*" -3497 -3498 @property -3499 def output_name(self) -> str: -3500 return self.name -3501 +3490class WindowSpec(Expression): +3491 arg_types = { +3492 "kind": False, +3493 "start": False, +3494 "start_side": False, +3495 "end": False, +3496 "end_side": False, +3497 } +3498 +3499 +3500class Where(Expression): +3501 pass 3502 -3503class Parameter(Condition): -3504 arg_types = {"this": True, "wrapped": False} -3505 +3503 +3504class Star(Expression): +3505 arg_types = {"except": False, "replace": False} 3506 -3507class SessionParameter(Condition): -3508 arg_types = {"this": True, "kind": False} -3509 +3507 @property +3508 def name(self) -> str: +3509 return "*" 3510 -3511class Placeholder(Condition): -3512 arg_types = {"this": False, "kind": False} -3513 +3511 @property +3512 def output_name(self) -> str: +3513 return self.name 3514 -3515class Null(Condition): -3516 arg_types: t.Dict[str, t.Any] = {} -3517 -3518 @property -3519 def name(self) -> str: -3520 return "NULL" -3521 +3515 +3516class Parameter(Condition): +3517 arg_types = {"this": True, "expression": False} +3518 +3519 +3520class SessionParameter(Condition): +3521 arg_types = {"this": True, "kind": False} 3522 -3523class Boolean(Condition): -3524 pass -3525 +3523 +3524class Placeholder(Condition): +3525 arg_types = {"this": False, "kind": False} 3526 -3527class DataTypeParam(Expression): -3528 arg_types = {"this": True, "expression": False} -3529 +3527 +3528class Null(Condition): +3529 arg_types: t.Dict[str, t.Any] = {} 3530 -3531class DataType(Expression): -3532 arg_types = { -3533 "this": True, -3534 "expressions": False, -3535 "nested": False, -3536 "values": False, -3537 "prefix": False, -3538 "kind": False, -3539 } -3540 -3541 class Type(AutoName): -3542 ARRAY = auto() -3543 BIGDECIMAL = auto() -3544 BIGINT = auto() -3545 BIGSERIAL = auto() -3546 BINARY = auto() -3547 BIT = auto() -3548 BOOLEAN = auto() -3549 CHAR = auto() -3550 DATE = auto() -3551 DATEMULTIRANGE = auto() -3552 DATERANGE = auto() -3553 DATETIME = auto() -3554 DATETIME64 = auto() -3555 DECIMAL = auto() -3556 DOUBLE = auto() -3557 ENUM = auto() -3558 ENUM8 = auto() -3559 ENUM16 = auto() -3560 FIXEDSTRING = auto() -3561 FLOAT = auto() -3562 GEOGRAPHY = auto() -3563 GEOMETRY = auto() -3564 HLLSKETCH = auto() -3565 HSTORE = auto() -3566 IMAGE = auto() -3567 INET = auto() -3568 INT = auto() -3569 INT128 = auto() -3570 INT256 = auto() -3571 INT4MULTIRANGE = auto() -3572 INT4RANGE = auto() -3573 INT8MULTIRANGE = auto() -3574 INT8RANGE = auto() -3575 INTERVAL = auto() -3576 IPADDRESS = auto() -3577 IPPREFIX = auto() -3578 JSON = auto() -3579 JSONB = auto() -3580 LONGBLOB = auto() -3581 LONGTEXT = auto() -3582 LOWCARDINALITY = auto() -3583 MAP = auto() -3584 MEDIUMBLOB = auto() -3585 MEDIUMINT = auto() -3586 MEDIUMTEXT = auto() -3587 MONEY = auto() -3588 NCHAR = auto() -3589 NESTED = auto() -3590 NULL = auto() -3591 NULLABLE = auto() -3592 NUMMULTIRANGE = auto() -3593 NUMRANGE = auto() -3594 NVARCHAR = auto() -3595 OBJECT = auto() -3596 ROWVERSION = auto() -3597 SERIAL = auto() -3598 SET = auto() -3599 SMALLINT = auto() -3600 SMALLMONEY = auto() -3601 SMALLSERIAL = auto() -3602 STRUCT = auto() -3603 SUPER = auto() -3604 TEXT = auto() -3605 TINYBLOB = auto() -3606 TINYTEXT = auto() -3607 TIME = auto() -3608 TIMETZ = auto() -3609 TIMESTAMP = auto() -3610 TIMESTAMPLTZ = auto() -3611 TIMESTAMPTZ = auto() -3612 TIMESTAMP_S = auto() -3613 TIMESTAMP_MS = auto() -3614 TIMESTAMP_NS = auto() -3615 TINYINT = auto() -3616 TSMULTIRANGE = auto() -3617 TSRANGE = auto() -3618 TSTZMULTIRANGE = auto() -3619 TSTZRANGE = auto() -3620 UBIGINT = auto() -3621 UINT = auto() -3622 UINT128 = auto() -3623 UINT256 = auto() -3624 UMEDIUMINT = auto() -3625 UDECIMAL = auto() -3626 UNIQUEIDENTIFIER = auto() -3627 UNKNOWN = auto() # Sentinel value, useful for type annotation -3628 USERDEFINED = "USER-DEFINED" -3629 USMALLINT = auto() -3630 UTINYINT = auto() -3631 UUID = auto() -3632 VARBINARY = auto() -3633 VARCHAR = auto() -3634 VARIANT = auto() -3635 XML = auto() -3636 YEAR = auto() -3637 -3638 TEXT_TYPES = { -3639 Type.CHAR, -3640 Type.NCHAR, -3641 Type.VARCHAR, -3642 Type.NVARCHAR, -3643 Type.TEXT, -3644 } -3645 -3646 INTEGER_TYPES = { -3647 Type.INT, -3648 Type.TINYINT, -3649 Type.SMALLINT, -3650 Type.BIGINT, -3651 Type.INT128, -3652 Type.INT256, -3653 } -3654 -3655 FLOAT_TYPES = { -3656 Type.FLOAT, -3657 Type.DOUBLE, -3658 } -3659 -3660 NUMERIC_TYPES = { -3661 *INTEGER_TYPES, -3662 *FLOAT_TYPES, -3663 } -3664 -3665 TEMPORAL_TYPES = { -3666 Type.TIME, -3667 Type.TIMETZ, -3668 Type.TIMESTAMP, -3669 Type.TIMESTAMPTZ, -3670 Type.TIMESTAMPLTZ, -3671 Type.TIMESTAMP_S, -3672 Type.TIMESTAMP_MS, -3673 Type.TIMESTAMP_NS, -3674 Type.DATE, -3675 Type.DATETIME, -3676 Type.DATETIME64, -3677 } -3678 -3679 @classmethod -3680 def build( -3681 cls, -3682 dtype: str | DataType | DataType.Type, -3683 dialect: DialectType = None, -3684 udt: bool = False, -3685 **kwargs, -3686 ) -> DataType: -3687 """ -3688 Constructs a DataType object. -3689 -3690 Args: -3691 dtype: the data type of interest. -3692 dialect: the dialect to use for parsing `dtype`, in case it's a string. -3693 udt: when set to True, `dtype` will be used as-is if it can't be parsed into a -3694 DataType, thus creating a user-defined type. -3695 kawrgs: additional arguments to pass in the constructor of DataType. -3696 -3697 Returns: -3698 The constructed DataType object. -3699 """ -3700 from sqlglot import parse_one -3701 -3702 if isinstance(dtype, str): -3703 if dtype.upper() == "UNKNOWN": -3704 return DataType(this=DataType.Type.UNKNOWN, **kwargs) -3705 -3706 try: -3707 data_type_exp = parse_one( -3708 dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE -3709 ) -3710 except ParseError: -3711 if udt: -3712 return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs) -3713 raise -3714 elif isinstance(dtype, DataType.Type): -3715 data_type_exp = DataType(this=dtype) -3716 elif isinstance(dtype, DataType): -3717 return dtype -3718 else: -3719 raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type") -3720 -3721 return DataType(**{**data_type_exp.args, **kwargs}) -3722 -3723 def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool: -3724 """ -3725 Checks whether this DataType matches one of the provided data types. Nested types or precision -3726 will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>. -3727 -3728 Args: -3729 dtypes: the data types to compare this DataType to. -3730 -3731 Returns: -3732 True, if and only if there is a type in `dtypes` which is equal to this DataType. -3733 """ -3734 for dtype in dtypes: -3735 other = DataType.build(dtype, udt=True) -3736 -3737 if ( -3738 other.expressions -3739 or self.this == DataType.Type.USERDEFINED -3740 or other.this == DataType.Type.USERDEFINED -3741 ): -3742 matches = self == other -3743 else: -3744 matches = self.this == other.this -3745 -3746 if matches: -3747 return True -3748 return False +3531 @property +3532 def name(self) -> str: +3533 return "NULL" +3534 +3535 +3536class Boolean(Condition): +3537 pass +3538 +3539 +3540class DataTypeParam(Expression): +3541 arg_types = {"this": True, "expression": False} +3542 +3543 +3544class DataType(Expression): +3545 arg_types = { +3546 "this": True, +3547 "expressions": False, +3548 "nested": False, +3549 "values": False, +3550 "prefix": False, +3551 "kind": False, +3552 } +3553 +3554 class Type(AutoName): +3555 ARRAY = auto() +3556 BIGDECIMAL = auto() +3557 BIGINT = auto() +3558 BIGSERIAL = auto() +3559 BINARY = auto() +3560 BIT = auto() +3561 BOOLEAN = auto() +3562 CHAR = auto() +3563 DATE = auto() +3564 DATEMULTIRANGE = auto() +3565 DATERANGE = auto() +3566 DATETIME = auto() +3567 DATETIME64 = auto() +3568 DECIMAL = auto() +3569 DOUBLE = auto() +3570 ENUM = auto() +3571 ENUM8 = auto() +3572 ENUM16 = auto() +3573 FIXEDSTRING = auto() +3574 FLOAT = auto() +3575 GEOGRAPHY = auto() +3576 GEOMETRY = auto() +3577 HLLSKETCH = auto() +3578 HSTORE = auto() +3579 IMAGE = auto() +3580 INET = auto() +3581 INT = auto() +3582 INT128 = auto() +3583 INT256 = auto() +3584 INT4MULTIRANGE = auto() +3585 INT4RANGE = auto() +3586 INT8MULTIRANGE = auto() +3587 INT8RANGE = auto() +3588 INTERVAL = auto() +3589 IPADDRESS = auto() +3590 IPPREFIX = auto() +3591 JSON = auto() +3592 JSONB = auto() +3593 LONGBLOB = auto() +3594 LONGTEXT = auto() +3595 LOWCARDINALITY = auto() +3596 MAP = auto() +3597 MEDIUMBLOB = auto() +3598 MEDIUMINT = auto() +3599 MEDIUMTEXT = auto() +3600 MONEY = auto() +3601 NCHAR = auto() +3602 NESTED = auto() +3603 NULL = auto() +3604 NULLABLE = auto() +3605 NUMMULTIRANGE = auto() +3606 NUMRANGE = auto() +3607 NVARCHAR = auto() +3608 OBJECT = auto() +3609 ROWVERSION = auto() +3610 SERIAL = auto() +3611 SET = auto() +3612 SMALLINT = auto() +3613 SMALLMONEY = auto() +3614 SMALLSERIAL = auto() +3615 STRUCT = auto() +3616 SUPER = auto() +3617 TEXT = auto() +3618 TINYBLOB = auto() +3619 TINYTEXT = auto() +3620 TIME = auto() +3621 TIMETZ = auto() +3622 TIMESTAMP = auto() +3623 TIMESTAMPLTZ = auto() +3624 TIMESTAMPTZ = auto() +3625 TIMESTAMP_S = auto() +3626 TIMESTAMP_MS = auto() +3627 TIMESTAMP_NS = auto() +3628 TINYINT = auto() +3629 TSMULTIRANGE = auto() +3630 TSRANGE = auto() +3631 TSTZMULTIRANGE = auto() +3632 TSTZRANGE = auto() +3633 UBIGINT = auto() +3634 UINT = auto() +3635 UINT128 = auto() +3636 UINT256 = auto() +3637 UMEDIUMINT = auto() +3638 UDECIMAL = auto() +3639 UNIQUEIDENTIFIER = auto() +3640 UNKNOWN = auto() # Sentinel value, useful for type annotation +3641 USERDEFINED = "USER-DEFINED" +3642 USMALLINT = auto() +3643 UTINYINT = auto() +3644 UUID = auto() +3645 VARBINARY = auto() +3646 VARCHAR = auto() +3647 VARIANT = auto() +3648 XML = auto() +3649 YEAR = auto() +3650 +3651 TEXT_TYPES = { +3652 Type.CHAR, +3653 Type.NCHAR, +3654 Type.VARCHAR, +3655 Type.NVARCHAR, +3656 Type.TEXT, +3657 } +3658 +3659 INTEGER_TYPES = { +3660 Type.INT, +3661 Type.TINYINT, +3662 Type.SMALLINT, +3663 Type.BIGINT, +3664 Type.INT128, +3665 Type.INT256, +3666 } +3667 +3668 FLOAT_TYPES = { +3669 Type.FLOAT, +3670 Type.DOUBLE, +3671 } +3672 +3673 NUMERIC_TYPES = { +3674 *INTEGER_TYPES, +3675 *FLOAT_TYPES, +3676 } +3677 +3678 TEMPORAL_TYPES = { +3679 Type.TIME, +3680 Type.TIMETZ, +3681 Type.TIMESTAMP, +3682 Type.TIMESTAMPTZ, +3683 Type.TIMESTAMPLTZ, +3684 Type.TIMESTAMP_S, +3685 Type.TIMESTAMP_MS, +3686 Type.TIMESTAMP_NS, +3687 Type.DATE, +3688 Type.DATETIME, +3689 Type.DATETIME64, +3690 } +3691 +3692 @classmethod +3693 def build( +3694 cls, +3695 dtype: str | DataType | DataType.Type, +3696 dialect: DialectType = None, +3697 udt: bool = False, +3698 **kwargs, +3699 ) -> DataType: +3700 """ +3701 Constructs a DataType object. +3702 +3703 Args: +3704 dtype: the data type of interest. +3705 dialect: the dialect to use for parsing `dtype`, in case it's a string. +3706 udt: when set to True, `dtype` will be used as-is if it can't be parsed into a +3707 DataType, thus creating a user-defined type. +3708 kawrgs: additional arguments to pass in the constructor of DataType. +3709 +3710 Returns: +3711 The constructed DataType object. +3712 """ +3713 from sqlglot import parse_one +3714 +3715 if isinstance(dtype, str): +3716 if dtype.upper() == "UNKNOWN": +3717 return DataType(this=DataType.Type.UNKNOWN, **kwargs) +3718 +3719 try: +3720 data_type_exp = parse_one( +3721 dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE +3722 ) +3723 except ParseError: +3724 if udt: +3725 return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs) +3726 raise +3727 elif isinstance(dtype, DataType.Type): +3728 data_type_exp = DataType(this=dtype) +3729 elif isinstance(dtype, DataType): +3730 return dtype +3731 else: +3732 raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type") +3733 +3734 return DataType(**{**data_type_exp.args, **kwargs}) +3735 +3736 def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool: +3737 """ +3738 Checks whether this DataType matches one of the provided data types. Nested types or precision +3739 will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>. +3740 +3741 Args: +3742 dtypes: the data types to compare this DataType to. +3743 +3744 Returns: +3745 True, if and only if there is a type in `dtypes` which is equal to this DataType. +3746 """ +3747 for dtype in dtypes: +3748 other = DataType.build(dtype, udt=True) 3749 -3750 -3751# https://www.postgresql.org/docs/15/datatype-pseudo.html -3752class PseudoType(DataType): -3753 arg_types = {"this": True} -3754 -3755 -3756# https://www.postgresql.org/docs/15/datatype-oid.html -3757class ObjectIdentifier(DataType): -3758 arg_types = {"this": True} -3759 -3760 -3761# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...) -3762class SubqueryPredicate(Predicate): -3763 pass -3764 -3765 -3766class All(SubqueryPredicate): -3767 pass +3750 if ( +3751 other.expressions +3752 or self.this == DataType.Type.USERDEFINED +3753 or other.this == DataType.Type.USERDEFINED +3754 ): +3755 matches = self == other +3756 else: +3757 matches = self.this == other.this +3758 +3759 if matches: +3760 return True +3761 return False +3762 +3763 +3764# https://www.postgresql.org/docs/15/datatype-pseudo.html +3765class PseudoType(DataType): +3766 arg_types = {"this": True} +3767 3768 -3769 -3770class Any(SubqueryPredicate): -3771 pass +3769# https://www.postgresql.org/docs/15/datatype-oid.html +3770class ObjectIdentifier(DataType): +3771 arg_types = {"this": True} 3772 3773 -3774class Exists(SubqueryPredicate): -3775 pass -3776 +3774# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...) +3775class SubqueryPredicate(Predicate): +3776 pass 3777 -3778# Commands to interact with the databases or engines. For most of the command -3779# expressions we parse whatever comes after the command's name as a string. -3780class Command(Expression): -3781 arg_types = {"this": True, "expression": False} +3778 +3779class All(SubqueryPredicate): +3780 pass +3781 3782 -3783 -3784class Transaction(Expression): -3785 arg_types = {"this": False, "modes": False, "mark": False} +3783class Any(SubqueryPredicate): +3784 pass +3785 3786 -3787 -3788class Commit(Expression): -3789 arg_types = {"chain": False, "this": False, "durability": False} +3787class Exists(SubqueryPredicate): +3788 pass +3789 3790 -3791 -3792class Rollback(Expression): -3793 arg_types = {"savepoint": False, "this": False} -3794 +3791# Commands to interact with the databases or engines. For most of the command +3792# expressions we parse whatever comes after the command's name as a string. +3793class Command(Expression): +3794 arg_types = {"this": True, "expression": False} 3795 -3796class AlterTable(Expression): -3797 arg_types = {"this": True, "actions": True, "exists": False, "only": False} -3798 +3796 +3797class Transaction(Expression): +3798 arg_types = {"this": False, "modes": False, "mark": False} 3799 -3800class AddConstraint(Expression): -3801 arg_types = {"this": False, "expression": False, "enforced": False} -3802 +3800 +3801class Commit(Expression): +3802 arg_types = {"chain": False, "this": False, "durability": False} 3803 -3804class DropPartition(Expression): -3805 arg_types = {"expressions": True, "exists": False} -3806 +3804 +3805class Rollback(Expression): +3806 arg_types = {"savepoint": False, "this": False} 3807 -3808# Binary expressions like (ADD a b) -3809class Binary(Condition): -3810 arg_types = {"this": True, "expression": True} +3808 +3809class AlterTable(Expression): +3810 arg_types = {"this": True, "actions": True, "exists": False, "only": False} 3811 -3812 @property -3813 def left(self) -> Expression: -3814 return self.this +3812 +3813class AddConstraint(Expression): +3814 arg_types = {"this": False, "expression": False, "enforced": False} 3815 -3816 @property -3817 def right(self) -> Expression: -3818 return self.expression +3816 +3817class DropPartition(Expression): +3818 arg_types = {"expressions": True, "exists": False} 3819 3820 -3821class Add(Binary): -3822 pass -3823 +3821# Binary expressions like (ADD a b) +3822class Binary(Condition): +3823 arg_types = {"this": True, "expression": True} 3824 -3825class Connector(Binary): -3826 pass -3827 +3825 @property +3826 def left(self) -> Expression: +3827 return self.this 3828 -3829class And(Connector): -3830 pass -3831 +3829 @property +3830 def right(self) -> Expression: +3831 return self.expression 3832 -3833class Or(Connector): -3834 pass -3835 +3833 +3834class Add(Binary): +3835 pass 3836 -3837class BitwiseAnd(Binary): -3838 pass -3839 +3837 +3838class Connector(Binary): +3839 pass 3840 -3841class BitwiseLeftShift(Binary): -3842 pass -3843 +3841 +3842class And(Connector): +3843 pass 3844 -3845class BitwiseOr(Binary): -3846 pass -3847 +3845 +3846class Or(Connector): +3847 pass 3848 -3849class BitwiseRightShift(Binary): -3850 pass -3851 +3849 +3850class BitwiseAnd(Binary): +3851 pass 3852 -3853class BitwiseXor(Binary): -3854 pass -3855 +3853 +3854class BitwiseLeftShift(Binary): +3855 pass 3856 -3857class Div(Binary): -3858 pass -3859 +3857 +3858class BitwiseOr(Binary): +3859 pass 3860 -3861class Overlaps(Binary): -3862 pass -3863 +3861 +3862class BitwiseRightShift(Binary): +3863 pass 3864 -3865class Dot(Binary): -3866 @property -3867 def name(self) -> str: -3868 return self.expression.name +3865 +3866class BitwiseXor(Binary): +3867 pass +3868 3869 -3870 @property -3871 def output_name(self) -> str: -3872 return self.name +3870class Div(Binary): +3871 pass +3872 3873 -3874 @classmethod -3875 def build(self, expressions: t.Sequence[Expression]) -> Dot: -3876 """Build a Dot object with a sequence of expressions.""" -3877 if len(expressions) < 2: -3878 raise ValueError(f"Dot requires >= 2 expressions.") -3879 -3880 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) -3881 +3874class Overlaps(Binary): +3875 pass +3876 +3877 +3878class Dot(Binary): +3879 @property +3880 def name(self) -> str: +3881 return self.expression.name 3882 -3883class DPipe(Binary): -3884 pass -3885 +3883 @property +3884 def output_name(self) -> str: +3885 return self.name 3886 -3887class SafeDPipe(DPipe): -3888 pass -3889 -3890 -3891class EQ(Binary, Predicate): -3892 pass -3893 +3887 @classmethod +3888 def build(self, expressions: t.Sequence[Expression]) -> Dot: +3889 """Build a Dot object with a sequence of expressions.""" +3890 if len(expressions) < 2: +3891 raise ValueError(f"Dot requires >= 2 expressions.") +3892 +3893 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 3894 -3895class NullSafeEQ(Binary, Predicate): -3896 pass -3897 +3895 +3896class DPipe(Binary): +3897 pass 3898 -3899class NullSafeNEQ(Binary, Predicate): -3900 pass -3901 +3899 +3900class SafeDPipe(DPipe): +3901 pass 3902 -3903class Distance(Binary): -3904 pass -3905 +3903 +3904class EQ(Binary, Predicate): +3905 pass 3906 -3907class Escape(Binary): -3908 pass -3909 +3907 +3908class NullSafeEQ(Binary, Predicate): +3909 pass 3910 -3911class Glob(Binary, Predicate): -3912 pass -3913 +3911 +3912class NullSafeNEQ(Binary, Predicate): +3913 pass 3914 -3915class GT(Binary, Predicate): -3916 pass -3917 +3915 +3916class Distance(Binary): +3917 pass 3918 -3919class GTE(Binary, Predicate): -3920 pass -3921 +3919 +3920class Escape(Binary): +3921 pass 3922 -3923class ILike(Binary, Predicate): -3924 pass -3925 +3923 +3924class Glob(Binary, Predicate): +3925 pass 3926 -3927class ILikeAny(Binary, Predicate): -3928 pass -3929 +3927 +3928class GT(Binary, Predicate): +3929 pass 3930 -3931class IntDiv(Binary): -3932 pass -3933 +3931 +3932class GTE(Binary, Predicate): +3933 pass 3934 -3935class Is(Binary, Predicate): -3936 pass -3937 +3935 +3936class ILike(Binary, Predicate): +3937 pass 3938 -3939class Kwarg(Binary): -3940 """Kwarg in special functions like func(kwarg => y).""" -3941 +3939 +3940class ILikeAny(Binary, Predicate): +3941 pass 3942 -3943class Like(Binary, Predicate): -3944 pass -3945 +3943 +3944class IntDiv(Binary): +3945 pass 3946 -3947class LikeAny(Binary, Predicate): -3948 pass -3949 +3947 +3948class Is(Binary, Predicate): +3949 pass 3950 -3951class LT(Binary, Predicate): -3952 pass -3953 +3951 +3952class Kwarg(Binary): +3953 """Kwarg in special functions like func(kwarg => y).""" 3954 -3955class LTE(Binary, Predicate): -3956 pass -3957 +3955 +3956class Like(Binary, Predicate): +3957 pass 3958 -3959class Mod(Binary): -3960 pass -3961 +3959 +3960class LikeAny(Binary, Predicate): +3961 pass 3962 -3963class Mul(Binary): -3964 pass -3965 +3963 +3964class LT(Binary, Predicate): +3965 pass 3966 -3967class NEQ(Binary, Predicate): -3968 pass -3969 +3967 +3968class LTE(Binary, Predicate): +3969 pass 3970 -3971class SimilarTo(Binary, Predicate): -3972 pass -3973 +3971 +3972class Mod(Binary): +3973 pass 3974 -3975class Slice(Binary): -3976 arg_types = {"this": False, "expression": False} -3977 +3975 +3976class Mul(Binary): +3977 pass 3978 -3979class Sub(Binary): -3980 pass -3981 +3979 +3980class NEQ(Binary, Predicate): +3981 pass 3982 -3983class ArrayOverlaps(Binary): -3984 pass -3985 +3983 +3984class SimilarTo(Binary, Predicate): +3985 pass 3986 -3987# Unary Expressions -3988# (NOT a) -3989class Unary(Condition): -3990 pass +3987 +3988class Slice(Binary): +3989 arg_types = {"this": False, "expression": False} +3990 3991 -3992 -3993class BitwiseNot(Unary): -3994 pass +3992class Sub(Binary): +3993 pass +3994 3995 -3996 -3997class Not(Unary): -3998 pass +3996class ArrayOverlaps(Binary): +3997 pass +3998 3999 -4000 -4001class Paren(Unary): -4002 arg_types = {"this": True, "with": False} -4003 -4004 @property -4005 def output_name(self) -> str: -4006 return self.this.name -4007 +4000# Unary Expressions +4001# (NOT a) +4002class Unary(Condition): +4003 pass +4004 +4005 +4006class BitwiseNot(Unary): +4007 pass 4008 -4009class Neg(Unary): -4010 pass -4011 +4009 +4010class Not(Unary): +4011 pass 4012 -4013class Alias(Expression): -4014 arg_types = {"this": True, "alias": False} -4015 -4016 @property -4017 def output_name(self) -> str: -4018 return self.alias -4019 +4013 +4014class Paren(Unary): +4015 arg_types = {"this": True, "with": False} +4016 +4017 @property +4018 def output_name(self) -> str: +4019 return self.this.name 4020 -4021class Aliases(Expression): -4022 arg_types = {"this": True, "expressions": True} -4023 -4024 @property -4025 def aliases(self): -4026 return self.expressions -4027 +4021 +4022class Neg(Unary): +4023 pass +4024 +4025 +4026class Alias(Expression): +4027 arg_types = {"this": True, "alias": False} 4028 -4029class AtTimeZone(Expression): -4030 arg_types = {"this": True, "zone": True} -4031 +4029 @property +4030 def output_name(self) -> str: +4031 return self.alias 4032 -4033class Between(Predicate): -4034 arg_types = {"this": True, "low": True, "high": True} -4035 +4033 +4034class Aliases(Expression): +4035 arg_types = {"this": True, "expressions": True} 4036 -4037class Bracket(Condition): -4038 arg_types = {"this": True, "expressions": True} -4039 -4040 @property -4041 def output_name(self) -> str: -4042 if len(self.expressions) == 1: -4043 return self.expressions[0].output_name +4037 @property +4038 def aliases(self): +4039 return self.expressions +4040 +4041 +4042class AtTimeZone(Expression): +4043 arg_types = {"this": True, "zone": True} 4044 -4045 return super().output_name -4046 -4047 -4048class SafeBracket(Bracket): -4049 """Represents array lookup where OOB index yields NULL instead of causing a failure.""" -4050 -4051 -4052class Distinct(Expression): -4053 arg_types = {"expressions": False, "on": False} -4054 -4055 -4056class In(Predicate): -4057 arg_types = { -4058 "this": True, -4059 "expressions": False, -4060 "query": False, -4061 "unnest": False, -4062 "field": False, -4063 "is_global": False, -4064 } -4065 -4066 -4067class TimeUnit(Expression): -4068 """Automatically converts unit arg into a var.""" -4069 -4070 arg_types = {"unit": False} -4071 -4072 def __init__(self, **args): -4073 unit = args.get("unit") -4074 if isinstance(unit, (Column, Literal)): -4075 args["unit"] = Var(this=unit.name) -4076 elif isinstance(unit, Week): -4077 unit.set("this", Var(this=unit.this.name)) +4045 +4046class Between(Predicate): +4047 arg_types = {"this": True, "low": True, "high": True} +4048 +4049 +4050class Bracket(Condition): +4051 arg_types = {"this": True, "expressions": True} +4052 +4053 @property +4054 def output_name(self) -> str: +4055 if len(self.expressions) == 1: +4056 return self.expressions[0].output_name +4057 +4058 return super().output_name +4059 +4060 +4061class SafeBracket(Bracket): +4062 """Represents array lookup where OOB index yields NULL instead of causing a failure.""" +4063 +4064 +4065class Distinct(Expression): +4066 arg_types = {"expressions": False, "on": False} +4067 +4068 +4069class In(Predicate): +4070 arg_types = { +4071 "this": True, +4072 "expressions": False, +4073 "query": False, +4074 "unnest": False, +4075 "field": False, +4076 "is_global": False, +4077 } 4078 -4079 super().__init__(**args) -4080 -4081 @property -4082 def unit(self) -> t.Optional[Var]: -4083 return self.args.get("unit") +4079 +4080class TimeUnit(Expression): +4081 """Automatically converts unit arg into a var.""" +4082 +4083 arg_types = {"unit": False} 4084 -4085 -4086class IntervalOp(TimeUnit): -4087 arg_types = {"unit": True, "expression": True} -4088 -4089 def interval(self): -4090 return Interval( -4091 this=self.expression.copy(), -4092 unit=self.unit.copy(), -4093 ) -4094 -4095 -4096# https://www.oracletutorial.com/oracle-basics/oracle-interval/ -4097# https://trino.io/docs/current/language/types.html#interval-day-to-second -4098# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html -4099class IntervalSpan(DataType): -4100 arg_types = {"this": True, "expression": True} -4101 -4102 -4103class Interval(TimeUnit): -4104 arg_types = {"this": False, "unit": False} -4105 +4085 UNABBREVIATED_UNIT_NAME = { +4086 "d": "day", +4087 "h": "hour", +4088 "m": "minute", +4089 "ms": "millisecond", +4090 "ns": "nanosecond", +4091 "q": "quarter", +4092 "s": "second", +4093 "us": "microsecond", +4094 "w": "week", +4095 "y": "year", +4096 } +4097 +4098 VAR_LIKE = (Column, Literal, Var) +4099 +4100 def __init__(self, **args): +4101 unit = args.get("unit") +4102 if isinstance(unit, self.VAR_LIKE): +4103 args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name) +4104 elif isinstance(unit, Week): +4105 unit.set("this", Var(this=unit.this.name)) 4106 -4107class IgnoreNulls(Expression): -4108 pass -4109 -4110 -4111class RespectNulls(Expression): -4112 pass +4107 super().__init__(**args) +4108 +4109 @property +4110 def unit(self) -> t.Optional[Var]: +4111 return self.args.get("unit") +4112 4113 -4114 -4115# Functions -4116class Func(Condition): -4117 """ -4118 The base class for all function expressions. -4119 -4120 Attributes: -4121 is_var_len_args (bool): if set to True the last argument defined in arg_types will be -4122 treated as a variable length argument and the argument's value will be stored as a list. -4123 _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items) -4124 for this function expression. These values are used to map this node to a name during parsing -4125 as well as to provide the function's name during SQL string generation. By default the SQL -4126 name is set to the expression's class name transformed to snake case. -4127 """ -4128 -4129 is_var_len_args = False +4114class IntervalOp(TimeUnit): +4115 arg_types = {"unit": True, "expression": True} +4116 +4117 def interval(self): +4118 return Interval( +4119 this=self.expression.copy(), +4120 unit=self.unit.copy(), +4121 ) +4122 +4123 +4124# https://www.oracletutorial.com/oracle-basics/oracle-interval/ +4125# https://trino.io/docs/current/language/types.html#interval-day-to-second +4126# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html +4127class IntervalSpan(DataType): +4128 arg_types = {"this": True, "expression": True} +4129 4130 -4131 @classmethod -4132 def from_arg_list(cls, args): -4133 if cls.is_var_len_args: -4134 all_arg_keys = list(cls.arg_types) -4135 # If this function supports variable length argument treat the last argument as such. -4136 non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys -4137 num_non_var = len(non_var_len_arg_keys) +4131class Interval(TimeUnit): +4132 arg_types = {"this": False, "unit": False} +4133 +4134 +4135class IgnoreNulls(Expression): +4136 pass +4137 4138 -4139 args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)} -4140 args_dict[all_arg_keys[-1]] = args[num_non_var:] -4141 else: -4142 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} -4143 -4144 return cls(**args_dict) -4145 -4146 @classmethod -4147 def sql_names(cls): -4148 if cls is Func: -4149 raise NotImplementedError( -4150 "SQL name is only supported by concrete function implementations" -4151 ) -4152 if "_sql_names" not in cls.__dict__: -4153 cls._sql_names = [camel_to_snake_case(cls.__name__)] -4154 return cls._sql_names -4155 -4156 @classmethod -4157 def sql_name(cls): -4158 return cls.sql_names()[0] -4159 -4160 @classmethod -4161 def default_parser_mappings(cls): -4162 return {name: cls.from_arg_list for name in cls.sql_names()} -4163 -4164 -4165class AggFunc(Func): -4166 pass -4167 -4168 -4169class ParameterizedAgg(AggFunc): -4170 arg_types = {"this": True, "expressions": True, "params": True} +4139class RespectNulls(Expression): +4140 pass +4141 +4142 +4143# Functions +4144class Func(Condition): +4145 """ +4146 The base class for all function expressions. +4147 +4148 Attributes: +4149 is_var_len_args (bool): if set to True the last argument defined in arg_types will be +4150 treated as a variable length argument and the argument's value will be stored as a list. +4151 _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items) +4152 for this function expression. These values are used to map this node to a name during parsing +4153 as well as to provide the function's name during SQL string generation. By default the SQL +4154 name is set to the expression's class name transformed to snake case. +4155 """ +4156 +4157 is_var_len_args = False +4158 +4159 @classmethod +4160 def from_arg_list(cls, args): +4161 if cls.is_var_len_args: +4162 all_arg_keys = list(cls.arg_types) +4163 # If this function supports variable length argument treat the last argument as such. +4164 non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys +4165 num_non_var = len(non_var_len_arg_keys) +4166 +4167 args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)} +4168 args_dict[all_arg_keys[-1]] = args[num_non_var:] +4169 else: +4170 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 4171 -4172 -4173class Abs(Func): -4174 pass -4175 -4176 -4177class Flatten(Func): -4178 pass -4179 -4180 -4181# https://spark.apache.org/docs/latest/api/sql/index.html#transform -4182class Transform(Func): -4183 arg_types = {"this": True, "expression": True} -4184 -4185 -4186class Anonymous(Func): -4187 arg_types = {"this": True, "expressions": False} -4188 is_var_len_args = True -4189 -4190 -4191# https://docs.snowflake.com/en/sql-reference/functions/hll -4192# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html -4193class Hll(AggFunc): -4194 arg_types = {"this": True, "expressions": False} -4195 is_var_len_args = True +4172 return cls(**args_dict) +4173 +4174 @classmethod +4175 def sql_names(cls): +4176 if cls is Func: +4177 raise NotImplementedError( +4178 "SQL name is only supported by concrete function implementations" +4179 ) +4180 if "_sql_names" not in cls.__dict__: +4181 cls._sql_names = [camel_to_snake_case(cls.__name__)] +4182 return cls._sql_names +4183 +4184 @classmethod +4185 def sql_name(cls): +4186 return cls.sql_names()[0] +4187 +4188 @classmethod +4189 def default_parser_mappings(cls): +4190 return {name: cls.from_arg_list for name in cls.sql_names()} +4191 +4192 +4193class AggFunc(Func): +4194 pass +4195 4196 -4197 -4198class ApproxDistinct(AggFunc): -4199 arg_types = {"this": True, "accuracy": False} -4200 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"] -4201 -4202 -4203class Array(Func): -4204 arg_types = {"expressions": False} -4205 is_var_len_args = True -4206 -4207 -4208# https://docs.snowflake.com/en/sql-reference/functions/to_char -4209class ToChar(Func): -4210 arg_types = {"this": True, "format": False} -4211 -4212 -4213class GenerateSeries(Func): -4214 arg_types = {"start": True, "end": True, "step": False} -4215 -4216 -4217class ArrayAgg(AggFunc): -4218 pass -4219 -4220 -4221class ArrayAll(Func): -4222 arg_types = {"this": True, "expression": True} -4223 -4224 -4225class ArrayAny(Func): -4226 arg_types = {"this": True, "expression": True} +4197class ParameterizedAgg(AggFunc): +4198 arg_types = {"this": True, "expressions": True, "params": True} +4199 +4200 +4201class Abs(Func): +4202 pass +4203 +4204 +4205class ArgMax(AggFunc): +4206 arg_types = {"this": True, "expression": True, "count": False} +4207 _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"] +4208 +4209 +4210class ArgMin(AggFunc): +4211 arg_types = {"this": True, "expression": True, "count": False} +4212 _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"] +4213 +4214 +4215class ApproxTopK(AggFunc): +4216 arg_types = {"this": True, "expression": False, "counters": False} +4217 +4218 +4219class Flatten(Func): +4220 pass +4221 +4222 +4223# https://spark.apache.org/docs/latest/api/sql/index.html#transform +4224class Transform(Func): +4225 arg_types = {"this": True, "expression": True} +4226 4227 -4228 -4229class ArrayConcat(Func): -4230 _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"] -4231 arg_types = {"this": True, "expressions": False} -4232 is_var_len_args = True -4233 -4234 -4235class ArrayContains(Binary, Func): -4236 pass -4237 +4228class Anonymous(Func): +4229 arg_types = {"this": True, "expressions": False} +4230 is_var_len_args = True +4231 +4232 +4233# https://docs.snowflake.com/en/sql-reference/functions/hll +4234# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html +4235class Hll(AggFunc): +4236 arg_types = {"this": True, "expressions": False} +4237 is_var_len_args = True 4238 -4239class ArrayContained(Binary): -4240 pass -4241 -4242 -4243class ArrayFilter(Func): -4244 arg_types = {"this": True, "expression": True} -4245 _sql_names = ["FILTER", "ARRAY_FILTER"] -4246 -4247 -4248class ArrayJoin(Func): -4249 arg_types = {"this": True, "expression": True, "null": False} -4250 -4251 -4252class ArraySize(Func): -4253 arg_types = {"this": True, "expression": False} +4239 +4240class ApproxDistinct(AggFunc): +4241 arg_types = {"this": True, "accuracy": False} +4242 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"] +4243 +4244 +4245class Array(Func): +4246 arg_types = {"expressions": False} +4247 is_var_len_args = True +4248 +4249 +4250# https://docs.snowflake.com/en/sql-reference/functions/to_char +4251class ToChar(Func): +4252 arg_types = {"this": True, "format": False} +4253 4254 -4255 -4256class ArraySort(Func): -4257 arg_types = {"this": True, "expression": False} +4255class GenerateSeries(Func): +4256 arg_types = {"start": True, "end": True, "step": False} +4257 4258 -4259 -4260class ArraySum(Func): -4261 pass +4259class ArrayAgg(AggFunc): +4260 pass +4261 4262 -4263 -4264class ArrayUnionAgg(AggFunc): -4265 pass +4263class ArrayAll(Func): +4264 arg_types = {"this": True, "expression": True} +4265 4266 -4267 -4268class Avg(AggFunc): -4269 pass +4267class ArrayAny(Func): +4268 arg_types = {"this": True, "expression": True} +4269 4270 -4271 -4272class AnyValue(AggFunc): -4273 arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False} -4274 +4271class ArrayConcat(Func): +4272 _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"] +4273 arg_types = {"this": True, "expressions": False} +4274 is_var_len_args = True 4275 -4276class First(Func): -4277 arg_types = {"this": True, "ignore_nulls": False} -4278 +4276 +4277class ArrayContains(Binary, Func): +4278 pass 4279 -4280class Last(Func): -4281 arg_types = {"this": True, "ignore_nulls": False} -4282 +4280 +4281class ArrayContained(Binary): +4282 pass 4283 -4284class Case(Func): -4285 arg_types = {"this": False, "ifs": True, "default": False} -4286 -4287 def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case: -4288 instance = maybe_copy(self, copy) -4289 instance.append( -4290 "ifs", -4291 If( -4292 this=maybe_parse(condition, copy=copy, **opts), -4293 true=maybe_parse(then, copy=copy, **opts), -4294 ), -4295 ) -4296 return instance +4284 +4285class ArrayFilter(Func): +4286 arg_types = {"this": True, "expression": True} +4287 _sql_names = ["FILTER", "ARRAY_FILTER"] +4288 +4289 +4290class ArrayJoin(Func): +4291 arg_types = {"this": True, "expression": True, "null": False} +4292 +4293 +4294class ArraySize(Func): +4295 arg_types = {"this": True, "expression": False} +4296 4297 -4298 def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case: -4299 instance = maybe_copy(self, copy) -4300 instance.set("default", maybe_parse(condition, copy=copy, **opts)) -4301 return instance -4302 -4303 -4304class Cast(Func): -4305 arg_types = {"this": True, "to": True, "format": False, "safe": False} -4306 -4307 @property -4308 def name(self) -> str: -4309 return self.this.name -4310 -4311 @property -4312 def to(self) -> DataType: -4313 return self.args["to"] -4314 -4315 @property -4316 def output_name(self) -> str: -4317 return self.name -4318 -4319 def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool: -4320 """ -4321 Checks whether this Cast's DataType matches one of the provided data types. Nested types -4322 like arrays or structs will be compared using "structural equivalence" semantics, so e.g. -4323 array<int> != array<float>. +4298class ArraySort(Func): +4299 arg_types = {"this": True, "expression": False} +4300 +4301 +4302class ArraySum(Func): +4303 pass +4304 +4305 +4306class ArrayUnionAgg(AggFunc): +4307 pass +4308 +4309 +4310class Avg(AggFunc): +4311 pass +4312 +4313 +4314class AnyValue(AggFunc): +4315 arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False} +4316 +4317 +4318class First(Func): +4319 arg_types = {"this": True, "ignore_nulls": False} +4320 +4321 +4322class Last(Func): +4323 arg_types = {"this": True, "ignore_nulls": False} 4324 -4325 Args: -4326 dtypes: the data types to compare this Cast's DataType to. -4327 -4328 Returns: -4329 True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType. -4330 """ -4331 return self.to.is_type(*dtypes) -4332 -4333 -4334class TryCast(Cast): -4335 pass -4336 -4337 -4338class CastToStrType(Func): -4339 arg_types = {"this": True, "to": True} -4340 -4341 -4342class Collate(Binary, Func): -4343 pass +4325 +4326class Case(Func): +4327 arg_types = {"this": False, "ifs": True, "default": False} +4328 +4329 def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case: +4330 instance = maybe_copy(self, copy) +4331 instance.append( +4332 "ifs", +4333 If( +4334 this=maybe_parse(condition, copy=copy, **opts), +4335 true=maybe_parse(then, copy=copy, **opts), +4336 ), +4337 ) +4338 return instance +4339 +4340 def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case: +4341 instance = maybe_copy(self, copy) +4342 instance.set("default", maybe_parse(condition, copy=copy, **opts)) +4343 return instance 4344 4345 -4346class Ceil(Func): -4347 arg_types = {"this": True, "decimals": False} -4348 _sql_names = ["CEIL", "CEILING"] -4349 -4350 -4351class Coalesce(Func): -4352 arg_types = {"this": True, "expressions": False} -4353 is_var_len_args = True -4354 _sql_names = ["COALESCE", "IFNULL", "NVL"] -4355 +4346class Cast(Func): +4347 arg_types = {"this": True, "to": True, "format": False, "safe": False} +4348 +4349 @property +4350 def name(self) -> str: +4351 return self.this.name +4352 +4353 @property +4354 def to(self) -> DataType: +4355 return self.args["to"] 4356 -4357class Chr(Func): -4358 arg_types = {"this": True, "charset": False, "expressions": False} -4359 is_var_len_args = True -4360 _sql_names = ["CHR", "CHAR"] -4361 -4362 -4363class Concat(Func): -4364 arg_types = {"expressions": True} -4365 is_var_len_args = True +4357 @property +4358 def output_name(self) -> str: +4359 return self.name +4360 +4361 def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool: +4362 """ +4363 Checks whether this Cast's DataType matches one of the provided data types. Nested types +4364 like arrays or structs will be compared using "structural equivalence" semantics, so e.g. +4365 array<int> != array<float>. 4366 -4367 -4368class SafeConcat(Concat): -4369 pass -4370 -4371 -4372class ConcatWs(Concat): -4373 _sql_names = ["CONCAT_WS"] +4367 Args: +4368 dtypes: the data types to compare this Cast's DataType to. +4369 +4370 Returns: +4371 True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType. +4372 """ +4373 return self.to.is_type(*dtypes) 4374 4375 -4376class Count(AggFunc): -4377 arg_types = {"this": False, "expressions": False} -4378 is_var_len_args = True +4376class TryCast(Cast): +4377 pass +4378 4379 -4380 -4381class CountIf(AggFunc): -4382 pass +4380class CastToStrType(Func): +4381 arg_types = {"this": True, "to": True} +4382 4383 -4384 -4385class CurrentDate(Func): -4386 arg_types = {"this": False} +4384class Collate(Binary, Func): +4385 pass +4386 4387 -4388 -4389class CurrentDatetime(Func): -4390 arg_types = {"this": False} +4388class Ceil(Func): +4389 arg_types = {"this": True, "decimals": False} +4390 _sql_names = ["CEIL", "CEILING"] 4391 4392 -4393class CurrentTime(Func): -4394 arg_types = {"this": False} -4395 -4396 -4397class CurrentTimestamp(Func): -4398 arg_types = {"this": False} -4399 -4400 -4401class CurrentUser(Func): -4402 arg_types = {"this": False} +4393class Coalesce(Func): +4394 arg_types = {"this": True, "expressions": False} +4395 is_var_len_args = True +4396 _sql_names = ["COALESCE", "IFNULL", "NVL"] +4397 +4398 +4399class Chr(Func): +4400 arg_types = {"this": True, "charset": False, "expressions": False} +4401 is_var_len_args = True +4402 _sql_names = ["CHR", "CHAR"] 4403 4404 -4405class DateAdd(Func, IntervalOp): -4406 arg_types = {"this": True, "expression": True, "unit": False} -4407 +4405class Concat(Func): +4406 arg_types = {"expressions": True} +4407 is_var_len_args = True 4408 -4409class DateSub(Func, IntervalOp): -4410 arg_types = {"this": True, "expression": True, "unit": False} -4411 +4409 +4410class SafeConcat(Concat): +4411 pass 4412 -4413class DateDiff(Func, TimeUnit): -4414 _sql_names = ["DATEDIFF", "DATE_DIFF"] -4415 arg_types = {"this": True, "expression": True, "unit": False} +4413 +4414class ConcatWs(Concat): +4415 _sql_names = ["CONCAT_WS"] 4416 4417 -4418class DateTrunc(Func): -4419 arg_types = {"unit": True, "this": True, "zone": False} -4420 -4421 @property -4422 def unit(self) -> Expression: -4423 return self.args["unit"] -4424 +4418class Count(AggFunc): +4419 arg_types = {"this": False, "expressions": False} +4420 is_var_len_args = True +4421 +4422 +4423class CountIf(AggFunc): +4424 pass 4425 -4426class DatetimeAdd(Func, IntervalOp): -4427 arg_types = {"this": True, "expression": True, "unit": False} -4428 +4426 +4427class CurrentDate(Func): +4428 arg_types = {"this": False} 4429 -4430class DatetimeSub(Func, IntervalOp): -4431 arg_types = {"this": True, "expression": True, "unit": False} -4432 +4430 +4431class CurrentDatetime(Func): +4432 arg_types = {"this": False} 4433 -4434class DatetimeDiff(Func, TimeUnit): -4435 arg_types = {"this": True, "expression": True, "unit": False} -4436 +4434 +4435class CurrentTime(Func): +4436 arg_types = {"this": False} 4437 -4438class DatetimeTrunc(Func, TimeUnit): -4439 arg_types = {"this": True, "unit": True, "zone": False} -4440 +4438 +4439class CurrentTimestamp(Func): +4440 arg_types = {"this": False} 4441 -4442class DayOfWeek(Func): -4443 _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"] -4444 +4442 +4443class CurrentUser(Func): +4444 arg_types = {"this": False} 4445 -4446class DayOfMonth(Func): -4447 _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"] -4448 +4446 +4447class DateAdd(Func, IntervalOp): +4448 arg_types = {"this": True, "expression": True, "unit": False} 4449 -4450class DayOfYear(Func): -4451 _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"] -4452 +4450 +4451class DateSub(Func, IntervalOp): +4452 arg_types = {"this": True, "expression": True, "unit": False} 4453 -4454class ToDays(Func): -4455 pass -4456 -4457 -4458class WeekOfYear(Func): -4459 _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"] -4460 -4461 -4462class MonthsBetween(Func): -4463 arg_types = {"this": True, "expression": True, "roundoff": False} -4464 -4465 -4466class LastDateOfMonth(Func): -4467 pass -4468 -4469 -4470class Extract(Func): -4471 arg_types = {"this": True, "expression": True} -4472 -4473 -4474class Timestamp(Func): -4475 arg_types = {"this": False, "expression": False} -4476 -4477 -4478class TimestampAdd(Func, TimeUnit): -4479 arg_types = {"this": True, "expression": True, "unit": False} -4480 -4481 -4482class TimestampSub(Func, TimeUnit): -4483 arg_types = {"this": True, "expression": True, "unit": False} -4484 -4485 -4486class TimestampDiff(Func, TimeUnit): -4487 arg_types = {"this": True, "expression": True, "unit": False} -4488 -4489 -4490class TimestampTrunc(Func, TimeUnit): -4491 arg_types = {"this": True, "unit": True, "zone": False} -4492 -4493 -4494class TimeAdd(Func, TimeUnit): -4495 arg_types = {"this": True, "expression": True, "unit": False} -4496 -4497 -4498class TimeSub(Func, TimeUnit): -4499 arg_types = {"this": True, "expression": True, "unit": False} -4500 -4501 -4502class TimeDiff(Func, TimeUnit): -4503 arg_types = {"this": True, "expression": True, "unit": False} -4504 -4505 -4506class TimeTrunc(Func, TimeUnit): -4507 arg_types = {"this": True, "unit": True, "zone": False} -4508 -4509 -4510class DateFromParts(Func): -4511 _sql_names = ["DATEFROMPARTS"] -4512 arg_types = {"year": True, "month": True, "day": True} -4513 +4454 +4455class DateDiff(Func, TimeUnit): +4456 _sql_names = ["DATEDIFF", "DATE_DIFF"] +4457 arg_types = {"this": True, "expression": True, "unit": False} +4458 +4459 +4460class DateTrunc(Func): +4461 arg_types = {"unit": True, "this": True, "zone": False} +4462 +4463 @property +4464 def unit(self) -> Expression: +4465 return self.args["unit"] +4466 +4467 +4468class DatetimeAdd(Func, IntervalOp): +4469 arg_types = {"this": True, "expression": True, "unit": False} +4470 +4471 +4472class DatetimeSub(Func, IntervalOp): +4473 arg_types = {"this": True, "expression": True, "unit": False} +4474 +4475 +4476class DatetimeDiff(Func, TimeUnit): +4477 arg_types = {"this": True, "expression": True, "unit": False} +4478 +4479 +4480class DatetimeTrunc(Func, TimeUnit): +4481 arg_types = {"this": True, "unit": True, "zone": False} +4482 +4483 +4484class DayOfWeek(Func): +4485 _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"] +4486 +4487 +4488class DayOfMonth(Func): +4489 _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"] +4490 +4491 +4492class DayOfYear(Func): +4493 _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"] +4494 +4495 +4496class ToDays(Func): +4497 pass +4498 +4499 +4500class WeekOfYear(Func): +4501 _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"] +4502 +4503 +4504class MonthsBetween(Func): +4505 arg_types = {"this": True, "expression": True, "roundoff": False} +4506 +4507 +4508class LastDateOfMonth(Func): +4509 pass +4510 +4511 +4512class Extract(Func): +4513 arg_types = {"this": True, "expression": True} 4514 -4515class DateStrToDate(Func): -4516 pass -4517 +4515 +4516class Timestamp(Func): +4517 arg_types = {"this": False, "expression": False} 4518 -4519class DateToDateStr(Func): -4520 pass -4521 +4519 +4520class TimestampAdd(Func, TimeUnit): +4521 arg_types = {"this": True, "expression": True, "unit": False} 4522 -4523class DateToDi(Func): -4524 pass -4525 +4523 +4524class TimestampSub(Func, TimeUnit): +4525 arg_types = {"this": True, "expression": True, "unit": False} 4526 -4527# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date -4528class Date(Func): -4529 arg_types = {"this": False, "zone": False, "expressions": False} -4530 is_var_len_args = True +4527 +4528class TimestampDiff(Func, TimeUnit): +4529 arg_types = {"this": True, "expression": True, "unit": False} +4530 4531 -4532 -4533class Day(Func): -4534 pass +4532class TimestampTrunc(Func, TimeUnit): +4533 arg_types = {"this": True, "unit": True, "zone": False} +4534 4535 -4536 -4537class Decode(Func): -4538 arg_types = {"this": True, "charset": True, "replace": False} +4536class TimeAdd(Func, TimeUnit): +4537 arg_types = {"this": True, "expression": True, "unit": False} +4538 4539 -4540 -4541class DiToDate(Func): -4542 pass +4540class TimeSub(Func, TimeUnit): +4541 arg_types = {"this": True, "expression": True, "unit": False} +4542 4543 -4544 -4545class Encode(Func): -4546 arg_types = {"this": True, "charset": True} +4544class TimeDiff(Func, TimeUnit): +4545 arg_types = {"this": True, "expression": True, "unit": False} +4546 4547 -4548 -4549class Exp(Func): -4550 pass +4548class TimeTrunc(Func, TimeUnit): +4549 arg_types = {"this": True, "unit": True, "zone": False} +4550 4551 -4552 -4553# https://docs.snowflake.com/en/sql-reference/functions/flatten -4554class Explode(Func): -4555 arg_types = {"this": True, "expressions": False} -4556 is_var_len_args = True -4557 -4558 -4559class ExplodeOuter(Explode): -4560 pass -4561 -4562 -4563class Posexplode(Explode): -4564 pass -4565 -4566 -4567class PosexplodeOuter(Posexplode): -4568 pass -4569 -4570 -4571class Floor(Func): -4572 arg_types = {"this": True, "decimals": False} +4552class DateFromParts(Func): +4553 _sql_names = ["DATEFROMPARTS"] +4554 arg_types = {"year": True, "month": True, "day": True} +4555 +4556 +4557class DateStrToDate(Func): +4558 pass +4559 +4560 +4561class DateToDateStr(Func): +4562 pass +4563 +4564 +4565class DateToDi(Func): +4566 pass +4567 +4568 +4569# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date +4570class Date(Func): +4571 arg_types = {"this": False, "zone": False, "expressions": False} +4572 is_var_len_args = True 4573 4574 -4575class FromBase64(Func): +4575class Day(Func): 4576 pass 4577 4578 -4579class ToBase64(Func): -4580 pass +4579class Decode(Func): +4580 arg_types = {"this": True, "charset": True, "replace": False} 4581 4582 -4583class Greatest(Func): -4584 arg_types = {"this": True, "expressions": False} -4585 is_var_len_args = True +4583class DiToDate(Func): +4584 pass +4585 4586 -4587 -4588class GroupConcat(AggFunc): -4589 arg_types = {"this": True, "separator": False} +4587class Encode(Func): +4588 arg_types = {"this": True, "charset": True} +4589 4590 -4591 -4592class Hex(Func): -4593 pass +4591class Exp(Func): +4592 pass +4593 4594 -4595 -4596class Xor(Connector, Func): -4597 arg_types = {"this": False, "expression": False, "expressions": False} -4598 +4595# https://docs.snowflake.com/en/sql-reference/functions/flatten +4596class Explode(Func): +4597 arg_types = {"this": True, "expressions": False} +4598 is_var_len_args = True 4599 -4600class If(Func): -4601 arg_types = {"this": True, "true": True, "false": False} -4602 +4600 +4601class ExplodeOuter(Explode): +4602 pass 4603 -4604class Initcap(Func): -4605 arg_types = {"this": True, "expression": False} -4606 +4604 +4605class Posexplode(Explode): +4606 pass 4607 -4608class IsNan(Func): -4609 _sql_names = ["IS_NAN", "ISNAN"] -4610 +4608 +4609class PosexplodeOuter(Posexplode): +4610 pass 4611 -4612class FormatJson(Expression): -4613 pass -4614 +4612 +4613class Floor(Func): +4614 arg_types = {"this": True, "decimals": False} 4615 -4616class JSONKeyValue(Expression): -4617 arg_types = {"this": True, "expression": True} -4618 +4616 +4617class FromBase64(Func): +4618 pass 4619 -4620class JSONObject(Func): -4621 arg_types = { -4622 "expressions": False, -4623 "null_handling": False, -4624 "unique_keys": False, -4625 "return_type": False, -4626 "encoding": False, -4627 } +4620 +4621class ToBase64(Func): +4622 pass +4623 +4624 +4625class Greatest(Func): +4626 arg_types = {"this": True, "expressions": False} +4627 is_var_len_args = True 4628 4629 -4630# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html -4631class JSONArray(Func): -4632 arg_types = { -4633 "expressions": True, -4634 "null_handling": False, -4635 "return_type": False, -4636 "strict": False, -4637 } -4638 -4639 -4640# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html -4641class JSONArrayAgg(Func): -4642 arg_types = { -4643 "this": True, -4644 "order": False, -4645 "null_handling": False, -4646 "return_type": False, -4647 "strict": False, -4648 } +4630class GroupConcat(AggFunc): +4631 arg_types = {"this": True, "separator": False} +4632 +4633 +4634class Hex(Func): +4635 pass +4636 +4637 +4638class Xor(Connector, Func): +4639 arg_types = {"this": False, "expression": False, "expressions": False} +4640 +4641 +4642class If(Func): +4643 arg_types = {"this": True, "true": True, "false": False} +4644 +4645 +4646class Initcap(Func): +4647 arg_types = {"this": True, "expression": False} +4648 4649 -4650 -4651# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html -4652# Note: parsing of JSON column definitions is currently incomplete. -4653class JSONColumnDef(Expression): -4654 arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False} -4655 +4650class IsNan(Func): +4651 _sql_names = ["IS_NAN", "ISNAN"] +4652 +4653 +4654class FormatJson(Expression): +4655 pass 4656 -4657class JSONSchema(Expression): -4658 arg_types = {"expressions": True} -4659 +4657 +4658class JSONKeyValue(Expression): +4659 arg_types = {"this": True, "expression": True} 4660 -4661# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html -4662class JSONTable(Func): +4661 +4662class JSONObject(Func): 4663 arg_types = { -4664 "this": True, -4665 "schema": True, -4666 "path": False, -4667 "error_handling": False, -4668 "empty_handling": False, +4664 "expressions": False, +4665 "null_handling": False, +4666 "unique_keys": False, +4667 "return_type": False, +4668 "encoding": False, 4669 } 4670 4671 -4672class OpenJSONColumnDef(Expression): -4673 arg_types = {"this": True, "kind": True, "path": False, "as_json": False} -4674 -4675 -4676class OpenJSON(Func): -4677 arg_types = {"this": True, "path": False, "expressions": False} -4678 -4679 -4680class JSONBContains(Binary): -4681 _sql_names = ["JSONB_CONTAINS"] -4682 -4683 -4684class JSONExtract(Binary, Func): -4685 _sql_names = ["JSON_EXTRACT"] -4686 -4687 -4688class JSONExtractScalar(JSONExtract): -4689 _sql_names = ["JSON_EXTRACT_SCALAR"] -4690 +4672# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html +4673class JSONArray(Func): +4674 arg_types = { +4675 "expressions": True, +4676 "null_handling": False, +4677 "return_type": False, +4678 "strict": False, +4679 } +4680 +4681 +4682# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html +4683class JSONArrayAgg(Func): +4684 arg_types = { +4685 "this": True, +4686 "order": False, +4687 "null_handling": False, +4688 "return_type": False, +4689 "strict": False, +4690 } 4691 -4692class JSONBExtract(JSONExtract): -4693 _sql_names = ["JSONB_EXTRACT"] -4694 -4695 -4696class JSONBExtractScalar(JSONExtract): -4697 _sql_names = ["JSONB_EXTRACT_SCALAR"] +4692 +4693# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html +4694# Note: parsing of JSON column definitions is currently incomplete. +4695class JSONColumnDef(Expression): +4696 arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False} +4697 4698 -4699 -4700class JSONFormat(Func): -4701 arg_types = {"this": False, "options": False} -4702 _sql_names = ["JSON_FORMAT"] -4703 -4704 -4705# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of -4706class JSONArrayContains(Binary, Predicate, Func): -4707 _sql_names = ["JSON_ARRAY_CONTAINS"] -4708 -4709 -4710class ParseJSON(Func): -4711 # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE -4712 _sql_names = ["PARSE_JSON", "JSON_PARSE"] -4713 arg_types = {"this": True, "expressions": False} -4714 is_var_len_args = True -4715 +4699class JSONSchema(Expression): +4700 arg_types = {"expressions": True} +4701 +4702 +4703# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html +4704class JSONTable(Func): +4705 arg_types = { +4706 "this": True, +4707 "schema": True, +4708 "path": False, +4709 "error_handling": False, +4710 "empty_handling": False, +4711 } +4712 +4713 +4714class OpenJSONColumnDef(Expression): +4715 arg_types = {"this": True, "kind": True, "path": False, "as_json": False} 4716 -4717class Least(Func): -4718 arg_types = {"this": True, "expressions": False} -4719 is_var_len_args = True +4717 +4718class OpenJSON(Func): +4719 arg_types = {"this": True, "path": False, "expressions": False} 4720 4721 -4722class Left(Func): -4723 arg_types = {"this": True, "expression": True} +4722class JSONBContains(Binary): +4723 _sql_names = ["JSONB_CONTAINS"] 4724 4725 -4726class Right(Func): -4727 arg_types = {"this": True, "expression": True} +4726class JSONExtract(Binary, Func): +4727 _sql_names = ["JSON_EXTRACT"] 4728 4729 -4730class Length(Func): -4731 _sql_names = ["LENGTH", "LEN"] +4730class JSONExtractScalar(JSONExtract): +4731 _sql_names = ["JSON_EXTRACT_SCALAR"] 4732 4733 -4734class Levenshtein(Func): -4735 arg_types = { -4736 "this": True, -4737 "expression": False, -4738 "ins_cost": False, -4739 "del_cost": False, -4740 "sub_cost": False, -4741 } -4742 -4743 -4744class Ln(Func): -4745 pass +4734class JSONBExtract(JSONExtract): +4735 _sql_names = ["JSONB_EXTRACT"] +4736 +4737 +4738class JSONBExtractScalar(JSONExtract): +4739 _sql_names = ["JSONB_EXTRACT_SCALAR"] +4740 +4741 +4742class JSONFormat(Func): +4743 arg_types = {"this": False, "options": False} +4744 _sql_names = ["JSON_FORMAT"] +4745 4746 -4747 -4748class Log(Func): -4749 arg_types = {"this": True, "expression": False} +4747# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of +4748class JSONArrayContains(Binary, Predicate, Func): +4749 _sql_names = ["JSON_ARRAY_CONTAINS"] 4750 4751 -4752class Log2(Func): -4753 pass -4754 -4755 -4756class Log10(Func): -4757 pass +4752class ParseJSON(Func): +4753 # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE +4754 _sql_names = ["PARSE_JSON", "JSON_PARSE"] +4755 arg_types = {"this": True, "expressions": False} +4756 is_var_len_args = True +4757 4758 -4759 -4760class LogicalOr(AggFunc): -4761 _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"] +4759class Least(Func): +4760 arg_types = {"this": True, "expressions": False} +4761 is_var_len_args = True 4762 4763 -4764class LogicalAnd(AggFunc): -4765 _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"] +4764class Left(Func): +4765 arg_types = {"this": True, "expression": True} 4766 4767 -4768class Lower(Func): -4769 _sql_names = ["LOWER", "LCASE"] +4768class Right(Func): +4769 arg_types = {"this": True, "expression": True} 4770 4771 -4772class Map(Func): -4773 arg_types = {"keys": False, "values": False} +4772class Length(Func): +4773 _sql_names = ["LENGTH", "LEN"] 4774 4775 -4776class MapFromEntries(Func): -4777 pass -4778 -4779 -4780class StarMap(Func): -4781 pass -4782 -4783 -4784class VarMap(Func): -4785 arg_types = {"keys": True, "values": True} -4786 is_var_len_args = True -4787 -4788 @property -4789 def keys(self) -> t.List[Expression]: -4790 return self.args["keys"].expressions -4791 -4792 @property -4793 def values(self) -> t.List[Expression]: -4794 return self.args["values"].expressions -4795 +4776class Levenshtein(Func): +4777 arg_types = { +4778 "this": True, +4779 "expression": False, +4780 "ins_cost": False, +4781 "del_cost": False, +4782 "sub_cost": False, +4783 } +4784 +4785 +4786class Ln(Func): +4787 pass +4788 +4789 +4790class Log(Func): +4791 arg_types = {"this": True, "expression": False} +4792 +4793 +4794class Log2(Func): +4795 pass 4796 -4797# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html -4798class MatchAgainst(Func): -4799 arg_types = {"this": True, "expressions": True, "modifier": False} +4797 +4798class Log10(Func): +4799 pass 4800 4801 -4802class Max(AggFunc): -4803 arg_types = {"this": True, "expressions": False} -4804 is_var_len_args = True +4802class LogicalOr(AggFunc): +4803 _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"] +4804 4805 -4806 -4807class MD5(Func): -4808 _sql_names = ["MD5"] +4806class LogicalAnd(AggFunc): +4807 _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"] +4808 4809 -4810 -4811# Represents the variant of the MD5 function that returns a binary value -4812class MD5Digest(Func): -4813 _sql_names = ["MD5_DIGEST"] -4814 -4815 -4816class Min(AggFunc): -4817 arg_types = {"this": True, "expressions": False} -4818 is_var_len_args = True -4819 -4820 -4821class Month(Func): -4822 pass -4823 -4824 -4825class Nvl2(Func): -4826 arg_types = {"this": True, "true": True, "false": False} +4810class Lower(Func): +4811 _sql_names = ["LOWER", "LCASE"] +4812 +4813 +4814class Map(Func): +4815 arg_types = {"keys": False, "values": False} +4816 +4817 @property +4818 def keys(self) -> t.List[Expression]: +4819 keys = self.args.get("keys") +4820 return keys.expressions if keys else [] +4821 +4822 @property +4823 def values(self) -> t.List[Expression]: +4824 values = self.args.get("values") +4825 return values.expressions if values else [] +4826 4827 -4828 -4829# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function -4830class Predict(Func): -4831 arg_types = {"this": True, "expression": True, "params_struct": False} -4832 -4833 -4834class Pow(Binary, Func): -4835 _sql_names = ["POWER", "POW"] -4836 -4837 -4838class PercentileCont(AggFunc): -4839 arg_types = {"this": True, "expression": False} -4840 -4841 -4842class PercentileDisc(AggFunc): -4843 arg_types = {"this": True, "expression": False} -4844 -4845 -4846class Quantile(AggFunc): -4847 arg_types = {"this": True, "quantile": True} +4828class MapFromEntries(Func): +4829 pass +4830 +4831 +4832class StarMap(Func): +4833 pass +4834 +4835 +4836class VarMap(Func): +4837 arg_types = {"keys": True, "values": True} +4838 is_var_len_args = True +4839 +4840 @property +4841 def keys(self) -> t.List[Expression]: +4842 return self.args["keys"].expressions +4843 +4844 @property +4845 def values(self) -> t.List[Expression]: +4846 return self.args["values"].expressions +4847 4848 -4849 -4850class ApproxQuantile(Quantile): -4851 arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False} +4849# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html +4850class MatchAgainst(Func): +4851 arg_types = {"this": True, "expressions": True, "modifier": False} 4852 4853 -4854class RangeN(Func): -4855 arg_types = {"this": True, "expressions": True, "each": False} -4856 +4854class Max(AggFunc): +4855 arg_types = {"this": True, "expressions": False} +4856 is_var_len_args = True 4857 -4858class ReadCSV(Func): -4859 _sql_names = ["READ_CSV"] -4860 is_var_len_args = True -4861 arg_types = {"this": True, "expressions": False} +4858 +4859class MD5(Func): +4860 _sql_names = ["MD5"] +4861 4862 -4863 -4864class Reduce(Func): -4865 arg_types = {"this": True, "initial": True, "merge": True, "finish": False} +4863# Represents the variant of the MD5 function that returns a binary value +4864class MD5Digest(Func): +4865 _sql_names = ["MD5_DIGEST"] 4866 4867 -4868class RegexpExtract(Func): -4869 arg_types = { -4870 "this": True, -4871 "expression": True, -4872 "position": False, -4873 "occurrence": False, -4874 "parameters": False, -4875 "group": False, -4876 } -4877 -4878 -4879class RegexpReplace(Func): -4880 arg_types = { -4881 "this": True, -4882 "expression": True, -4883 "replacement": True, -4884 "position": False, -4885 "occurrence": False, -4886 "parameters": False, -4887 "modifiers": False, -4888 } +4868class Min(AggFunc): +4869 arg_types = {"this": True, "expressions": False} +4870 is_var_len_args = True +4871 +4872 +4873class Month(Func): +4874 pass +4875 +4876 +4877class Nvl2(Func): +4878 arg_types = {"this": True, "true": True, "false": False} +4879 +4880 +4881# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function +4882class Predict(Func): +4883 arg_types = {"this": True, "expression": True, "params_struct": False} +4884 +4885 +4886class Pow(Binary, Func): +4887 _sql_names = ["POWER", "POW"] +4888 4889 -4890 -4891class RegexpLike(Binary, Func): -4892 arg_types = {"this": True, "expression": True, "flag": False} +4890class PercentileCont(AggFunc): +4891 arg_types = {"this": True, "expression": False} +4892 4893 -4894 -4895class RegexpILike(Binary, Func): -4896 arg_types = {"this": True, "expression": True, "flag": False} +4894class PercentileDisc(AggFunc): +4895 arg_types = {"this": True, "expression": False} +4896 4897 -4898 -4899# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html -4900# limit is the number of times a pattern is applied -4901class RegexpSplit(Func): -4902 arg_types = {"this": True, "expression": True, "limit": False} -4903 +4898class Quantile(AggFunc): +4899 arg_types = {"this": True, "quantile": True} +4900 +4901 +4902class ApproxQuantile(Quantile): +4903 arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False} 4904 -4905class Repeat(Func): -4906 arg_types = {"this": True, "times": True} -4907 +4905 +4906class RangeN(Func): +4907 arg_types = {"this": True, "expressions": True, "each": False} 4908 -4909class Round(Func): -4910 arg_types = {"this": True, "decimals": False} -4911 -4912 -4913class RowNumber(Func): -4914 arg_types: t.Dict[str, t.Any] = {} +4909 +4910class ReadCSV(Func): +4911 _sql_names = ["READ_CSV"] +4912 is_var_len_args = True +4913 arg_types = {"this": True, "expressions": False} +4914 4915 -4916 -4917class SafeDivide(Func): -4918 arg_types = {"this": True, "expression": True} +4916class Reduce(Func): +4917 arg_types = {"this": True, "initial": True, "merge": True, "finish": False} +4918 4919 -4920 -4921class SetAgg(AggFunc): -4922 pass -4923 -4924 -4925class SHA(Func): -4926 _sql_names = ["SHA", "SHA1"] -4927 -4928 -4929class SHA2(Func): -4930 _sql_names = ["SHA2"] -4931 arg_types = {"this": True, "length": False} -4932 -4933 -4934class SortArray(Func): -4935 arg_types = {"this": True, "asc": False} -4936 -4937 -4938class Split(Func): -4939 arg_types = {"this": True, "expression": True, "limit": False} -4940 +4920class RegexpExtract(Func): +4921 arg_types = { +4922 "this": True, +4923 "expression": True, +4924 "position": False, +4925 "occurrence": False, +4926 "parameters": False, +4927 "group": False, +4928 } +4929 +4930 +4931class RegexpReplace(Func): +4932 arg_types = { +4933 "this": True, +4934 "expression": True, +4935 "replacement": True, +4936 "position": False, +4937 "occurrence": False, +4938 "parameters": False, +4939 "modifiers": False, +4940 } 4941 -4942# Start may be omitted in the case of postgres -4943# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6 -4944class Substring(Func): -4945 arg_types = {"this": True, "start": False, "length": False} +4942 +4943class RegexpLike(Binary, Func): +4944 arg_types = {"this": True, "expression": True, "flag": False} +4945 4946 -4947 -4948class StandardHash(Func): -4949 arg_types = {"this": True, "expression": False} +4947class RegexpILike(Binary, Func): +4948 arg_types = {"this": True, "expression": True, "flag": False} +4949 4950 -4951 -4952class StartsWith(Func): -4953 _sql_names = ["STARTS_WITH", "STARTSWITH"] -4954 arg_types = {"this": True, "expression": True} +4951# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html +4952# limit is the number of times a pattern is applied +4953class RegexpSplit(Func): +4954 arg_types = {"this": True, "expression": True, "limit": False} 4955 4956 -4957class StrPosition(Func): -4958 arg_types = { -4959 "this": True, -4960 "substr": True, -4961 "position": False, -4962 "instance": False, -4963 } +4957class Repeat(Func): +4958 arg_types = {"this": True, "times": True} +4959 +4960 +4961class Round(Func): +4962 arg_types = {"this": True, "decimals": False} +4963 4964 -4965 -4966class StrToDate(Func): -4967 arg_types = {"this": True, "format": True} +4965class RowNumber(Func): +4966 arg_types: t.Dict[str, t.Any] = {} +4967 4968 -4969 -4970class StrToTime(Func): -4971 arg_types = {"this": True, "format": True, "zone": False} +4969class SafeDivide(Func): +4970 arg_types = {"this": True, "expression": True} +4971 4972 -4973 -4974# Spark allows unix_timestamp() -4975# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html -4976class StrToUnix(Func): -4977 arg_types = {"this": False, "format": False} -4978 +4973class SetAgg(AggFunc): +4974 pass +4975 +4976 +4977class SHA(Func): +4978 _sql_names = ["SHA", "SHA1"] 4979 -4980# https://prestodb.io/docs/current/functions/string.html -4981# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map -4982class StrToMap(Func): -4983 arg_types = { -4984 "this": True, -4985 "pair_delim": False, -4986 "key_value_delim": False, -4987 "duplicate_resolution_callback": False, -4988 } +4980 +4981class SHA2(Func): +4982 _sql_names = ["SHA2"] +4983 arg_types = {"this": True, "length": False} +4984 +4985 +4986class SortArray(Func): +4987 arg_types = {"this": True, "asc": False} +4988 4989 -4990 -4991class NumberToStr(Func): -4992 arg_types = {"this": True, "format": True, "culture": False} +4990class Split(Func): +4991 arg_types = {"this": True, "expression": True, "limit": False} +4992 4993 -4994 -4995class FromBase(Func): -4996 arg_types = {"this": True, "expression": True} -4997 +4994# Start may be omitted in the case of postgres +4995# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6 +4996class Substring(Func): +4997 arg_types = {"this": True, "start": False, "length": False} 4998 -4999class Struct(Func): -5000 arg_types = {"expressions": True} -5001 is_var_len_args = True +4999 +5000class StandardHash(Func): +5001 arg_types = {"this": True, "expression": False} 5002 5003 -5004class StructExtract(Func): -5005 arg_types = {"this": True, "expression": True} -5006 +5004class StartsWith(Func): +5005 _sql_names = ["STARTS_WITH", "STARTSWITH"] +5006 arg_types = {"this": True, "expression": True} 5007 -5008# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16 -5009# https://docs.snowflake.com/en/sql-reference/functions/insert -5010class Stuff(Func): -5011 _sql_names = ["STUFF", "INSERT"] -5012 arg_types = {"this": True, "start": True, "length": True, "expression": True} -5013 -5014 -5015class Sum(AggFunc): -5016 pass +5008 +5009class StrPosition(Func): +5010 arg_types = { +5011 "this": True, +5012 "substr": True, +5013 "position": False, +5014 "instance": False, +5015 } +5016 5017 -5018 -5019class Sqrt(Func): -5020 pass +5018class StrToDate(Func): +5019 arg_types = {"this": True, "format": True} +5020 5021 -5022 -5023class Stddev(AggFunc): -5024 pass +5022class StrToTime(Func): +5023 arg_types = {"this": True, "format": True, "zone": False} +5024 5025 -5026 -5027class StddevPop(AggFunc): -5028 pass -5029 +5026# Spark allows unix_timestamp() +5027# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html +5028class StrToUnix(Func): +5029 arg_types = {"this": False, "format": False} 5030 -5031class StddevSamp(AggFunc): -5032 pass -5033 -5034 -5035class TimeToStr(Func): -5036 arg_types = {"this": True, "format": True, "culture": False} -5037 -5038 -5039class TimeToTimeStr(Func): -5040 pass +5031 +5032# https://prestodb.io/docs/current/functions/string.html +5033# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map +5034class StrToMap(Func): +5035 arg_types = { +5036 "this": True, +5037 "pair_delim": False, +5038 "key_value_delim": False, +5039 "duplicate_resolution_callback": False, +5040 } 5041 5042 -5043class TimeToUnix(Func): -5044 pass +5043class NumberToStr(Func): +5044 arg_types = {"this": True, "format": True, "culture": False} 5045 5046 -5047class TimeStrToDate(Func): -5048 pass +5047class FromBase(Func): +5048 arg_types = {"this": True, "expression": True} 5049 5050 -5051class TimeStrToTime(Func): -5052 pass -5053 +5051class Struct(Func): +5052 arg_types = {"expressions": False} +5053 is_var_len_args = True 5054 -5055class TimeStrToUnix(Func): -5056 pass -5057 +5055 +5056class StructExtract(Func): +5057 arg_types = {"this": True, "expression": True} 5058 -5059class Trim(Func): -5060 arg_types = { -5061 "this": True, -5062 "expression": False, -5063 "position": False, -5064 "collation": False, -5065 } +5059 +5060# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16 +5061# https://docs.snowflake.com/en/sql-reference/functions/insert +5062class Stuff(Func): +5063 _sql_names = ["STUFF", "INSERT"] +5064 arg_types = {"this": True, "start": True, "length": True, "expression": True} +5065 5066 -5067 -5068class TsOrDsAdd(Func, TimeUnit): -5069 arg_types = {"this": True, "expression": True, "unit": False} +5067class Sum(AggFunc): +5068 pass +5069 5070 -5071 -5072class TsOrDsToDateStr(Func): -5073 pass +5071class Sqrt(Func): +5072 pass +5073 5074 -5075 -5076class TsOrDsToDate(Func): -5077 arg_types = {"this": True, "format": False} +5075class Stddev(AggFunc): +5076 pass +5077 5078 -5079 -5080class TsOrDiToDi(Func): -5081 pass +5079class StddevPop(AggFunc): +5080 pass +5081 5082 -5083 -5084class Unhex(Func): -5085 pass +5083class StddevSamp(AggFunc): +5084 pass +5085 5086 -5087 -5088class UnixToStr(Func): -5089 arg_types = {"this": True, "format": False} +5087class TimeToStr(Func): +5088 arg_types = {"this": True, "format": True, "culture": False} +5089 5090 -5091 -5092# https://prestodb.io/docs/current/functions/datetime.html -5093# presto has weird zone/hours/minutes -5094class UnixToTime(Func): -5095 arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False} -5096 -5097 SECONDS = Literal.string("seconds") -5098 MILLIS = Literal.string("millis") -5099 MICROS = Literal.string("micros") -5100 +5091class TimeToTimeStr(Func): +5092 pass +5093 +5094 +5095class TimeToUnix(Func): +5096 pass +5097 +5098 +5099class TimeStrToDate(Func): +5100 pass 5101 -5102class UnixToTimeStr(Func): -5103 pass -5104 +5102 +5103class TimeStrToTime(Func): +5104 pass 5105 -5106class Upper(Func): -5107 _sql_names = ["UPPER", "UCASE"] -5108 +5106 +5107class TimeStrToUnix(Func): +5108 pass 5109 -5110class Variance(AggFunc): -5111 _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"] -5112 -5113 -5114class VariancePop(AggFunc): -5115 _sql_names = ["VARIANCE_POP", "VAR_POP"] -5116 -5117 -5118class Week(Func): -5119 arg_types = {"this": True, "mode": False} -5120 -5121 -5122class XMLTable(Func): -5123 arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False} -5124 -5125 -5126class Year(Func): -5127 pass -5128 -5129 -5130class Use(Expression): -5131 arg_types = {"this": True, "kind": False} -5132 -5133 -5134class Merge(Expression): -5135 arg_types = {"this": True, "using": True, "on": True, "expressions": True} -5136 -5137 -5138class When(Func): -5139 arg_types = {"matched": True, "source": False, "condition": False, "then": True} -5140 -5141 -5142# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html -5143# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16 -5144class NextValueFor(Func): -5145 arg_types = {"this": True, "order": False} -5146 -5147 -5148def _norm_arg(arg): -5149 return arg.lower() if type(arg) is str else arg -5150 -5151 -5152ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func)) +5110 +5111class Trim(Func): +5112 arg_types = { +5113 "this": True, +5114 "expression": False, +5115 "position": False, +5116 "collation": False, +5117 } +5118 +5119 +5120class TsOrDsAdd(Func, TimeUnit): +5121 arg_types = {"this": True, "expression": True, "unit": False} +5122 +5123 +5124class TsOrDsToDateStr(Func): +5125 pass +5126 +5127 +5128class TsOrDsToDate(Func): +5129 arg_types = {"this": True, "format": False} +5130 +5131 +5132class TsOrDiToDi(Func): +5133 pass +5134 +5135 +5136class Unhex(Func): +5137 pass +5138 +5139 +5140class UnixToStr(Func): +5141 arg_types = {"this": True, "format": False} +5142 +5143 +5144# https://prestodb.io/docs/current/functions/datetime.html +5145# presto has weird zone/hours/minutes +5146class UnixToTime(Func): +5147 arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False} +5148 +5149 SECONDS = Literal.string("seconds") +5150 MILLIS = Literal.string("millis") +5151 MICROS = Literal.string("micros") +5152 5153 -5154 -5155# Helpers -5156@t.overload -5157def maybe_parse( -5158 sql_or_expression: ExpOrStr, -5159 *, -5160 into: t.Type[E], -5161 dialect: DialectType = None, -5162 prefix: t.Optional[str] = None, -5163 copy: bool = False, -5164 **opts, -5165) -> E: -5166 ... -5167 +5154class UnixToTimeStr(Func): +5155 pass +5156 +5157 +5158class Upper(Func): +5159 _sql_names = ["UPPER", "UCASE"] +5160 +5161 +5162class Variance(AggFunc): +5163 _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"] +5164 +5165 +5166class VariancePop(AggFunc): +5167 _sql_names = ["VARIANCE_POP", "VAR_POP"] 5168 -5169@t.overload -5170def maybe_parse( -5171 sql_or_expression: str | E, -5172 *, -5173 into: t.Optional[IntoType] = None, -5174 dialect: DialectType = None, -5175 prefix: t.Optional[str] = None, -5176 copy: bool = False, -5177 **opts, -5178) -> E: -5179 ... +5169 +5170class Week(Func): +5171 arg_types = {"this": True, "mode": False} +5172 +5173 +5174class XMLTable(Func): +5175 arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False} +5176 +5177 +5178class Year(Func): +5179 pass 5180 5181 -5182def maybe_parse( -5183 sql_or_expression: ExpOrStr, -5184 *, -5185 into: t.Optional[IntoType] = None, -5186 dialect: DialectType = None, -5187 prefix: t.Optional[str] = None, -5188 copy: bool = False, -5189 **opts, -5190) -> Expression: -5191 """Gracefully handle a possible string or expression. +5182class Use(Expression): +5183 arg_types = {"this": True, "kind": False} +5184 +5185 +5186class Merge(Expression): +5187 arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False} +5188 +5189 +5190class When(Func): +5191 arg_types = {"matched": True, "source": False, "condition": False, "then": True} 5192 -5193 Example: -5194 >>> maybe_parse("1") -5195 (LITERAL this: 1, is_string: False) -5196 >>> maybe_parse(to_identifier("x")) -5197 (IDENTIFIER this: x, quoted: False) +5193 +5194# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html +5195# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16 +5196class NextValueFor(Func): +5197 arg_types = {"this": True, "order": False} 5198 -5199 Args: -5200 sql_or_expression: the SQL code string or an expression -5201 into: the SQLGlot Expression to parse into -5202 dialect: the dialect used to parse the input expressions (in the case that an -5203 input expression is a SQL string). -5204 prefix: a string to prefix the sql with before it gets parsed -5205 (automatically includes a space) -5206 copy: whether or not to copy the expression. -5207 **opts: other options to use to parse the input expressions (again, in the case -5208 that an input expression is a SQL string). -5209 -5210 Returns: -5211 Expression: the parsed or given expression. -5212 """ -5213 if isinstance(sql_or_expression, Expression): -5214 if copy: -5215 return sql_or_expression.copy() -5216 return sql_or_expression -5217 -5218 if sql_or_expression is None: -5219 raise ParseError(f"SQL cannot be None") +5199 +5200def _norm_arg(arg): +5201 return arg.lower() if type(arg) is str else arg +5202 +5203 +5204ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func)) +5205 +5206 +5207# Helpers +5208@t.overload +5209def maybe_parse( +5210 sql_or_expression: ExpOrStr, +5211 *, +5212 into: t.Type[E], +5213 dialect: DialectType = None, +5214 prefix: t.Optional[str] = None, +5215 copy: bool = False, +5216 **opts, +5217) -> E: +5218 ... +5219 5220 -5221 import sqlglot -5222 -5223 sql = str(sql_or_expression) -5224 if prefix: -5225 sql = f"{prefix} {sql}" -5226 -5227 return sqlglot.parse_one(sql, read=dialect, into=into, **opts) -5228 -5229 -5230@t.overload -5231def maybe_copy(instance: None, copy: bool = True) -> None: -5232 ... +5221@t.overload +5222def maybe_parse( +5223 sql_or_expression: str | E, +5224 *, +5225 into: t.Optional[IntoType] = None, +5226 dialect: DialectType = None, +5227 prefix: t.Optional[str] = None, +5228 copy: bool = False, +5229 **opts, +5230) -> E: +5231 ... +5232 5233 -5234 -5235@t.overload -5236def maybe_copy(instance: E, copy: bool = True) -> E: -5237 ... -5238 -5239 -5240def maybe_copy(instance, copy=True): -5241 return instance.copy() if copy and instance else instance -5242 -5243 -5244def _is_wrong_expression(expression, into): -5245 return isinstance(expression, Expression) and not isinstance(expression, into) -5246 -5247 -5248def _apply_builder( -5249 expression, -5250 instance, -5251 arg, -5252 copy=True, -5253 prefix=None, -5254 into=None, -5255 dialect=None, -5256 into_arg="this", -5257 **opts, -5258): -5259 if _is_wrong_expression(expression, into): -5260 expression = into(**{into_arg: expression}) -5261 instance = maybe_copy(instance, copy) -5262 expression = maybe_parse( -5263 sql_or_expression=expression, -5264 prefix=prefix, -5265 into=into, -5266 dialect=dialect, -5267 **opts, -5268 ) -5269 instance.set(arg, expression) -5270 return instance -5271 +5234def maybe_parse( +5235 sql_or_expression: ExpOrStr, +5236 *, +5237 into: t.Optional[IntoType] = None, +5238 dialect: DialectType = None, +5239 prefix: t.Optional[str] = None, +5240 copy: bool = False, +5241 **opts, +5242) -> Expression: +5243 """Gracefully handle a possible string or expression. +5244 +5245 Example: +5246 >>> maybe_parse("1") +5247 (LITERAL this: 1, is_string: False) +5248 >>> maybe_parse(to_identifier("x")) +5249 (IDENTIFIER this: x, quoted: False) +5250 +5251 Args: +5252 sql_or_expression: the SQL code string or an expression +5253 into: the SQLGlot Expression to parse into +5254 dialect: the dialect used to parse the input expressions (in the case that an +5255 input expression is a SQL string). +5256 prefix: a string to prefix the sql with before it gets parsed +5257 (automatically includes a space) +5258 copy: whether or not to copy the expression. +5259 **opts: other options to use to parse the input expressions (again, in the case +5260 that an input expression is a SQL string). +5261 +5262 Returns: +5263 Expression: the parsed or given expression. +5264 """ +5265 if isinstance(sql_or_expression, Expression): +5266 if copy: +5267 return sql_or_expression.copy() +5268 return sql_or_expression +5269 +5270 if sql_or_expression is None: +5271 raise ParseError(f"SQL cannot be None") 5272 -5273def _apply_child_list_builder( -5274 *expressions, -5275 instance, -5276 arg, -5277 append=True, -5278 copy=True, -5279 prefix=None, -5280 into=None, -5281 dialect=None, -5282 properties=None, -5283 **opts, -5284): -5285 instance = maybe_copy(instance, copy) -5286 parsed = [] -5287 for expression in expressions: -5288 if expression is not None: -5289 if _is_wrong_expression(expression, into): -5290 expression = into(expressions=[expression]) +5273 import sqlglot +5274 +5275 sql = str(sql_or_expression) +5276 if prefix: +5277 sql = f"{prefix} {sql}" +5278 +5279 return sqlglot.parse_one(sql, read=dialect, into=into, **opts) +5280 +5281 +5282@t.overload +5283def maybe_copy(instance: None, copy: bool = True) -> None: +5284 ... +5285 +5286 +5287@t.overload +5288def maybe_copy(instance: E, copy: bool = True) -> E: +5289 ... +5290 5291 -5292 expression = maybe_parse( -5293 expression, -5294 into=into, -5295 dialect=dialect, -5296 prefix=prefix, -5297 **opts, -5298 ) -5299 parsed.extend(expression.expressions) -5300 -5301 existing = instance.args.get(arg) -5302 if append and existing: -5303 parsed = existing.expressions + parsed -5304 -5305 child = into(expressions=parsed) -5306 for k, v in (properties or {}).items(): -5307 child.set(k, v) -5308 instance.set(arg, child) -5309 -5310 return instance -5311 -5312 -5313def _apply_list_builder( -5314 *expressions, -5315 instance, -5316 arg, -5317 append=True, -5318 copy=True, -5319 prefix=None, -5320 into=None, -5321 dialect=None, -5322 **opts, -5323): -5324 inst = maybe_copy(instance, copy) -5325 -5326 expressions = [ -5327 maybe_parse( -5328 sql_or_expression=expression, -5329 into=into, -5330 prefix=prefix, -5331 dialect=dialect, -5332 **opts, -5333 ) -5334 for expression in expressions -5335 if expression is not None -5336 ] -5337 -5338 existing_expressions = inst.args.get(arg) -5339 if append and existing_expressions: -5340 expressions = existing_expressions + expressions -5341 -5342 inst.set(arg, expressions) -5343 return inst -5344 -5345 -5346def _apply_conjunction_builder( -5347 *expressions, -5348 instance, -5349 arg, -5350 into=None, -5351 append=True, -5352 copy=True, -5353 dialect=None, -5354 **opts, -5355): -5356 expressions = [exp for exp in expressions if exp is not None and exp != ""] -5357 if not expressions: -5358 return instance -5359 -5360 inst = maybe_copy(instance, copy) +5292def maybe_copy(instance, copy=True): +5293 return instance.copy() if copy and instance else instance +5294 +5295 +5296def _is_wrong_expression(expression, into): +5297 return isinstance(expression, Expression) and not isinstance(expression, into) +5298 +5299 +5300def _apply_builder( +5301 expression, +5302 instance, +5303 arg, +5304 copy=True, +5305 prefix=None, +5306 into=None, +5307 dialect=None, +5308 into_arg="this", +5309 **opts, +5310): +5311 if _is_wrong_expression(expression, into): +5312 expression = into(**{into_arg: expression}) +5313 instance = maybe_copy(instance, copy) +5314 expression = maybe_parse( +5315 sql_or_expression=expression, +5316 prefix=prefix, +5317 into=into, +5318 dialect=dialect, +5319 **opts, +5320 ) +5321 instance.set(arg, expression) +5322 return instance +5323 +5324 +5325def _apply_child_list_builder( +5326 *expressions, +5327 instance, +5328 arg, +5329 append=True, +5330 copy=True, +5331 prefix=None, +5332 into=None, +5333 dialect=None, +5334 properties=None, +5335 **opts, +5336): +5337 instance = maybe_copy(instance, copy) +5338 parsed = [] +5339 for expression in expressions: +5340 if expression is not None: +5341 if _is_wrong_expression(expression, into): +5342 expression = into(expressions=[expression]) +5343 +5344 expression = maybe_parse( +5345 expression, +5346 into=into, +5347 dialect=dialect, +5348 prefix=prefix, +5349 **opts, +5350 ) +5351 parsed.extend(expression.expressions) +5352 +5353 existing = instance.args.get(arg) +5354 if append and existing: +5355 parsed = existing.expressions + parsed +5356 +5357 child = into(expressions=parsed) +5358 for k, v in (properties or {}).items(): +5359 child.set(k, v) +5360 instance.set(arg, child) 5361 -5362 existing = inst.args.get(arg) -5363 if append and existing is not None: -5364 expressions = [existing.this if into else existing] + list(expressions) -5365 -5366 node = and_(*expressions, dialect=dialect, copy=copy, **opts) -5367 -5368 inst.set(arg, into(this=node) if into else node) -5369 return inst -5370 -5371 -5372def _apply_cte_builder( -5373 instance: E, -5374 alias: ExpOrStr, -5375 as_: ExpOrStr, -5376 recursive: t.Optional[bool] = None, -5377 append: bool = True, -5378 dialect: DialectType = None, -5379 copy: bool = True, -5380 **opts, -5381) -> E: -5382 alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts) -5383 as_expression = maybe_parse(as_, dialect=dialect, **opts) -5384 cte = CTE(this=as_expression, alias=alias_expression) -5385 return _apply_child_list_builder( -5386 cte, -5387 instance=instance, -5388 arg="with", -5389 append=append, -5390 copy=copy, -5391 into=With, -5392 properties={"recursive": recursive or False}, -5393 ) -5394 -5395 -5396def _combine( -5397 expressions: t.Sequence[t.Optional[ExpOrStr]], -5398 operator: t.Type[Connector], -5399 dialect: DialectType = None, -5400 copy: bool = True, -5401 **opts, -5402) -> Expression: -5403 conditions = [ -5404 condition(expression, dialect=dialect, copy=copy, **opts) -5405 for expression in expressions -5406 if expression is not None -5407 ] -5408 -5409 this, *rest = conditions -5410 if rest: -5411 this = _wrap(this, Connector) -5412 for expression in rest: -5413 this = operator(this=this, expression=_wrap(expression, Connector)) -5414 -5415 return this -5416 +5362 return instance +5363 +5364 +5365def _apply_list_builder( +5366 *expressions, +5367 instance, +5368 arg, +5369 append=True, +5370 copy=True, +5371 prefix=None, +5372 into=None, +5373 dialect=None, +5374 **opts, +5375): +5376 inst = maybe_copy(instance, copy) +5377 +5378 expressions = [ +5379 maybe_parse( +5380 sql_or_expression=expression, +5381 into=into, +5382 prefix=prefix, +5383 dialect=dialect, +5384 **opts, +5385 ) +5386 for expression in expressions +5387 if expression is not None +5388 ] +5389 +5390 existing_expressions = inst.args.get(arg) +5391 if append and existing_expressions: +5392 expressions = existing_expressions + expressions +5393 +5394 inst.set(arg, expressions) +5395 return inst +5396 +5397 +5398def _apply_conjunction_builder( +5399 *expressions, +5400 instance, +5401 arg, +5402 into=None, +5403 append=True, +5404 copy=True, +5405 dialect=None, +5406 **opts, +5407): +5408 expressions = [exp for exp in expressions if exp is not None and exp != ""] +5409 if not expressions: +5410 return instance +5411 +5412 inst = maybe_copy(instance, copy) +5413 +5414 existing = inst.args.get(arg) +5415 if append and existing is not None: +5416 expressions = [existing.this if into else existing] + list(expressions) 5417 -5418def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: -5419 return Paren(this=expression) if isinstance(expression, kind) else expression -5420 -5421 -5422def union( -5423 left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts -5424) -> Union: -5425 """ -5426 Initializes a syntax tree from one UNION expression. -5427 -5428 Example: -5429 >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql() -5430 'SELECT * FROM foo UNION SELECT * FROM bla' -5431 -5432 Args: -5433 left: the SQL code string corresponding to the left-hand side. -5434 If an `Expression` instance is passed, it will be used as-is. -5435 right: the SQL code string corresponding to the right-hand side. -5436 If an `Expression` instance is passed, it will be used as-is. -5437 distinct: set the DISTINCT flag if and only if this is true. -5438 dialect: the dialect used to parse the input expression. -5439 opts: other options to use to parse the input expressions. -5440 -5441 Returns: -5442 The new Union instance. -5443 """ -5444 left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts) -5445 right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts) +5418 node = and_(*expressions, dialect=dialect, copy=copy, **opts) +5419 +5420 inst.set(arg, into(this=node) if into else node) +5421 return inst +5422 +5423 +5424def _apply_cte_builder( +5425 instance: E, +5426 alias: ExpOrStr, +5427 as_: ExpOrStr, +5428 recursive: t.Optional[bool] = None, +5429 append: bool = True, +5430 dialect: DialectType = None, +5431 copy: bool = True, +5432 **opts, +5433) -> E: +5434 alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts) +5435 as_expression = maybe_parse(as_, dialect=dialect, **opts) +5436 cte = CTE(this=as_expression, alias=alias_expression) +5437 return _apply_child_list_builder( +5438 cte, +5439 instance=instance, +5440 arg="with", +5441 append=append, +5442 copy=copy, +5443 into=With, +5444 properties={"recursive": recursive or False}, +5445 ) 5446 -5447 return Union(this=left, expression=right, distinct=distinct) -5448 -5449 -5450def intersect( -5451 left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts -5452) -> Intersect: -5453 """ -5454 Initializes a syntax tree from one INTERSECT expression. -5455 -5456 Example: -5457 >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql() -5458 'SELECT * FROM foo INTERSECT SELECT * FROM bla' -5459 -5460 Args: -5461 left: the SQL code string corresponding to the left-hand side. -5462 If an `Expression` instance is passed, it will be used as-is. -5463 right: the SQL code string corresponding to the right-hand side. -5464 If an `Expression` instance is passed, it will be used as-is. -5465 distinct: set the DISTINCT flag if and only if this is true. -5466 dialect: the dialect used to parse the input expression. -5467 opts: other options to use to parse the input expressions. +5447 +5448def _combine( +5449 expressions: t.Sequence[t.Optional[ExpOrStr]], +5450 operator: t.Type[Connector], +5451 dialect: DialectType = None, +5452 copy: bool = True, +5453 **opts, +5454) -> Expression: +5455 conditions = [ +5456 condition(expression, dialect=dialect, copy=copy, **opts) +5457 for expression in expressions +5458 if expression is not None +5459 ] +5460 +5461 this, *rest = conditions +5462 if rest: +5463 this = _wrap(this, Connector) +5464 for expression in rest: +5465 this = operator(this=this, expression=_wrap(expression, Connector)) +5466 +5467 return this 5468 -5469 Returns: -5470 The new Intersect instance. -5471 """ -5472 left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts) -5473 right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts) -5474 -5475 return Intersect(this=left, expression=right, distinct=distinct) -5476 -5477 -5478def except_( -5479 left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts -5480) -> Except: -5481 """ -5482 Initializes a syntax tree from one EXCEPT expression. -5483 -5484 Example: -5485 >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql() -5486 'SELECT * FROM foo EXCEPT SELECT * FROM bla' -5487 -5488 Args: -5489 left: the SQL code string corresponding to the left-hand side. -5490 If an `Expression` instance is passed, it will be used as-is. -5491 right: the SQL code string corresponding to the right-hand side. -5492 If an `Expression` instance is passed, it will be used as-is. -5493 distinct: set the DISTINCT flag if and only if this is true. -5494 dialect: the dialect used to parse the input expression. -5495 opts: other options to use to parse the input expressions. -5496 -5497 Returns: -5498 The new Except instance. -5499 """ -5500 left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts) -5501 right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts) -5502 -5503 return Except(this=left, expression=right, distinct=distinct) +5469 +5470def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: +5471 return Paren(this=expression) if isinstance(expression, kind) else expression +5472 +5473 +5474def union( +5475 left: ExpOrStr, +5476 right: ExpOrStr, +5477 distinct: bool = True, +5478 dialect: DialectType = None, +5479 copy: bool = True, +5480 **opts, +5481) -> Union: +5482 """ +5483 Initializes a syntax tree from one UNION expression. +5484 +5485 Example: +5486 >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql() +5487 'SELECT * FROM foo UNION SELECT * FROM bla' +5488 +5489 Args: +5490 left: the SQL code string corresponding to the left-hand side. +5491 If an `Expression` instance is passed, it will be used as-is. +5492 right: the SQL code string corresponding to the right-hand side. +5493 If an `Expression` instance is passed, it will be used as-is. +5494 distinct: set the DISTINCT flag if and only if this is true. +5495 dialect: the dialect used to parse the input expression. +5496 copy: whether or not to copy the expression. +5497 opts: other options to use to parse the input expressions. +5498 +5499 Returns: +5500 The new Union instance. +5501 """ +5502 left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts) +5503 right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts) 5504 -5505 -5506def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select: -5507 """ -5508 Initializes a syntax tree from one or multiple SELECT expressions. -5509 -5510 Example: -5511 >>> select("col1", "col2").from_("tbl").sql() -5512 'SELECT col1, col2 FROM tbl' -5513 -5514 Args: -5515 *expressions: the SQL code string to parse as the expressions of a -5516 SELECT statement. If an Expression instance is passed, this is used as-is. -5517 dialect: the dialect used to parse the input expressions (in the case that an -5518 input expression is a SQL string). -5519 **opts: other options to use to parse the input expressions (again, in the case -5520 that an input expression is a SQL string). -5521 -5522 Returns: -5523 Select: the syntax tree for the SELECT statement. -5524 """ -5525 return Select().select(*expressions, dialect=dialect, **opts) -5526 -5527 -5528def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select: -5529 """ -5530 Initializes a syntax tree from a FROM expression. -5531 -5532 Example: -5533 >>> from_("tbl").select("col1", "col2").sql() -5534 'SELECT col1, col2 FROM tbl' -5535 -5536 Args: -5537 *expression: the SQL code string to parse as the FROM expressions of a -5538 SELECT statement. If an Expression instance is passed, this is used as-is. -5539 dialect: the dialect used to parse the input expression (in the case that the -5540 input expression is a SQL string). -5541 **opts: other options to use to parse the input expressions (again, in the case -5542 that the input expression is a SQL string). -5543 -5544 Returns: -5545 Select: the syntax tree for the SELECT statement. -5546 """ -5547 return Select().from_(expression, dialect=dialect, **opts) -5548 -5549 -5550def update( -5551 table: str | Table, -5552 properties: dict, -5553 where: t.Optional[ExpOrStr] = None, -5554 from_: t.Optional[ExpOrStr] = None, -5555 dialect: DialectType = None, -5556 **opts, -5557) -> Update: -5558 """ -5559 Creates an update statement. -5560 -5561 Example: -5562 >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql() -5563 "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1" -5564 -5565 Args: -5566 *properties: dictionary of properties to set which are -5567 auto converted to sql objects eg None -> NULL -5568 where: sql conditional parsed into a WHERE statement -5569 from_: sql statement parsed into a FROM statement -5570 dialect: the dialect used to parse the input expressions. -5571 **opts: other options to use to parse the input expressions. +5505 return Union(this=left, expression=right, distinct=distinct) +5506 +5507 +5508def intersect( +5509 left: ExpOrStr, +5510 right: ExpOrStr, +5511 distinct: bool = True, +5512 dialect: DialectType = None, +5513 copy: bool = True, +5514 **opts, +5515) -> Intersect: +5516 """ +5517 Initializes a syntax tree from one INTERSECT expression. +5518 +5519 Example: +5520 >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql() +5521 'SELECT * FROM foo INTERSECT SELECT * FROM bla' +5522 +5523 Args: +5524 left: the SQL code string corresponding to the left-hand side. +5525 If an `Expression` instance is passed, it will be used as-is. +5526 right: the SQL code string corresponding to the right-hand side. +5527 If an `Expression` instance is passed, it will be used as-is. +5528 distinct: set the DISTINCT flag if and only if this is true. +5529 dialect: the dialect used to parse the input expression. +5530 copy: whether or not to copy the expression. +5531 opts: other options to use to parse the input expressions. +5532 +5533 Returns: +5534 The new Intersect instance. +5535 """ +5536 left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts) +5537 right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts) +5538 +5539 return Intersect(this=left, expression=right, distinct=distinct) +5540 +5541 +5542def except_( +5543 left: ExpOrStr, +5544 right: ExpOrStr, +5545 distinct: bool = True, +5546 dialect: DialectType = None, +5547 copy: bool = True, +5548 **opts, +5549) -> Except: +5550 """ +5551 Initializes a syntax tree from one EXCEPT expression. +5552 +5553 Example: +5554 >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql() +5555 'SELECT * FROM foo EXCEPT SELECT * FROM bla' +5556 +5557 Args: +5558 left: the SQL code string corresponding to the left-hand side. +5559 If an `Expression` instance is passed, it will be used as-is. +5560 right: the SQL code string corresponding to the right-hand side. +5561 If an `Expression` instance is passed, it will be used as-is. +5562 distinct: set the DISTINCT flag if and only if this is true. +5563 dialect: the dialect used to parse the input expression. +5564 copy: whether or not to copy the expression. +5565 opts: other options to use to parse the input expressions. +5566 +5567 Returns: +5568 The new Except instance. +5569 """ +5570 left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts) +5571 right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts) 5572 -5573 Returns: -5574 Update: the syntax tree for the UPDATE statement. -5575 """ -5576 update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect)) -5577 update_expr.set( -5578 "expressions", -5579 [ -5580 EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v)) -5581 for k, v in properties.items() -5582 ], -5583 ) -5584 if from_: -5585 update_expr.set( -5586 "from", -5587 maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts), -5588 ) -5589 if isinstance(where, Condition): -5590 where = Where(this=where) -5591 if where: -5592 update_expr.set( -5593 "where", -5594 maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts), -5595 ) -5596 return update_expr +5573 return Except(this=left, expression=right, distinct=distinct) +5574 +5575 +5576def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select: +5577 """ +5578 Initializes a syntax tree from one or multiple SELECT expressions. +5579 +5580 Example: +5581 >>> select("col1", "col2").from_("tbl").sql() +5582 'SELECT col1, col2 FROM tbl' +5583 +5584 Args: +5585 *expressions: the SQL code string to parse as the expressions of a +5586 SELECT statement. If an Expression instance is passed, this is used as-is. +5587 dialect: the dialect used to parse the input expressions (in the case that an +5588 input expression is a SQL string). +5589 **opts: other options to use to parse the input expressions (again, in the case +5590 that an input expression is a SQL string). +5591 +5592 Returns: +5593 Select: the syntax tree for the SELECT statement. +5594 """ +5595 return Select().select(*expressions, dialect=dialect, **opts) +5596 5597 -5598 -5599def delete( -5600 table: ExpOrStr, -5601 where: t.Optional[ExpOrStr] = None, -5602 returning: t.Optional[ExpOrStr] = None, -5603 dialect: DialectType = None, -5604 **opts, -5605) -> Delete: -5606 """ -5607 Builds a delete statement. -5608 -5609 Example: -5610 >>> delete("my_table", where="id > 1").sql() -5611 'DELETE FROM my_table WHERE id > 1' -5612 -5613 Args: -5614 where: sql conditional parsed into a WHERE statement -5615 returning: sql conditional parsed into a RETURNING statement -5616 dialect: the dialect used to parse the input expressions. -5617 **opts: other options to use to parse the input expressions. +5598def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select: +5599 """ +5600 Initializes a syntax tree from a FROM expression. +5601 +5602 Example: +5603 >>> from_("tbl").select("col1", "col2").sql() +5604 'SELECT col1, col2 FROM tbl' +5605 +5606 Args: +5607 *expression: the SQL code string to parse as the FROM expressions of a +5608 SELECT statement. If an Expression instance is passed, this is used as-is. +5609 dialect: the dialect used to parse the input expression (in the case that the +5610 input expression is a SQL string). +5611 **opts: other options to use to parse the input expressions (again, in the case +5612 that the input expression is a SQL string). +5613 +5614 Returns: +5615 Select: the syntax tree for the SELECT statement. +5616 """ +5617 return Select().from_(expression, dialect=dialect, **opts) 5618 -5619 Returns: -5620 Delete: the syntax tree for the DELETE statement. -5621 """ -5622 delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts) -5623 if where: -5624 delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts) -5625 if returning: -5626 delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts) -5627 return delete_expr -5628 -5629 -5630def insert( -5631 expression: ExpOrStr, -5632 into: ExpOrStr, -5633 columns: t.Optional[t.Sequence[ExpOrStr]] = None, -5634 overwrite: t.Optional[bool] = None, -5635 dialect: DialectType = None, -5636 copy: bool = True, -5637 **opts, -5638) -> Insert: -5639 """ -5640 Builds an INSERT statement. -5641 -5642 Example: -5643 >>> insert("VALUES (1, 2, 3)", "tbl").sql() -5644 'INSERT INTO tbl VALUES (1, 2, 3)' -5645 -5646 Args: -5647 expression: the sql string or expression of the INSERT statement -5648 into: the tbl to insert data to. -5649 columns: optionally the table's column names. -5650 overwrite: whether to INSERT OVERWRITE or not. -5651 dialect: the dialect used to parse the input expressions. -5652 copy: whether or not to copy the expression. -5653 **opts: other options to use to parse the input expressions. -5654 -5655 Returns: -5656 Insert: the syntax tree for the INSERT statement. -5657 """ -5658 expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts) -5659 this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts) -5660 -5661 if columns: -5662 this = _apply_list_builder( -5663 *columns, -5664 instance=Schema(this=this), -5665 arg="expressions", -5666 into=Identifier, -5667 copy=False, -5668 dialect=dialect, -5669 **opts, -5670 ) -5671 -5672 return Insert(this=this, expression=expr, overwrite=overwrite) -5673 -5674 -5675def condition( -5676 expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts -5677) -> Condition: -5678 """ -5679 Initialize a logical condition expression. -5680 -5681 Example: -5682 >>> condition("x=1").sql() -5683 'x = 1' -5684 -5685 This is helpful for composing larger logical syntax trees: -5686 >>> where = condition("x=1") -5687 >>> where = where.and_("y=1") -5688 >>> Select().from_("tbl").select("*").where(where).sql() -5689 'SELECT * FROM tbl WHERE x = 1 AND y = 1' -5690 -5691 Args: -5692 *expression: the SQL code string to parse. -5693 If an Expression instance is passed, this is used as-is. -5694 dialect: the dialect used to parse the input expression (in the case that the -5695 input expression is a SQL string). -5696 copy: Whether or not to copy `expression` (only applies to expressions). -5697 **opts: other options to use to parse the input expressions (again, in the case -5698 that the input expression is a SQL string). +5619 +5620def update( +5621 table: str | Table, +5622 properties: dict, +5623 where: t.Optional[ExpOrStr] = None, +5624 from_: t.Optional[ExpOrStr] = None, +5625 dialect: DialectType = None, +5626 **opts, +5627) -> Update: +5628 """ +5629 Creates an update statement. +5630 +5631 Example: +5632 >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql() +5633 "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1" +5634 +5635 Args: +5636 *properties: dictionary of properties to set which are +5637 auto converted to sql objects eg None -> NULL +5638 where: sql conditional parsed into a WHERE statement +5639 from_: sql statement parsed into a FROM statement +5640 dialect: the dialect used to parse the input expressions. +5641 **opts: other options to use to parse the input expressions. +5642 +5643 Returns: +5644 Update: the syntax tree for the UPDATE statement. +5645 """ +5646 update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect)) +5647 update_expr.set( +5648 "expressions", +5649 [ +5650 EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v)) +5651 for k, v in properties.items() +5652 ], +5653 ) +5654 if from_: +5655 update_expr.set( +5656 "from", +5657 maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts), +5658 ) +5659 if isinstance(where, Condition): +5660 where = Where(this=where) +5661 if where: +5662 update_expr.set( +5663 "where", +5664 maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts), +5665 ) +5666 return update_expr +5667 +5668 +5669def delete( +5670 table: ExpOrStr, +5671 where: t.Optional[ExpOrStr] = None, +5672 returning: t.Optional[ExpOrStr] = None, +5673 dialect: DialectType = None, +5674 **opts, +5675) -> Delete: +5676 """ +5677 Builds a delete statement. +5678 +5679 Example: +5680 >>> delete("my_table", where="id > 1").sql() +5681 'DELETE FROM my_table WHERE id > 1' +5682 +5683 Args: +5684 where: sql conditional parsed into a WHERE statement +5685 returning: sql conditional parsed into a RETURNING statement +5686 dialect: the dialect used to parse the input expressions. +5687 **opts: other options to use to parse the input expressions. +5688 +5689 Returns: +5690 Delete: the syntax tree for the DELETE statement. +5691 """ +5692 delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts) +5693 if where: +5694 delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts) +5695 if returning: +5696 delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts) +5697 return delete_expr +5698 5699 -5700 Returns: -5701 The new Condition instance -5702 """ -5703 return maybe_parse( -5704 expression, -5705 into=Condition, -5706 dialect=dialect, -5707 copy=copy, -5708 **opts, -5709 ) -5710 +5700def insert( +5701 expression: ExpOrStr, +5702 into: ExpOrStr, +5703 columns: t.Optional[t.Sequence[ExpOrStr]] = None, +5704 overwrite: t.Optional[bool] = None, +5705 dialect: DialectType = None, +5706 copy: bool = True, +5707 **opts, +5708) -> Insert: +5709 """ +5710 Builds an INSERT statement. 5711 -5712def and_( -5713 *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts -5714) -> Condition: -5715 """ -5716 Combine multiple conditions with an AND logical operator. -5717 -5718 Example: -5719 >>> and_("x=1", and_("y=1", "z=1")).sql() -5720 'x = 1 AND (y = 1 AND z = 1)' -5721 -5722 Args: -5723 *expressions: the SQL code strings to parse. -5724 If an Expression instance is passed, this is used as-is. -5725 dialect: the dialect used to parse the input expression. -5726 copy: whether or not to copy `expressions` (only applies to Expressions). -5727 **opts: other options to use to parse the input expressions. -5728 -5729 Returns: -5730 And: the new condition -5731 """ -5732 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts)) -5733 -5734 -5735def or_( -5736 *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts -5737) -> Condition: -5738 """ -5739 Combine multiple conditions with an OR logical operator. -5740 -5741 Example: -5742 >>> or_("x=1", or_("y=1", "z=1")).sql() -5743 'x = 1 OR (y = 1 OR z = 1)' +5712 Example: +5713 >>> insert("VALUES (1, 2, 3)", "tbl").sql() +5714 'INSERT INTO tbl VALUES (1, 2, 3)' +5715 +5716 Args: +5717 expression: the sql string or expression of the INSERT statement +5718 into: the tbl to insert data to. +5719 columns: optionally the table's column names. +5720 overwrite: whether to INSERT OVERWRITE or not. +5721 dialect: the dialect used to parse the input expressions. +5722 copy: whether or not to copy the expression. +5723 **opts: other options to use to parse the input expressions. +5724 +5725 Returns: +5726 Insert: the syntax tree for the INSERT statement. +5727 """ +5728 expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts) +5729 this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts) +5730 +5731 if columns: +5732 this = _apply_list_builder( +5733 *columns, +5734 instance=Schema(this=this), +5735 arg="expressions", +5736 into=Identifier, +5737 copy=False, +5738 dialect=dialect, +5739 **opts, +5740 ) +5741 +5742 return Insert(this=this, expression=expr, overwrite=overwrite) +5743 5744 -5745 Args: -5746 *expressions: the SQL code strings to parse. -5747 If an Expression instance is passed, this is used as-is. -5748 dialect: the dialect used to parse the input expression. -5749 copy: whether or not to copy `expressions` (only applies to Expressions). -5750 **opts: other options to use to parse the input expressions. -5751 -5752 Returns: -5753 Or: the new condition -5754 """ -5755 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts)) -5756 -5757 -5758def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not: -5759 """ -5760 Wrap a condition with a NOT operator. -5761 -5762 Example: -5763 >>> not_("this_suit='black'").sql() -5764 "NOT this_suit = 'black'" -5765 -5766 Args: -5767 expression: the SQL code string to parse. -5768 If an Expression instance is passed, this is used as-is. -5769 dialect: the dialect used to parse the input expression. -5770 copy: whether to copy the expression or not. -5771 **opts: other options to use to parse the input expressions. -5772 -5773 Returns: -5774 The new condition. -5775 """ -5776 this = condition( -5777 expression, -5778 dialect=dialect, -5779 copy=copy, -5780 **opts, -5781 ) -5782 return Not(this=_wrap(this, Connector)) -5783 -5784 -5785def paren(expression: ExpOrStr, copy: bool = True) -> Paren: -5786 """ -5787 Wrap an expression in parentheses. -5788 -5789 Example: -5790 >>> paren("5 + 3").sql() -5791 '(5 + 3)' -5792 -5793 Args: -5794 expression: the SQL code string to parse. -5795 If an Expression instance is passed, this is used as-is. -5796 copy: whether to copy the expression or not. -5797 -5798 Returns: -5799 The wrapped expression. -5800 """ -5801 return Paren(this=maybe_parse(expression, copy=copy)) -5802 +5745def condition( +5746 expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts +5747) -> Condition: +5748 """ +5749 Initialize a logical condition expression. +5750 +5751 Example: +5752 >>> condition("x=1").sql() +5753 'x = 1' +5754 +5755 This is helpful for composing larger logical syntax trees: +5756 >>> where = condition("x=1") +5757 >>> where = where.and_("y=1") +5758 >>> Select().from_("tbl").select("*").where(where).sql() +5759 'SELECT * FROM tbl WHERE x = 1 AND y = 1' +5760 +5761 Args: +5762 *expression: the SQL code string to parse. +5763 If an Expression instance is passed, this is used as-is. +5764 dialect: the dialect used to parse the input expression (in the case that the +5765 input expression is a SQL string). +5766 copy: Whether or not to copy `expression` (only applies to expressions). +5767 **opts: other options to use to parse the input expressions (again, in the case +5768 that the input expression is a SQL string). +5769 +5770 Returns: +5771 The new Condition instance +5772 """ +5773 return maybe_parse( +5774 expression, +5775 into=Condition, +5776 dialect=dialect, +5777 copy=copy, +5778 **opts, +5779 ) +5780 +5781 +5782def and_( +5783 *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts +5784) -> Condition: +5785 """ +5786 Combine multiple conditions with an AND logical operator. +5787 +5788 Example: +5789 >>> and_("x=1", and_("y=1", "z=1")).sql() +5790 'x = 1 AND (y = 1 AND z = 1)' +5791 +5792 Args: +5793 *expressions: the SQL code strings to parse. +5794 If an Expression instance is passed, this is used as-is. +5795 dialect: the dialect used to parse the input expression. +5796 copy: whether or not to copy `expressions` (only applies to Expressions). +5797 **opts: other options to use to parse the input expressions. +5798 +5799 Returns: +5800 And: the new condition +5801 """ +5802 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts)) 5803 -5804SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$") -5805 -5806 -5807@t.overload -5808def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: -5809 ... +5804 +5805def or_( +5806 *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts +5807) -> Condition: +5808 """ +5809 Combine multiple conditions with an OR logical operator. 5810 -5811 -5812@t.overload -5813def to_identifier( -5814 name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True -5815) -> Identifier: -5816 ... -5817 -5818 -5819def to_identifier(name, quoted=None, copy=True): -5820 """Builds an identifier. +5811 Example: +5812 >>> or_("x=1", or_("y=1", "z=1")).sql() +5813 'x = 1 OR (y = 1 OR z = 1)' +5814 +5815 Args: +5816 *expressions: the SQL code strings to parse. +5817 If an Expression instance is passed, this is used as-is. +5818 dialect: the dialect used to parse the input expression. +5819 copy: whether or not to copy `expressions` (only applies to Expressions). +5820 **opts: other options to use to parse the input expressions. 5821 -5822 Args: -5823 name: The name to turn into an identifier. -5824 quoted: Whether or not force quote the identifier. -5825 copy: Whether or not to copy a passed in Identefier node. +5822 Returns: +5823 Or: the new condition +5824 """ +5825 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts)) 5826 -5827 Returns: -5828 The identifier ast node. -5829 """ -5830 -5831 if name is None: -5832 return None -5833 -5834 if isinstance(name, Identifier): -5835 identifier = maybe_copy(name, copy) -5836 elif isinstance(name, str): -5837 identifier = Identifier( -5838 this=name, -5839 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, -5840 ) -5841 else: -5842 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") -5843 return identifier -5844 -5845 -5846INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*") -5847 -5848 -5849def to_interval(interval: str | Literal) -> Interval: -5850 """Builds an interval expression from a string like '1 day' or '5 months'.""" -5851 if isinstance(interval, Literal): -5852 if not interval.is_string: -5853 raise ValueError("Invalid interval string.") +5827 +5828def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not: +5829 """ +5830 Wrap a condition with a NOT operator. +5831 +5832 Example: +5833 >>> not_("this_suit='black'").sql() +5834 "NOT this_suit = 'black'" +5835 +5836 Args: +5837 expression: the SQL code string to parse. +5838 If an Expression instance is passed, this is used as-is. +5839 dialect: the dialect used to parse the input expression. +5840 copy: whether to copy the expression or not. +5841 **opts: other options to use to parse the input expressions. +5842 +5843 Returns: +5844 The new condition. +5845 """ +5846 this = condition( +5847 expression, +5848 dialect=dialect, +5849 copy=copy, +5850 **opts, +5851 ) +5852 return Not(this=_wrap(this, Connector)) +5853 5854 -5855 interval = interval.this -5856 -5857 interval_parts = INTERVAL_STRING_RE.match(interval) # type: ignore +5855def paren(expression: ExpOrStr, copy: bool = True) -> Paren: +5856 """ +5857 Wrap an expression in parentheses. 5858 -5859 if not interval_parts: -5860 raise ValueError("Invalid interval string.") -5861 -5862 return Interval( -5863 this=Literal.string(interval_parts.group(1)), -5864 unit=Var(this=interval_parts.group(2)), -5865 ) -5866 +5859 Example: +5860 >>> paren("5 + 3").sql() +5861 '(5 + 3)' +5862 +5863 Args: +5864 expression: the SQL code string to parse. +5865 If an Expression instance is passed, this is used as-is. +5866 copy: whether to copy the expression or not. 5867 -5868@t.overload -5869def to_table(sql_path: str | Table, **kwargs) -> Table: -5870 ... -5871 +5868 Returns: +5869 The wrapped expression. +5870 """ +5871 return Paren(this=maybe_parse(expression, copy=copy)) 5872 -5873@t.overload -5874def to_table(sql_path: None, **kwargs) -> None: -5875 ... +5873 +5874SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$") +5875 5876 -5877 -5878def to_table( -5879 sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs -5880) -> t.Optional[Table]: -5881 """ -5882 Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional. -5883 If a table is passed in then that table is returned. -5884 -5885 Args: -5886 sql_path: a `[catalog].[schema].[table]` string. -5887 dialect: the source dialect according to which the table name will be parsed. -5888 kwargs: the kwargs to instantiate the resulting `Table` expression with. -5889 -5890 Returns: -5891 A table expression. -5892 """ -5893 if sql_path is None or isinstance(sql_path, Table): -5894 return sql_path -5895 if not isinstance(sql_path, str): -5896 raise ValueError(f"Invalid type provided for a table: {type(sql_path)}") -5897 -5898 table = maybe_parse(sql_path, into=Table, dialect=dialect) -5899 if table: -5900 for k, v in kwargs.items(): -5901 table.set(k, v) -5902 -5903 return table -5904 -5905 -5906def to_column(sql_path: str | Column, **kwargs) -> Column: -5907 """ -5908 Create a column from a `[table].[column]` sql path. Schema is optional. -5909 -5910 If a column is passed in then that column is returned. -5911 -5912 Args: -5913 sql_path: `[table].[column]` string -5914 Returns: -5915 Table: A column expression -5916 """ -5917 if sql_path is None or isinstance(sql_path, Column): -5918 return sql_path -5919 if not isinstance(sql_path, str): -5920 raise ValueError(f"Invalid type provided for column: {type(sql_path)}") -5921 return column(*reversed(sql_path.split(".")), **kwargs) # type: ignore -5922 -5923 -5924def alias_( -5925 expression: ExpOrStr, -5926 alias: str | Identifier, -5927 table: bool | t.Sequence[str | Identifier] = False, -5928 quoted: t.Optional[bool] = None, -5929 dialect: DialectType = None, -5930 copy: bool = True, -5931 **opts, -5932): -5933 """Create an Alias expression. -5934 -5935 Example: -5936 >>> alias_('foo', 'bar').sql() -5937 'foo AS bar' -5938 -5939 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() -5940 '(SELECT 1, 2) AS bar(a, b)' +5877@t.overload +5878def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: +5879 ... +5880 +5881 +5882@t.overload +5883def to_identifier( +5884 name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True +5885) -> Identifier: +5886 ... +5887 +5888 +5889def to_identifier(name, quoted=None, copy=True): +5890 """Builds an identifier. +5891 +5892 Args: +5893 name: The name to turn into an identifier. +5894 quoted: Whether or not force quote the identifier. +5895 copy: Whether or not to copy a passed in Identefier node. +5896 +5897 Returns: +5898 The identifier ast node. +5899 """ +5900 +5901 if name is None: +5902 return None +5903 +5904 if isinstance(name, Identifier): +5905 identifier = maybe_copy(name, copy) +5906 elif isinstance(name, str): +5907 identifier = Identifier( +5908 this=name, +5909 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, +5910 ) +5911 else: +5912 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") +5913 return identifier +5914 +5915 +5916INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*") +5917 +5918 +5919def to_interval(interval: str | Literal) -> Interval: +5920 """Builds an interval expression from a string like '1 day' or '5 months'.""" +5921 if isinstance(interval, Literal): +5922 if not interval.is_string: +5923 raise ValueError("Invalid interval string.") +5924 +5925 interval = interval.this +5926 +5927 interval_parts = INTERVAL_STRING_RE.match(interval) # type: ignore +5928 +5929 if not interval_parts: +5930 raise ValueError("Invalid interval string.") +5931 +5932 return Interval( +5933 this=Literal.string(interval_parts.group(1)), +5934 unit=Var(this=interval_parts.group(2)), +5935 ) +5936 +5937 +5938@t.overload +5939def to_table(sql_path: str | Table, **kwargs) -> Table: +5940 ... 5941 -5942 Args: -5943 expression: the SQL code strings to parse. -5944 If an Expression instance is passed, this is used as-is. -5945 alias: the alias name to use. If the name has -5946 special characters it is quoted. -5947 table: Whether or not to create a table alias, can also be a list of columns. -5948 quoted: whether or not to quote the alias -5949 dialect: the dialect used to parse the input expression. -5950 copy: Whether or not to copy the expression. -5951 **opts: other options to use to parse the input expressions. -5952 -5953 Returns: -5954 Alias: the aliased expression -5955 """ -5956 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) -5957 alias = to_identifier(alias, quoted=quoted) -5958 -5959 if table: -5960 table_alias = TableAlias(this=alias) -5961 exp.set("alias", table_alias) -5962 -5963 if not isinstance(table, bool): -5964 for column in table: -5965 table_alias.append("columns", to_identifier(column, quoted=quoted)) -5966 -5967 return exp -5968 -5969 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in -5970 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node -5971 # for the complete Window expression. -5972 # -5973 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls +5942 +5943@t.overload +5944def to_table(sql_path: None, **kwargs) -> None: +5945 ... +5946 +5947 +5948def to_table( +5949 sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs +5950) -> t.Optional[Table]: +5951 """ +5952 Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional. +5953 If a table is passed in then that table is returned. +5954 +5955 Args: +5956 sql_path: a `[catalog].[schema].[table]` string. +5957 dialect: the source dialect according to which the table name will be parsed. +5958 kwargs: the kwargs to instantiate the resulting `Table` expression with. +5959 +5960 Returns: +5961 A table expression. +5962 """ +5963 if sql_path is None or isinstance(sql_path, Table): +5964 return sql_path +5965 if not isinstance(sql_path, str): +5966 raise ValueError(f"Invalid type provided for a table: {type(sql_path)}") +5967 +5968 table = maybe_parse(sql_path, into=Table, dialect=dialect) +5969 if table: +5970 for k, v in kwargs.items(): +5971 table.set(k, v) +5972 +5973 return table 5974 -5975 if "alias" in exp.arg_types and not isinstance(exp, Window): -5976 exp.set("alias", alias) -5977 return exp -5978 return Alias(this=exp, alias=alias) +5975 +5976def to_column(sql_path: str | Column, **kwargs) -> Column: +5977 """ +5978 Create a column from a `[table].[column]` sql path. Schema is optional. 5979 -5980 -5981def subquery( -5982 expression: ExpOrStr, -5983 alias: t.Optional[Identifier | str] = None, -5984 dialect: DialectType = None, -5985 **opts, -5986) -> Select: -5987 """ -5988 Build a subquery expression. -5989 -5990 Example: -5991 >>> subquery('select x from tbl', 'bar').select('x').sql() -5992 'SELECT x FROM (SELECT x FROM tbl) AS bar' +5980 If a column is passed in then that column is returned. +5981 +5982 Args: +5983 sql_path: `[table].[column]` string +5984 Returns: +5985 Table: A column expression +5986 """ +5987 if sql_path is None or isinstance(sql_path, Column): +5988 return sql_path +5989 if not isinstance(sql_path, str): +5990 raise ValueError(f"Invalid type provided for column: {type(sql_path)}") +5991 return column(*reversed(sql_path.split(".")), **kwargs) # type: ignore +5992 5993 -5994 Args: -5995 expression: the SQL code strings to parse. -5996 If an Expression instance is passed, this is used as-is. -5997 alias: the alias name to use. -5998 dialect: the dialect used to parse the input expression. -5999 **opts: other options to use to parse the input expressions. -6000 -6001 Returns: -6002 A new Select instance with the subquery expression included. -6003 """ +5994def alias_( +5995 expression: ExpOrStr, +5996 alias: str | Identifier, +5997 table: bool | t.Sequence[str | Identifier] = False, +5998 quoted: t.Optional[bool] = None, +5999 dialect: DialectType = None, +6000 copy: bool = True, +6001 **opts, +6002): +6003 """Create an Alias expression. 6004 -6005 expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias) -6006 return Select().from_(expression, dialect=dialect, **opts) -6007 +6005 Example: +6006 >>> alias_('foo', 'bar').sql() +6007 'foo AS bar' 6008 -6009def column( -6010 col: str | Identifier, -6011 table: t.Optional[str | Identifier] = None, -6012 db: t.Optional[str | Identifier] = None, -6013 catalog: t.Optional[str | Identifier] = None, -6014 quoted: t.Optional[bool] = None, -6015) -> Column: -6016 """ -6017 Build a Column. -6018 -6019 Args: -6020 col: Column name. -6021 table: Table name. -6022 db: Database name. -6023 catalog: Catalog name. -6024 quoted: Whether to force quotes on the column's identifiers. -6025 -6026 Returns: -6027 The new Column instance. -6028 """ -6029 return Column( -6030 this=to_identifier(col, quoted=quoted), -6031 table=to_identifier(table, quoted=quoted), -6032 db=to_identifier(db, quoted=quoted), -6033 catalog=to_identifier(catalog, quoted=quoted), -6034 ) -6035 +6009 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() +6010 '(SELECT 1, 2) AS bar(a, b)' +6011 +6012 Args: +6013 expression: the SQL code strings to parse. +6014 If an Expression instance is passed, this is used as-is. +6015 alias: the alias name to use. If the name has +6016 special characters it is quoted. +6017 table: Whether or not to create a table alias, can also be a list of columns. +6018 quoted: whether or not to quote the alias +6019 dialect: the dialect used to parse the input expression. +6020 copy: Whether or not to copy the expression. +6021 **opts: other options to use to parse the input expressions. +6022 +6023 Returns: +6024 Alias: the aliased expression +6025 """ +6026 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) +6027 alias = to_identifier(alias, quoted=quoted) +6028 +6029 if table: +6030 table_alias = TableAlias(this=alias) +6031 exp.set("alias", table_alias) +6032 +6033 if not isinstance(table, bool): +6034 for column in table: +6035 table_alias.append("columns", to_identifier(column, quoted=quoted)) 6036 -6037def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast: -6038 """Cast an expression to a data type. -6039 -6040 Example: -6041 >>> cast('x + 1', 'int').sql() -6042 'CAST(x + 1 AS INT)' -6043 -6044 Args: -6045 expression: The expression to cast. -6046 to: The datatype to cast to. -6047 -6048 Returns: -6049 The new Cast instance. -6050 """ -6051 expression = maybe_parse(expression, **opts) -6052 data_type = DataType.build(to, **opts) -6053 expression = Cast(this=expression, to=data_type) -6054 expression.type = data_type -6055 return expression -6056 -6057 -6058def table_( -6059 table: Identifier | str, -6060 db: t.Optional[Identifier | str] = None, -6061 catalog: t.Optional[Identifier | str] = None, -6062 quoted: t.Optional[bool] = None, -6063 alias: t.Optional[Identifier | str] = None, -6064) -> Table: -6065 """Build a Table. -6066 -6067 Args: -6068 table: Table name. -6069 db: Database name. -6070 catalog: Catalog name. -6071 quote: Whether to force quotes on the table's identifiers. -6072 alias: Table's alias. -6073 -6074 Returns: -6075 The new Table instance. -6076 """ -6077 return Table( -6078 this=to_identifier(table, quoted=quoted) if table else None, -6079 db=to_identifier(db, quoted=quoted) if db else None, -6080 catalog=to_identifier(catalog, quoted=quoted) if catalog else None, -6081 alias=TableAlias(this=to_identifier(alias)) if alias else None, -6082 ) -6083 -6084 -6085def values( -6086 values: t.Iterable[t.Tuple[t.Any, ...]], -6087 alias: t.Optional[str] = None, -6088 columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None, -6089) -> Values: -6090 """Build VALUES statement. -6091 -6092 Example: -6093 >>> values([(1, '2')]).sql() -6094 "VALUES (1, '2')" +6037 return exp +6038 +6039 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in +6040 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node +6041 # for the complete Window expression. +6042 # +6043 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls +6044 +6045 if "alias" in exp.arg_types and not isinstance(exp, Window): +6046 exp.set("alias", alias) +6047 return exp +6048 return Alias(this=exp, alias=alias) +6049 +6050 +6051def subquery( +6052 expression: ExpOrStr, +6053 alias: t.Optional[Identifier | str] = None, +6054 dialect: DialectType = None, +6055 **opts, +6056) -> Select: +6057 """ +6058 Build a subquery expression. +6059 +6060 Example: +6061 >>> subquery('select x from tbl', 'bar').select('x').sql() +6062 'SELECT x FROM (SELECT x FROM tbl) AS bar' +6063 +6064 Args: +6065 expression: the SQL code strings to parse. +6066 If an Expression instance is passed, this is used as-is. +6067 alias: the alias name to use. +6068 dialect: the dialect used to parse the input expression. +6069 **opts: other options to use to parse the input expressions. +6070 +6071 Returns: +6072 A new Select instance with the subquery expression included. +6073 """ +6074 +6075 expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias) +6076 return Select().from_(expression, dialect=dialect, **opts) +6077 +6078 +6079def column( +6080 col: str | Identifier, +6081 table: t.Optional[str | Identifier] = None, +6082 db: t.Optional[str | Identifier] = None, +6083 catalog: t.Optional[str | Identifier] = None, +6084 quoted: t.Optional[bool] = None, +6085) -> Column: +6086 """ +6087 Build a Column. +6088 +6089 Args: +6090 col: Column name. +6091 table: Table name. +6092 db: Database name. +6093 catalog: Catalog name. +6094 quoted: Whether to force quotes on the column's identifiers. 6095 -6096 Args: -6097 values: values statements that will be converted to SQL -6098 alias: optional alias -6099 columns: Optional list of ordered column names or ordered dictionary of column names to types. -6100 If either are provided then an alias is also required. -6101 -6102 Returns: -6103 Values: the Values expression object -6104 """ -6105 if columns and not alias: -6106 raise ValueError("Alias is required when providing columns") -6107 -6108 return Values( -6109 expressions=[convert(tup) for tup in values], -6110 alias=( -6111 TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns]) -6112 if columns -6113 else (TableAlias(this=to_identifier(alias)) if alias else None) -6114 ), -6115 ) -6116 +6096 Returns: +6097 The new Column instance. +6098 """ +6099 return Column( +6100 this=to_identifier(col, quoted=quoted), +6101 table=to_identifier(table, quoted=quoted), +6102 db=to_identifier(db, quoted=quoted), +6103 catalog=to_identifier(catalog, quoted=quoted), +6104 ) +6105 +6106 +6107def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast: +6108 """Cast an expression to a data type. +6109 +6110 Example: +6111 >>> cast('x + 1', 'int').sql() +6112 'CAST(x + 1 AS INT)' +6113 +6114 Args: +6115 expression: The expression to cast. +6116 to: The datatype to cast to. 6117 -6118def var(name: t.Optional[ExpOrStr]) -> Var: -6119 """Build a SQL variable. -6120 -6121 Example: -6122 >>> repr(var('x')) -6123 '(VAR this: x)' -6124 -6125 >>> repr(var(column('x', table='y'))) -6126 '(VAR this: x)' +6118 Returns: +6119 The new Cast instance. +6120 """ +6121 expression = maybe_parse(expression, **opts) +6122 data_type = DataType.build(to, **opts) +6123 expression = Cast(this=expression, to=data_type) +6124 expression.type = data_type +6125 return expression +6126 6127 -6128 Args: -6129 name: The name of the var or an expression who's name will become the var. -6130 -6131 Returns: -6132 The new variable node. -6133 """ -6134 if not name: -6135 raise ValueError("Cannot convert empty name into var.") +6128def table_( +6129 table: Identifier | str, +6130 db: t.Optional[Identifier | str] = None, +6131 catalog: t.Optional[Identifier | str] = None, +6132 quoted: t.Optional[bool] = None, +6133 alias: t.Optional[Identifier | str] = None, +6134) -> Table: +6135 """Build a Table. 6136 -6137 if isinstance(name, Expression): -6138 name = name.name -6139 return Var(this=name) -6140 -6141 -6142def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable: -6143 """Build ALTER TABLE... RENAME... expression -6144 -6145 Args: -6146 old_name: The old name of the table -6147 new_name: The new name of the table -6148 -6149 Returns: -6150 Alter table expression -6151 """ -6152 old_table = to_table(old_name) -6153 new_table = to_table(new_name) -6154 return AlterTable( -6155 this=old_table, -6156 actions=[ -6157 RenameTable(this=new_table), -6158 ], -6159 ) -6160 +6137 Args: +6138 table: Table name. +6139 db: Database name. +6140 catalog: Catalog name. +6141 quote: Whether to force quotes on the table's identifiers. +6142 alias: Table's alias. +6143 +6144 Returns: +6145 The new Table instance. +6146 """ +6147 return Table( +6148 this=to_identifier(table, quoted=quoted) if table else None, +6149 db=to_identifier(db, quoted=quoted) if db else None, +6150 catalog=to_identifier(catalog, quoted=quoted) if catalog else None, +6151 alias=TableAlias(this=to_identifier(alias)) if alias else None, +6152 ) +6153 +6154 +6155def values( +6156 values: t.Iterable[t.Tuple[t.Any, ...]], +6157 alias: t.Optional[str] = None, +6158 columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None, +6159) -> Values: +6160 """Build VALUES statement. 6161 -6162def convert(value: t.Any, copy: bool = False) -> Expression: -6163 """Convert a python value into an expression object. -6164 -6165 Raises an error if a conversion is not possible. -6166 -6167 Args: -6168 value: A python object. -6169 copy: Whether or not to copy `value` (only applies to Expressions and collections). -6170 -6171 Returns: -6172 Expression: the equivalent expression object. -6173 """ -6174 if isinstance(value, Expression): -6175 return maybe_copy(value, copy) -6176 if isinstance(value, str): -6177 return Literal.string(value) -6178 if isinstance(value, bool): -6179 return Boolean(this=value) -6180 if value is None or (isinstance(value, float) and math.isnan(value)): -6181 return NULL -6182 if isinstance(value, numbers.Number): -6183 return Literal.number(value) -6184 if isinstance(value, datetime.datetime): -6185 datetime_literal = Literal.string( -6186 (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat() -6187 ) -6188 return TimeStrToTime(this=datetime_literal) -6189 if isinstance(value, datetime.date): -6190 date_literal = Literal.string(value.strftime("%Y-%m-%d")) -6191 return DateStrToDate(this=date_literal) -6192 if isinstance(value, tuple): -6193 return Tuple(expressions=[convert(v, copy=copy) for v in value]) -6194 if isinstance(value, list): -6195 return Array(expressions=[convert(v, copy=copy) for v in value]) -6196 if isinstance(value, dict): -6197 return Map( -6198 keys=Array(expressions=[convert(k, copy=copy) for k in value]), -6199 values=Array(expressions=[convert(v, copy=copy) for v in value.values()]), -6200 ) -6201 raise ValueError(f"Cannot convert {value}") -6202 -6203 -6204def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None: -6205 """ -6206 Replace children of an expression with the result of a lambda fun(child) -> exp. -6207 """ -6208 for k, v in expression.args.items(): -6209 is_list_arg = type(v) is list +6162 Example: +6163 >>> values([(1, '2')]).sql() +6164 "VALUES (1, '2')" +6165 +6166 Args: +6167 values: values statements that will be converted to SQL +6168 alias: optional alias +6169 columns: Optional list of ordered column names or ordered dictionary of column names to types. +6170 If either are provided then an alias is also required. +6171 +6172 Returns: +6173 Values: the Values expression object +6174 """ +6175 if columns and not alias: +6176 raise ValueError("Alias is required when providing columns") +6177 +6178 return Values( +6179 expressions=[convert(tup) for tup in values], +6180 alias=( +6181 TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns]) +6182 if columns +6183 else (TableAlias(this=to_identifier(alias)) if alias else None) +6184 ), +6185 ) +6186 +6187 +6188def var(name: t.Optional[ExpOrStr]) -> Var: +6189 """Build a SQL variable. +6190 +6191 Example: +6192 >>> repr(var('x')) +6193 '(VAR this: x)' +6194 +6195 >>> repr(var(column('x', table='y'))) +6196 '(VAR this: x)' +6197 +6198 Args: +6199 name: The name of the var or an expression who's name will become the var. +6200 +6201 Returns: +6202 The new variable node. +6203 """ +6204 if not name: +6205 raise ValueError("Cannot convert empty name into var.") +6206 +6207 if isinstance(name, Expression): +6208 name = name.name +6209 return Var(this=name) 6210 -6211 child_nodes = v if is_list_arg else [v] -6212 new_child_nodes = [] -6213 -6214 for cn in child_nodes: -6215 if isinstance(cn, Expression): -6216 for child_node in ensure_collection(fun(cn, *args, **kwargs)): -6217 new_child_nodes.append(child_node) -6218 child_node.parent = expression -6219 child_node.arg_key = k -6220 else: -6221 new_child_nodes.append(cn) -6222 -6223 expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0) -6224 -6225 -6226def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]: -6227 """ -6228 Return all table names referenced through columns in an expression. -6229 -6230 Example: -6231 >>> import sqlglot -6232 >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e"))) -6233 ['a', 'c'] +6211 +6212def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable: +6213 """Build ALTER TABLE... RENAME... expression +6214 +6215 Args: +6216 old_name: The old name of the table +6217 new_name: The new name of the table +6218 +6219 Returns: +6220 Alter table expression +6221 """ +6222 old_table = to_table(old_name) +6223 new_table = to_table(new_name) +6224 return AlterTable( +6225 this=old_table, +6226 actions=[ +6227 RenameTable(this=new_table), +6228 ], +6229 ) +6230 +6231 +6232def convert(value: t.Any, copy: bool = False) -> Expression: +6233 """Convert a python value into an expression object. 6234 -6235 Args: -6236 expression: expression to find table names. -6237 exclude: a table name to exclude -6238 -6239 Returns: -6240 A list of unique names. -6241 """ -6242 return { -6243 table -6244 for table in (column.table for column in expression.find_all(Column)) -6245 if table and table != exclude -6246 } -6247 -6248 -6249def table_name(table: Table | str, dialect: DialectType = None) -> str: -6250 """Get the full name of a table as a string. -6251 -6252 Args: -6253 table: Table expression node or string. -6254 dialect: The dialect to generate the table name for. -6255 -6256 Examples: -6257 >>> from sqlglot import exp, parse_one -6258 >>> table_name(parse_one("select * from a.b.c").find(exp.Table)) -6259 'a.b.c' -6260 -6261 Returns: -6262 The table name. -6263 """ -6264 -6265 table = maybe_parse(table, into=Table, dialect=dialect) -6266 -6267 if not table: -6268 raise ValueError(f"Cannot parse {table}") -6269 -6270 return ".".join( -6271 part.sql(dialect=dialect, identify=True) -6272 if not SAFE_IDENTIFIER_RE.match(part.name) -6273 else part.name -6274 for part in table.parts -6275 ) -6276 -6277 -6278def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E: -6279 """Replace all tables in expression according to the mapping. +6235 Raises an error if a conversion is not possible. +6236 +6237 Args: +6238 value: A python object. +6239 copy: Whether or not to copy `value` (only applies to Expressions and collections). +6240 +6241 Returns: +6242 Expression: the equivalent expression object. +6243 """ +6244 if isinstance(value, Expression): +6245 return maybe_copy(value, copy) +6246 if isinstance(value, str): +6247 return Literal.string(value) +6248 if isinstance(value, bool): +6249 return Boolean(this=value) +6250 if value is None or (isinstance(value, float) and math.isnan(value)): +6251 return NULL +6252 if isinstance(value, numbers.Number): +6253 return Literal.number(value) +6254 if isinstance(value, datetime.datetime): +6255 datetime_literal = Literal.string( +6256 (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat() +6257 ) +6258 return TimeStrToTime(this=datetime_literal) +6259 if isinstance(value, datetime.date): +6260 date_literal = Literal.string(value.strftime("%Y-%m-%d")) +6261 return DateStrToDate(this=date_literal) +6262 if isinstance(value, tuple): +6263 return Tuple(expressions=[convert(v, copy=copy) for v in value]) +6264 if isinstance(value, list): +6265 return Array(expressions=[convert(v, copy=copy) for v in value]) +6266 if isinstance(value, dict): +6267 return Map( +6268 keys=Array(expressions=[convert(k, copy=copy) for k in value]), +6269 values=Array(expressions=[convert(v, copy=copy) for v in value.values()]), +6270 ) +6271 raise ValueError(f"Cannot convert {value}") +6272 +6273 +6274def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None: +6275 """ +6276 Replace children of an expression with the result of a lambda fun(child) -> exp. +6277 """ +6278 for k, v in expression.args.items(): +6279 is_list_arg = type(v) is list 6280 -6281 Args: -6282 expression: expression node to be transformed and replaced. -6283 mapping: mapping of table names. -6284 copy: whether or not to copy the expression. -6285 -6286 Examples: -6287 >>> from sqlglot import exp, parse_one -6288 >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql() -6289 'SELECT * FROM c' -6290 -6291 Returns: -6292 The mapped expression. -6293 """ +6281 child_nodes = v if is_list_arg else [v] +6282 new_child_nodes = [] +6283 +6284 for cn in child_nodes: +6285 if isinstance(cn, Expression): +6286 for child_node in ensure_collection(fun(cn, *args, **kwargs)): +6287 new_child_nodes.append(child_node) +6288 child_node.parent = expression +6289 child_node.arg_key = k +6290 else: +6291 new_child_nodes.append(cn) +6292 +6293 expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0) 6294 -6295 def _replace_tables(node: Expression) -> Expression: -6296 if isinstance(node, Table): -6297 new_name = mapping.get(table_name(node)) -6298 if new_name: -6299 return to_table( -6300 new_name, -6301 **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")}, -6302 ) -6303 return node +6295 +6296def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]: +6297 """ +6298 Return all table names referenced through columns in an expression. +6299 +6300 Example: +6301 >>> import sqlglot +6302 >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e"))) +6303 ['a', 'c'] 6304 -6305 return expression.transform(_replace_tables, copy=copy) -6306 -6307 -6308def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression: -6309 """Replace placeholders in an expression. -6310 -6311 Args: -6312 expression: expression node to be transformed and replaced. -6313 args: positional names that will substitute unnamed placeholders in the given order. -6314 kwargs: keyword arguments that will substitute named placeholders. -6315 -6316 Examples: -6317 >>> from sqlglot import exp, parse_one -6318 >>> replace_placeholders( -6319 ... parse_one("select * from :tbl where ? = ?"), -6320 ... exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo") -6321 ... ).sql() -6322 "SELECT * FROM foo WHERE str_col = 'b'" -6323 -6324 Returns: -6325 The mapped expression. -6326 """ -6327 -6328 def _replace_placeholders(node: Expression, args, **kwargs) -> Expression: -6329 if isinstance(node, Placeholder): -6330 if node.name: -6331 new_name = kwargs.get(node.name) -6332 if new_name: -6333 return convert(new_name) -6334 else: -6335 try: -6336 return convert(next(args)) -6337 except StopIteration: -6338 pass -6339 return node -6340 -6341 return expression.transform(_replace_placeholders, iter(args), **kwargs) -6342 -6343 -6344def expand( -6345 expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True -6346) -> Expression: -6347 """Transforms an expression by expanding all referenced sources into subqueries. -6348 -6349 Examples: -6350 >>> from sqlglot import parse_one -6351 >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql() -6352 'SELECT * FROM (SELECT * FROM y) AS z /* source: x */' -6353 -6354 >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql() -6355 'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */' -6356 -6357 Args: -6358 expression: The expression to expand. -6359 sources: A dictionary of name to Subqueryables. -6360 copy: Whether or not to copy the expression during transformation. Defaults to True. -6361 -6362 Returns: -6363 The transformed expression. -6364 """ -6365 -6366 def _expand(node: Expression): -6367 if isinstance(node, Table): -6368 name = table_name(node) -6369 source = sources.get(name) -6370 if source: -6371 subquery = source.subquery(node.alias or name) -6372 subquery.comments = [f"source: {name}"] -6373 return subquery.transform(_expand, copy=False) -6374 return node -6375 -6376 return expression.transform(_expand, copy=copy) +6305 Args: +6306 expression: expression to find table names. +6307 exclude: a table name to exclude +6308 +6309 Returns: +6310 A list of unique names. +6311 """ +6312 return { +6313 table +6314 for table in (column.table for column in expression.find_all(Column)) +6315 if table and table != exclude +6316 } +6317 +6318 +6319def table_name(table: Table | str, dialect: DialectType = None) -> str: +6320 """Get the full name of a table as a string. +6321 +6322 Args: +6323 table: Table expression node or string. +6324 dialect: The dialect to generate the table name for. +6325 +6326 Examples: +6327 >>> from sqlglot import exp, parse_one +6328 >>> table_name(parse_one("select * from a.b.c").find(exp.Table)) +6329 'a.b.c' +6330 +6331 Returns: +6332 The table name. +6333 """ +6334 +6335 table = maybe_parse(table, into=Table, dialect=dialect) +6336 +6337 if not table: +6338 raise ValueError(f"Cannot parse {table}") +6339 +6340 return ".".join( +6341 part.sql(dialect=dialect, identify=True) +6342 if not SAFE_IDENTIFIER_RE.match(part.name) +6343 else part.name +6344 for part in table.parts +6345 ) +6346 +6347 +6348def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E: +6349 """Replace all tables in expression according to the mapping. +6350 +6351 Args: +6352 expression: expression node to be transformed and replaced. +6353 mapping: mapping of table names. +6354 copy: whether or not to copy the expression. +6355 +6356 Examples: +6357 >>> from sqlglot import exp, parse_one +6358 >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql() +6359 'SELECT * FROM c' +6360 +6361 Returns: +6362 The mapped expression. +6363 """ +6364 +6365 def _replace_tables(node: Expression) -> Expression: +6366 if isinstance(node, Table): +6367 new_name = mapping.get(table_name(node)) +6368 if new_name: +6369 return to_table( +6370 new_name, +6371 **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")}, +6372 ) +6373 return node +6374 +6375 return expression.transform(_replace_tables, copy=copy) +6376 6377 -6378 -6379def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func: -6380 """ -6381 Returns a Func expression. -6382 -6383 Examples: -6384 >>> func("abs", 5).sql() -6385 'ABS(5)' -6386 -6387 >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql() -6388 'CAST(5 AS DOUBLE)' -6389 -6390 Args: -6391 name: the name of the function to build. -6392 args: the args used to instantiate the function of interest. -6393 dialect: the source dialect. -6394 kwargs: the kwargs used to instantiate the function of interest. -6395 -6396 Note: -6397 The arguments `args` and `kwargs` are mutually exclusive. -6398 -6399 Returns: -6400 An instance of the function of interest, or an anonymous function, if `name` doesn't -6401 correspond to an existing `sqlglot.expressions.Func` class. -6402 """ -6403 if args and kwargs: -6404 raise ValueError("Can't use both args and kwargs to instantiate a function.") -6405 -6406 from sqlglot.dialects.dialect import Dialect -6407 -6408 converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args] -6409 kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()} +6378def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression: +6379 """Replace placeholders in an expression. +6380 +6381 Args: +6382 expression: expression node to be transformed and replaced. +6383 args: positional names that will substitute unnamed placeholders in the given order. +6384 kwargs: keyword arguments that will substitute named placeholders. +6385 +6386 Examples: +6387 >>> from sqlglot import exp, parse_one +6388 >>> replace_placeholders( +6389 ... parse_one("select * from :tbl where ? = ?"), +6390 ... exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo") +6391 ... ).sql() +6392 "SELECT * FROM foo WHERE str_col = 'b'" +6393 +6394 Returns: +6395 The mapped expression. +6396 """ +6397 +6398 def _replace_placeholders(node: Expression, args, **kwargs) -> Expression: +6399 if isinstance(node, Placeholder): +6400 if node.name: +6401 new_name = kwargs.get(node.name) +6402 if new_name: +6403 return convert(new_name) +6404 else: +6405 try: +6406 return convert(next(args)) +6407 except StopIteration: +6408 pass +6409 return node 6410 -6411 parser = Dialect.get_or_raise(dialect)().parser() -6412 from_args_list = parser.FUNCTIONS.get(name.upper()) +6411 return expression.transform(_replace_placeholders, iter(args), **kwargs) +6412 6413 -6414 if from_args_list: -6415 function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs) # type: ignore -6416 else: -6417 kwargs = kwargs or {"expressions": converted} -6418 function = Anonymous(this=name, **kwargs) -6419 -6420 for error_message in function.error_messages(converted): -6421 raise ValueError(error_message) -6422 -6423 return function -6424 -6425 -6426def true() -> Boolean: -6427 """ -6428 Returns a true Boolean expression. -6429 """ -6430 return Boolean(this=True) +6414def expand( +6415 expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True +6416) -> Expression: +6417 """Transforms an expression by expanding all referenced sources into subqueries. +6418 +6419 Examples: +6420 >>> from sqlglot import parse_one +6421 >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql() +6422 'SELECT * FROM (SELECT * FROM y) AS z /* source: x */' +6423 +6424 >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql() +6425 'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */' +6426 +6427 Args: +6428 expression: The expression to expand. +6429 sources: A dictionary of name to Subqueryables. +6430 copy: Whether or not to copy the expression during transformation. Defaults to True. 6431 -6432 -6433def false() -> Boolean: -6434 """ -6435 Returns a false Boolean expression. -6436 """ -6437 return Boolean(this=False) -6438 -6439 -6440def null() -> Null: -6441 """ -6442 Returns a Null expression. -6443 """ -6444 return Null() +6432 Returns: +6433 The transformed expression. +6434 """ +6435 +6436 def _expand(node: Expression): +6437 if isinstance(node, Table): +6438 name = table_name(node) +6439 source = sources.get(name) +6440 if source: +6441 subquery = source.subquery(node.alias or name) +6442 subquery.comments = [f"source: {name}"] +6443 return subquery.transform(_expand, copy=False) +6444 return node 6445 -6446 -6447# TODO: deprecate this -6448TRUE = Boolean(this=True) -6449FALSE = Boolean(this=False) -6450NULL = Null() +6446 return expression.transform(_expand, copy=copy) +6447 +6448 +6449def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func: +6450 """ +6451 Returns a Func expression. +6452 +6453 Examples: +6454 >>> func("abs", 5).sql() +6455 'ABS(5)' +6456 +6457 >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql() +6458 'CAST(5 AS DOUBLE)' +6459 +6460 Args: +6461 name: the name of the function to build. +6462 args: the args used to instantiate the function of interest. +6463 dialect: the source dialect. +6464 kwargs: the kwargs used to instantiate the function of interest. +6465 +6466 Note: +6467 The arguments `args` and `kwargs` are mutually exclusive. +6468 +6469 Returns: +6470 An instance of the function of interest, or an anonymous function, if `name` doesn't +6471 correspond to an existing `sqlglot.expressions.Func` class. +6472 """ +6473 if args and kwargs: +6474 raise ValueError("Can't use both args and kwargs to instantiate a function.") +6475 +6476 from sqlglot.dialects.dialect import Dialect +6477 +6478 converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args] +6479 kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()} +6480 +6481 parser = Dialect.get_or_raise(dialect)().parser() +6482 from_args_list = parser.FUNCTIONS.get(name.upper()) +6483 +6484 if from_args_list: +6485 function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs) # type: ignore +6486 else: +6487 kwargs = kwargs or {"expressions": converted} +6488 function = Anonymous(this=name, **kwargs) +6489 +6490 for error_message in function.error_messages(converted): +6491 raise ValueError(error_message) +6492 +6493 return function +6494 +6495 +6496def true() -> Boolean: +6497 """ +6498 Returns a true Boolean expression. +6499 """ +6500 return Boolean(this=True) +6501 +6502 +6503def false() -> Boolean: +6504 """ +6505 Returns a false Boolean expression. +6506 """ +6507 return Boolean(this=False) +6508 +6509 +6510def null() -> Null: +6511 """ +6512 Returns a Null expression. +6513 """ +6514 return Null() +6515 +6516 +6517# TODO: deprecate this +6518TRUE = Boolean(this=True) +6519FALSE = Boolean(this=False) +6520NULL = Null() @@ -32852,6 +32994,235 @@ Otherwise, this resets the expression.
    neq
    rlike
    + + + + +
    + +
    + + class + PartitionBoundSpec(Expression): + + + +
    + +
    2150class PartitionBoundSpec(Expression):
    +2151    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
    +2152    arg_types = {
    +2153        "this": False,
    +2154        "expression": False,
    +2155        "from_expressions": False,
    +2156        "to_expressions": False,
    +2157    }
    +
    + + + + +
    +
    + arg_types = +{'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False} + + +
    + + + + +
    +
    +
    + key = +'partitionboundspec' + + +
    + + + + +
    + +
    +
    + +
    + + class + PartitionedOfProperty(Property): + + + +
    + +
    2160class PartitionedOfProperty(Property):
    +2161    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
    +2162    arg_types = {"this": True, "expression": True}
    +
    + + + + +
    +
    + arg_types = +{'this': True, 'expression': True} + + +
    + + + + +
    +
    +
    + key = +'partitionedofproperty' + + +
    + + + + +
    + @@ -32867,8 +33238,8 @@ Otherwise, this resets the expression. -
    2149class RemoteWithConnectionModelProperty(Property):
    -2150    arg_types = {"this": True}
    +            
    2165class RemoteWithConnectionModelProperty(Property):
    +2166    arg_types = {"this": True}
     
    @@ -32978,8 +33349,8 @@ Otherwise, this resets the expression.
    -
    2153class ReturnsProperty(Property):
    -2154    arg_types = {"this": True, "is_table": False, "table": False}
    +            
    2169class ReturnsProperty(Property):
    +2170    arg_types = {"this": True, "is_table": False, "table": False}
     
    @@ -33089,8 +33460,8 @@ Otherwise, this resets the expression.
    -
    2157class RowFormatProperty(Property):
    -2158    arg_types = {"this": True}
    +            
    2173class RowFormatProperty(Property):
    +2174    arg_types = {"this": True}
     
    @@ -33200,17 +33571,17 @@ Otherwise, this resets the expression.
    -
    2161class RowFormatDelimitedProperty(Property):
    -2162    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
    -2163    arg_types = {
    -2164        "fields": False,
    -2165        "escaped": False,
    -2166        "collection_items": False,
    -2167        "map_keys": False,
    -2168        "lines": False,
    -2169        "null": False,
    -2170        "serde": False,
    -2171    }
    +            
    2177class RowFormatDelimitedProperty(Property):
    +2178    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
    +2179    arg_types = {
    +2180        "fields": False,
    +2181        "escaped": False,
    +2182        "collection_items": False,
    +2183        "map_keys": False,
    +2184        "lines": False,
    +2185        "null": False,
    +2186        "serde": False,
    +2187    }
     
    @@ -33321,8 +33692,8 @@ Otherwise, this resets the expression.
    -
    2174class RowFormatSerdeProperty(Property):
    -2175    arg_types = {"this": True, "serde_properties": False}
    +            
    2190class RowFormatSerdeProperty(Property):
    +2191    arg_types = {"this": True, "serde_properties": False}
     
    @@ -33432,16 +33803,16 @@ Otherwise, this resets the expression.
    -
    2179class QueryTransform(Expression):
    -2180    arg_types = {
    -2181        "expressions": True,
    -2182        "command_script": True,
    -2183        "schema": False,
    -2184        "row_format_before": False,
    -2185        "record_writer": False,
    -2186        "row_format_after": False,
    -2187        "record_reader": False,
    -2188    }
    +            
    2195class QueryTransform(Expression):
    +2196    arg_types = {
    +2197        "expressions": True,
    +2198        "command_script": True,
    +2199        "schema": False,
    +2200        "row_format_before": False,
    +2201        "record_writer": False,
    +2202        "row_format_after": False,
    +2203        "record_reader": False,
    +2204    }
     
    @@ -33552,8 +33923,8 @@ Otherwise, this resets the expression.
    -
    2191class SampleProperty(Property):
    -2192    arg_types = {"this": True}
    +            
    2207class SampleProperty(Property):
    +2208    arg_types = {"this": True}
     
    @@ -33663,8 +34034,8 @@ Otherwise, this resets the expression.
    -
    2195class SchemaCommentProperty(Property):
    -2196    arg_types = {"this": True}
    +            
    2211class SchemaCommentProperty(Property):
    +2212    arg_types = {"this": True}
     
    @@ -33774,8 +34145,8 @@ Otherwise, this resets the expression.
    -
    2199class SerdeProperties(Property):
    -2200    arg_types = {"expressions": True}
    +            
    2215class SerdeProperties(Property):
    +2216    arg_types = {"expressions": True}
     
    @@ -33885,8 +34256,8 @@ Otherwise, this resets the expression.
    -
    2203class SetProperty(Property):
    -2204    arg_types = {"multi": True}
    +            
    2219class SetProperty(Property):
    +2220    arg_types = {"multi": True}
     
    @@ -33996,8 +34367,8 @@ Otherwise, this resets the expression.
    -
    2207class SettingsProperty(Property):
    -2208    arg_types = {"expressions": True}
    +            
    2223class SettingsProperty(Property):
    +2224    arg_types = {"expressions": True}
     
    @@ -34107,8 +34478,8 @@ Otherwise, this resets the expression.
    -
    2211class SortKeyProperty(Property):
    -2212    arg_types = {"this": True, "compound": False}
    +            
    2227class SortKeyProperty(Property):
    +2228    arg_types = {"this": True, "compound": False}
     
    @@ -34218,8 +34589,8 @@ Otherwise, this resets the expression.
    -
    2215class SqlSecurityProperty(Property):
    -2216    arg_types = {"definer": True}
    +            
    2231class SqlSecurityProperty(Property):
    +2232    arg_types = {"definer": True}
     
    @@ -34329,8 +34700,8 @@ Otherwise, this resets the expression.
    -
    2219class StabilityProperty(Property):
    -2220    arg_types = {"this": True}
    +            
    2235class StabilityProperty(Property):
    +2236    arg_types = {"this": True}
     
    @@ -34440,8 +34811,8 @@ Otherwise, this resets the expression.
    -
    2223class TemporaryProperty(Property):
    -2224    arg_types = {}
    +            
    2239class TemporaryProperty(Property):
    +2240    arg_types = {}
     
    @@ -34551,8 +34922,8 @@ Otherwise, this resets the expression.
    -
    2227class TransformModelProperty(Property):
    -2228    arg_types = {"expressions": True}
    +            
    2243class TransformModelProperty(Property):
    +2244    arg_types = {"expressions": True}
     
    @@ -34662,8 +35033,8 @@ Otherwise, this resets the expression.
    -
    2231class TransientProperty(Property):
    -2232    arg_types = {"this": False}
    +            
    2247class TransientProperty(Property):
    +2248    arg_types = {"this": False}
     
    @@ -34773,8 +35144,8 @@ Otherwise, this resets the expression.
    -
    2235class VolatileProperty(Property):
    -2236    arg_types = {"this": False}
    +            
    2251class VolatileProperty(Property):
    +2252    arg_types = {"this": False}
     
    @@ -34884,8 +35255,8 @@ Otherwise, this resets the expression.
    -
    2239class WithDataProperty(Property):
    -2240    arg_types = {"no": True, "statistics": False}
    +            
    2255class WithDataProperty(Property):
    +2256    arg_types = {"no": True, "statistics": False}
     
    @@ -34995,8 +35366,8 @@ Otherwise, this resets the expression.
    -
    2243class WithJournalTableProperty(Property):
    -2244    arg_types = {"this": True}
    +            
    2259class WithJournalTableProperty(Property):
    +2260    arg_types = {"this": True}
     
    @@ -35106,66 +35477,66 @@ Otherwise, this resets the expression.
    -
    2247class Properties(Expression):
    -2248    arg_types = {"expressions": True}
    -2249
    -2250    NAME_TO_PROPERTY = {
    -2251        "ALGORITHM": AlgorithmProperty,
    -2252        "AUTO_INCREMENT": AutoIncrementProperty,
    -2253        "CHARACTER SET": CharacterSetProperty,
    -2254        "CLUSTERED_BY": ClusteredByProperty,
    -2255        "COLLATE": CollateProperty,
    -2256        "COMMENT": SchemaCommentProperty,
    -2257        "DEFINER": DefinerProperty,
    -2258        "DISTKEY": DistKeyProperty,
    -2259        "DISTSTYLE": DistStyleProperty,
    -2260        "ENGINE": EngineProperty,
    -2261        "EXECUTE AS": ExecuteAsProperty,
    -2262        "FORMAT": FileFormatProperty,
    -2263        "LANGUAGE": LanguageProperty,
    -2264        "LOCATION": LocationProperty,
    -2265        "PARTITIONED_BY": PartitionedByProperty,
    -2266        "RETURNS": ReturnsProperty,
    -2267        "ROW_FORMAT": RowFormatProperty,
    -2268        "SORTKEY": SortKeyProperty,
    -2269    }
    -2270
    -2271    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
    -2272
    -2273    # CREATE property locations
    -2274    # Form: schema specified
    -2275    #   create [POST_CREATE]
    -2276    #     table a [POST_NAME]
    -2277    #     (b int) [POST_SCHEMA]
    -2278    #     with ([POST_WITH])
    -2279    #     index (b) [POST_INDEX]
    -2280    #
    -2281    # Form: alias selection
    -2282    #   create [POST_CREATE]
    -2283    #     table a [POST_NAME]
    -2284    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
    -2285    #     index (c) [POST_INDEX]
    -2286    class Location(AutoName):
    -2287        POST_CREATE = auto()
    -2288        POST_NAME = auto()
    -2289        POST_SCHEMA = auto()
    -2290        POST_WITH = auto()
    -2291        POST_ALIAS = auto()
    -2292        POST_EXPRESSION = auto()
    -2293        POST_INDEX = auto()
    -2294        UNSUPPORTED = auto()
    -2295
    -2296    @classmethod
    -2297    def from_dict(cls, properties_dict: t.Dict) -> Properties:
    -2298        expressions = []
    -2299        for key, value in properties_dict.items():
    -2300            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
    -2301            if property_cls:
    -2302                expressions.append(property_cls(this=convert(value)))
    -2303            else:
    -2304                expressions.append(Property(this=Literal.string(key), value=convert(value)))
    -2305
    -2306        return cls(expressions=expressions)
    +            
    2263class Properties(Expression):
    +2264    arg_types = {"expressions": True}
    +2265
    +2266    NAME_TO_PROPERTY = {
    +2267        "ALGORITHM": AlgorithmProperty,
    +2268        "AUTO_INCREMENT": AutoIncrementProperty,
    +2269        "CHARACTER SET": CharacterSetProperty,
    +2270        "CLUSTERED_BY": ClusteredByProperty,
    +2271        "COLLATE": CollateProperty,
    +2272        "COMMENT": SchemaCommentProperty,
    +2273        "DEFINER": DefinerProperty,
    +2274        "DISTKEY": DistKeyProperty,
    +2275        "DISTSTYLE": DistStyleProperty,
    +2276        "ENGINE": EngineProperty,
    +2277        "EXECUTE AS": ExecuteAsProperty,
    +2278        "FORMAT": FileFormatProperty,
    +2279        "LANGUAGE": LanguageProperty,
    +2280        "LOCATION": LocationProperty,
    +2281        "PARTITIONED_BY": PartitionedByProperty,
    +2282        "RETURNS": ReturnsProperty,
    +2283        "ROW_FORMAT": RowFormatProperty,
    +2284        "SORTKEY": SortKeyProperty,
    +2285    }
    +2286
    +2287    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
    +2288
    +2289    # CREATE property locations
    +2290    # Form: schema specified
    +2291    #   create [POST_CREATE]
    +2292    #     table a [POST_NAME]
    +2293    #     (b int) [POST_SCHEMA]
    +2294    #     with ([POST_WITH])
    +2295    #     index (b) [POST_INDEX]
    +2296    #
    +2297    # Form: alias selection
    +2298    #   create [POST_CREATE]
    +2299    #     table a [POST_NAME]
    +2300    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
    +2301    #     index (c) [POST_INDEX]
    +2302    class Location(AutoName):
    +2303        POST_CREATE = auto()
    +2304        POST_NAME = auto()
    +2305        POST_SCHEMA = auto()
    +2306        POST_WITH = auto()
    +2307        POST_ALIAS = auto()
    +2308        POST_EXPRESSION = auto()
    +2309        POST_INDEX = auto()
    +2310        UNSUPPORTED = auto()
    +2311
    +2312    @classmethod
    +2313    def from_dict(cls, properties_dict: t.Dict) -> Properties:
    +2314        expressions = []
    +2315        for key, value in properties_dict.items():
    +2316            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
    +2317            if property_cls:
    +2318                expressions.append(property_cls(this=convert(value)))
    +2319            else:
    +2320                expressions.append(Property(this=Literal.string(key), value=convert(value)))
    +2321
    +2322        return cls(expressions=expressions)
     
    @@ -35221,17 +35592,17 @@ Otherwise, this resets the expression.
    -
    2296    @classmethod
    -2297    def from_dict(cls, properties_dict: t.Dict) -> Properties:
    -2298        expressions = []
    -2299        for key, value in properties_dict.items():
    -2300            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
    -2301            if property_cls:
    -2302                expressions.append(property_cls(this=convert(value)))
    -2303            else:
    -2304                expressions.append(Property(this=Literal.string(key), value=convert(value)))
    -2305
    -2306        return cls(expressions=expressions)
    +            
    2312    @classmethod
    +2313    def from_dict(cls, properties_dict: t.Dict) -> Properties:
    +2314        expressions = []
    +2315        for key, value in properties_dict.items():
    +2316            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
    +2317            if property_cls:
    +2318                expressions.append(property_cls(this=convert(value)))
    +2319            else:
    +2320                expressions.append(Property(this=Literal.string(key), value=convert(value)))
    +2321
    +2322        return cls(expressions=expressions)
     
    @@ -35330,15 +35701,15 @@ Otherwise, this resets the expression.
    -
    2286    class Location(AutoName):
    -2287        POST_CREATE = auto()
    -2288        POST_NAME = auto()
    -2289        POST_SCHEMA = auto()
    -2290        POST_WITH = auto()
    -2291        POST_ALIAS = auto()
    -2292        POST_EXPRESSION = auto()
    -2293        POST_INDEX = auto()
    -2294        UNSUPPORTED = auto()
    +            
    2302    class Location(AutoName):
    +2303        POST_CREATE = auto()
    +2304        POST_NAME = auto()
    +2305        POST_SCHEMA = auto()
    +2306        POST_WITH = auto()
    +2307        POST_ALIAS = auto()
    +2308        POST_EXPRESSION = auto()
    +2309        POST_INDEX = auto()
    +2310        UNSUPPORTED = auto()
     
    @@ -35464,8 +35835,8 @@ Otherwise, this resets the expression.
    -
    2309class Qualify(Expression):
    -2310    pass
    +            
    2325class Qualify(Expression):
    +2326    pass
     
    @@ -35564,8 +35935,8 @@ Otherwise, this resets the expression.
    -
    2313class InputOutputFormat(Expression):
    -2314    arg_types = {"input_format": False, "output_format": False}
    +            
    2329class InputOutputFormat(Expression):
    +2330    arg_types = {"input_format": False, "output_format": False}
     
    @@ -35675,8 +36046,8 @@ Otherwise, this resets the expression.
    -
    2318class Return(Expression):
    -2319    pass
    +            
    2334class Return(Expression):
    +2335    pass
     
    @@ -35775,8 +36146,8 @@ Otherwise, this resets the expression.
    -
    2322class Reference(Expression):
    -2323    arg_types = {"this": True, "expressions": False, "options": False}
    +            
    2338class Reference(Expression):
    +2339    arg_types = {"this": True, "expressions": False, "options": False}
     
    @@ -35886,29 +36257,29 @@ Otherwise, this resets the expression.
    -
    2326class Tuple(Expression):
    -2327    arg_types = {"expressions": False}
    -2328
    -2329    def isin(
    -2330        self,
    -2331        *expressions: t.Any,
    -2332        query: t.Optional[ExpOrStr] = None,
    -2333        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
    -2334        copy: bool = True,
    -2335        **opts,
    -2336    ) -> In:
    -2337        return In(
    -2338            this=maybe_copy(self, copy),
    -2339            expressions=[convert(e, copy=copy) for e in expressions],
    -2340            query=maybe_parse(query, copy=copy, **opts) if query else None,
    -2341            unnest=Unnest(
    -2342                expressions=[
    -2343                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
    -2344                ]
    -2345            )
    -2346            if unnest
    -2347            else None,
    -2348        )
    +            
    2342class Tuple(Expression):
    +2343    arg_types = {"expressions": False}
    +2344
    +2345    def isin(
    +2346        self,
    +2347        *expressions: t.Any,
    +2348        query: t.Optional[ExpOrStr] = None,
    +2349        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
    +2350        copy: bool = True,
    +2351        **opts,
    +2352    ) -> In:
    +2353        return In(
    +2354            this=maybe_copy(self, copy),
    +2355            expressions=[convert(e, copy=copy) for e in expressions],
    +2356            query=maybe_parse(query, copy=copy, **opts) if query else None,
    +2357            unnest=Unnest(
    +2358                expressions=[
    +2359                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
    +2360                ]
    +2361            )
    +2362            if unnest
    +2363            else None,
    +2364        )
     
    @@ -35937,26 +36308,26 @@ Otherwise, this resets the expression.
    -
    2329    def isin(
    -2330        self,
    -2331        *expressions: t.Any,
    -2332        query: t.Optional[ExpOrStr] = None,
    -2333        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
    -2334        copy: bool = True,
    -2335        **opts,
    -2336    ) -> In:
    -2337        return In(
    -2338            this=maybe_copy(self, copy),
    -2339            expressions=[convert(e, copy=copy) for e in expressions],
    -2340            query=maybe_parse(query, copy=copy, **opts) if query else None,
    -2341            unnest=Unnest(
    -2342                expressions=[
    -2343                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
    -2344                ]
    -2345            )
    -2346            if unnest
    -2347            else None,
    -2348        )
    +            
    2345    def isin(
    +2346        self,
    +2347        *expressions: t.Any,
    +2348        query: t.Optional[ExpOrStr] = None,
    +2349        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
    +2350        copy: bool = True,
    +2351        **opts,
    +2352    ) -> In:
    +2353        return In(
    +2354            this=maybe_copy(self, copy),
    +2355            expressions=[convert(e, copy=copy) for e in expressions],
    +2356            query=maybe_parse(query, copy=copy, **opts) if query else None,
    +2357            unnest=Unnest(
    +2358                expressions=[
    +2359                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
    +2360                ]
    +2361            )
    +2362            if unnest
    +2363            else None,
    +2364        )
     
    @@ -36054,94 +36425,94 @@ Otherwise, this resets the expression.
    -
    2351class Subqueryable(Unionable):
    -2352    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
    -2353        """
    -2354        Convert this expression to an aliased expression that can be used as a Subquery.
    -2355
    -2356        Example:
    -2357            >>> subquery = Select().select("x").from_("tbl").subquery()
    -2358            >>> Select().select("x").from_(subquery).sql()
    -2359            'SELECT x FROM (SELECT x FROM tbl)'
    -2360
    -2361        Args:
    -2362            alias (str | Identifier): an optional alias for the subquery
    -2363            copy (bool): if `False`, modify this expression instance in-place.
    -2364
    -2365        Returns:
    -2366            Alias: the subquery
    -2367        """
    -2368        instance = maybe_copy(self, copy)
    -2369        if not isinstance(alias, Expression):
    -2370            alias = TableAlias(this=to_identifier(alias)) if alias else None
    +            
    2367class Subqueryable(Unionable):
    +2368    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
    +2369        """
    +2370        Convert this expression to an aliased expression that can be used as a Subquery.
     2371
    -2372        return Subquery(this=instance, alias=alias)
    -2373
    -2374    def limit(
    -2375        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2376    ) -> Select:
    -2377        raise NotImplementedError
    -2378
    -2379    @property
    -2380    def ctes(self):
    -2381        with_ = self.args.get("with")
    -2382        if not with_:
    -2383            return []
    -2384        return with_.expressions
    -2385
    -2386    @property
    -2387    def selects(self) -> t.List[Expression]:
    -2388        raise NotImplementedError("Subqueryable objects must implement `selects`")
    +2372        Example:
    +2373            >>> subquery = Select().select("x").from_("tbl").subquery()
    +2374            >>> Select().select("x").from_(subquery).sql()
    +2375            'SELECT x FROM (SELECT x FROM tbl)'
    +2376
    +2377        Args:
    +2378            alias (str | Identifier): an optional alias for the subquery
    +2379            copy (bool): if `False`, modify this expression instance in-place.
    +2380
    +2381        Returns:
    +2382            Alias: the subquery
    +2383        """
    +2384        instance = maybe_copy(self, copy)
    +2385        if not isinstance(alias, Expression):
    +2386            alias = TableAlias(this=to_identifier(alias)) if alias else None
    +2387
    +2388        return Subquery(this=instance, alias=alias)
     2389
    -2390    @property
    -2391    def named_selects(self) -> t.List[str]:
    -2392        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
    -2393
    -2394    def select(
    -2395        self,
    -2396        *expressions: t.Optional[ExpOrStr],
    -2397        append: bool = True,
    -2398        dialect: DialectType = None,
    -2399        copy: bool = True,
    -2400        **opts,
    -2401    ) -> Subqueryable:
    -2402        raise NotImplementedError("Subqueryable objects must implement `select`")
    -2403
    -2404    def with_(
    -2405        self,
    -2406        alias: ExpOrStr,
    -2407        as_: ExpOrStr,
    -2408        recursive: t.Optional[bool] = None,
    -2409        append: bool = True,
    -2410        dialect: DialectType = None,
    -2411        copy: bool = True,
    -2412        **opts,
    -2413    ) -> Subqueryable:
    -2414        """
    -2415        Append to or set the common table expressions.
    -2416
    -2417        Example:
    -2418            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
    -2419            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
    -2420
    -2421        Args:
    -2422            alias: the SQL code string to parse as the table name.
    -2423                If an `Expression` instance is passed, this is used as-is.
    -2424            as_: the SQL code string to parse as the table expression.
    -2425                If an `Expression` instance is passed, it will be used as-is.
    -2426            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
    -2427            append: if `True`, add to any existing expressions.
    -2428                Otherwise, this resets the expressions.
    -2429            dialect: the dialect used to parse the input expression.
    -2430            copy: if `False`, modify this expression instance in-place.
    -2431            opts: other options to use to parse the input expressions.
    +2390    def limit(
    +2391        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2392    ) -> Select:
    +2393        raise NotImplementedError
    +2394
    +2395    @property
    +2396    def ctes(self):
    +2397        with_ = self.args.get("with")
    +2398        if not with_:
    +2399            return []
    +2400        return with_.expressions
    +2401
    +2402    @property
    +2403    def selects(self) -> t.List[Expression]:
    +2404        raise NotImplementedError("Subqueryable objects must implement `selects`")
    +2405
    +2406    @property
    +2407    def named_selects(self) -> t.List[str]:
    +2408        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
    +2409
    +2410    def select(
    +2411        self,
    +2412        *expressions: t.Optional[ExpOrStr],
    +2413        append: bool = True,
    +2414        dialect: DialectType = None,
    +2415        copy: bool = True,
    +2416        **opts,
    +2417    ) -> Subqueryable:
    +2418        raise NotImplementedError("Subqueryable objects must implement `select`")
    +2419
    +2420    def with_(
    +2421        self,
    +2422        alias: ExpOrStr,
    +2423        as_: ExpOrStr,
    +2424        recursive: t.Optional[bool] = None,
    +2425        append: bool = True,
    +2426        dialect: DialectType = None,
    +2427        copy: bool = True,
    +2428        **opts,
    +2429    ) -> Subqueryable:
    +2430        """
    +2431        Append to or set the common table expressions.
     2432
    -2433        Returns:
    -2434            The modified expression.
    -2435        """
    -2436        return _apply_cte_builder(
    -2437            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
    -2438        )
    +2433        Example:
    +2434            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
    +2435            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
    +2436
    +2437        Args:
    +2438            alias: the SQL code string to parse as the table name.
    +2439                If an `Expression` instance is passed, this is used as-is.
    +2440            as_: the SQL code string to parse as the table expression.
    +2441                If an `Expression` instance is passed, it will be used as-is.
    +2442            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
    +2443            append: if `True`, add to any existing expressions.
    +2444                Otherwise, this resets the expressions.
    +2445            dialect: the dialect used to parse the input expression.
    +2446            copy: if `False`, modify this expression instance in-place.
    +2447            opts: other options to use to parse the input expressions.
    +2448
    +2449        Returns:
    +2450            The modified expression.
    +2451        """
    +2452        return _apply_cte_builder(
    +2453            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
    +2454        )
     
    @@ -36158,27 +36529,27 @@ Otherwise, this resets the expression.
    -
    2352    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
    -2353        """
    -2354        Convert this expression to an aliased expression that can be used as a Subquery.
    -2355
    -2356        Example:
    -2357            >>> subquery = Select().select("x").from_("tbl").subquery()
    -2358            >>> Select().select("x").from_(subquery).sql()
    -2359            'SELECT x FROM (SELECT x FROM tbl)'
    -2360
    -2361        Args:
    -2362            alias (str | Identifier): an optional alias for the subquery
    -2363            copy (bool): if `False`, modify this expression instance in-place.
    -2364
    -2365        Returns:
    -2366            Alias: the subquery
    -2367        """
    -2368        instance = maybe_copy(self, copy)
    -2369        if not isinstance(alias, Expression):
    -2370            alias = TableAlias(this=to_identifier(alias)) if alias else None
    +            
    2368    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
    +2369        """
    +2370        Convert this expression to an aliased expression that can be used as a Subquery.
     2371
    -2372        return Subquery(this=instance, alias=alias)
    +2372        Example:
    +2373            >>> subquery = Select().select("x").from_("tbl").subquery()
    +2374            >>> Select().select("x").from_(subquery).sql()
    +2375            'SELECT x FROM (SELECT x FROM tbl)'
    +2376
    +2377        Args:
    +2378            alias (str | Identifier): an optional alias for the subquery
    +2379            copy (bool): if `False`, modify this expression instance in-place.
    +2380
    +2381        Returns:
    +2382            Alias: the subquery
    +2383        """
    +2384        instance = maybe_copy(self, copy)
    +2385        if not isinstance(alias, Expression):
    +2386            alias = TableAlias(this=to_identifier(alias)) if alias else None
    +2387
    +2388        return Subquery(this=instance, alias=alias)
     
    @@ -36222,10 +36593,10 @@ Otherwise, this resets the expression.
    -
    2374    def limit(
    -2375        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2376    ) -> Select:
    -2377        raise NotImplementedError
    +            
    2390    def limit(
    +2391        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2392    ) -> Select:
    +2393        raise NotImplementedError
     
    @@ -36276,15 +36647,15 @@ Otherwise, this resets the expression.
    -
    2394    def select(
    -2395        self,
    -2396        *expressions: t.Optional[ExpOrStr],
    -2397        append: bool = True,
    -2398        dialect: DialectType = None,
    -2399        copy: bool = True,
    -2400        **opts,
    -2401    ) -> Subqueryable:
    -2402        raise NotImplementedError("Subqueryable objects must implement `select`")
    +            
    2410    def select(
    +2411        self,
    +2412        *expressions: t.Optional[ExpOrStr],
    +2413        append: bool = True,
    +2414        dialect: DialectType = None,
    +2415        copy: bool = True,
    +2416        **opts,
    +2417    ) -> Subqueryable:
    +2418        raise NotImplementedError("Subqueryable objects must implement `select`")
     
    @@ -36302,41 +36673,41 @@ Otherwise, this resets the expression.
    -
    2404    def with_(
    -2405        self,
    -2406        alias: ExpOrStr,
    -2407        as_: ExpOrStr,
    -2408        recursive: t.Optional[bool] = None,
    -2409        append: bool = True,
    -2410        dialect: DialectType = None,
    -2411        copy: bool = True,
    -2412        **opts,
    -2413    ) -> Subqueryable:
    -2414        """
    -2415        Append to or set the common table expressions.
    -2416
    -2417        Example:
    -2418            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
    -2419            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
    -2420
    -2421        Args:
    -2422            alias: the SQL code string to parse as the table name.
    -2423                If an `Expression` instance is passed, this is used as-is.
    -2424            as_: the SQL code string to parse as the table expression.
    -2425                If an `Expression` instance is passed, it will be used as-is.
    -2426            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
    -2427            append: if `True`, add to any existing expressions.
    -2428                Otherwise, this resets the expressions.
    -2429            dialect: the dialect used to parse the input expression.
    -2430            copy: if `False`, modify this expression instance in-place.
    -2431            opts: other options to use to parse the input expressions.
    +            
    2420    def with_(
    +2421        self,
    +2422        alias: ExpOrStr,
    +2423        as_: ExpOrStr,
    +2424        recursive: t.Optional[bool] = None,
    +2425        append: bool = True,
    +2426        dialect: DialectType = None,
    +2427        copy: bool = True,
    +2428        **opts,
    +2429    ) -> Subqueryable:
    +2430        """
    +2431        Append to or set the common table expressions.
     2432
    -2433        Returns:
    -2434            The modified expression.
    -2435        """
    -2436        return _apply_cte_builder(
    -2437            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
    -2438        )
    +2433        Example:
    +2434            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
    +2435            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
    +2436
    +2437        Args:
    +2438            alias: the SQL code string to parse as the table name.
    +2439                If an `Expression` instance is passed, this is used as-is.
    +2440            as_: the SQL code string to parse as the table expression.
    +2441                If an `Expression` instance is passed, it will be used as-is.
    +2442            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
    +2443            append: if `True`, add to any existing expressions.
    +2444                Otherwise, this resets the expressions.
    +2445            dialect: the dialect used to parse the input expression.
    +2446            copy: if `False`, modify this expression instance in-place.
    +2447            opts: other options to use to parse the input expressions.
    +2448
    +2449        Returns:
    +2450            The modified expression.
    +2451        """
    +2452        return _apply_cte_builder(
    +2453            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
    +2454        )
     
    @@ -36488,8 +36859,8 @@ Otherwise, this resets the expressions.
    -
    2466class WithTableHint(Expression):
    -2467    arg_types = {"expressions": True}
    +            
    2482class WithTableHint(Expression):
    +2483    arg_types = {"expressions": True}
     
    @@ -36599,8 +36970,8 @@ Otherwise, this resets the expressions.
    -
    2471class IndexTableHint(Expression):
    -2472    arg_types = {"this": True, "expressions": False, "target": False}
    +            
    2487class IndexTableHint(Expression):
    +2488    arg_types = {"this": True, "expressions": False, "target": False}
     
    @@ -36710,59 +37081,60 @@ Otherwise, this resets the expressions.
    -
    2475class Table(Expression):
    -2476    arg_types = {
    -2477        "this": True,
    -2478        "alias": False,
    -2479        "db": False,
    -2480        "catalog": False,
    -2481        "laterals": False,
    -2482        "joins": False,
    -2483        "pivots": False,
    -2484        "hints": False,
    -2485        "system_time": False,
    -2486        "version": False,
    -2487        "format": False,
    -2488        "pattern": False,
    -2489        "index": False,
    -2490    }
    -2491
    -2492    @property
    -2493    def name(self) -> str:
    -2494        if isinstance(self.this, Func):
    -2495            return ""
    -2496        return self.this.name
    -2497
    -2498    @property
    -2499    def db(self) -> str:
    -2500        return self.text("db")
    -2501
    -2502    @property
    -2503    def catalog(self) -> str:
    -2504        return self.text("catalog")
    -2505
    -2506    @property
    -2507    def selects(self) -> t.List[Expression]:
    -2508        return []
    -2509
    -2510    @property
    -2511    def named_selects(self) -> t.List[str]:
    -2512        return []
    -2513
    -2514    @property
    -2515    def parts(self) -> t.List[Expression]:
    -2516        """Return the parts of a table in order catalog, db, table."""
    -2517        parts: t.List[Expression] = []
    +            
    2491class Table(Expression):
    +2492    arg_types = {
    +2493        "this": True,
    +2494        "alias": False,
    +2495        "db": False,
    +2496        "catalog": False,
    +2497        "laterals": False,
    +2498        "joins": False,
    +2499        "pivots": False,
    +2500        "hints": False,
    +2501        "system_time": False,
    +2502        "version": False,
    +2503        "format": False,
    +2504        "pattern": False,
    +2505        "index": False,
    +2506        "ordinality": False,
    +2507    }
    +2508
    +2509    @property
    +2510    def name(self) -> str:
    +2511        if isinstance(self.this, Func):
    +2512            return ""
    +2513        return self.this.name
    +2514
    +2515    @property
    +2516    def db(self) -> str:
    +2517        return self.text("db")
     2518
    -2519        for arg in ("catalog", "db", "this"):
    -2520            part = self.args.get(arg)
    -2521
    -2522            if isinstance(part, Dot):
    -2523                parts.extend(part.flatten())
    -2524            elif isinstance(part, Expression):
    -2525                parts.append(part)
    +2519    @property
    +2520    def catalog(self) -> str:
    +2521        return self.text("catalog")
    +2522
    +2523    @property
    +2524    def selects(self) -> t.List[Expression]:
    +2525        return []
     2526
    -2527        return parts
    +2527    @property
    +2528    def named_selects(self) -> t.List[str]:
    +2529        return []
    +2530
    +2531    @property
    +2532    def parts(self) -> t.List[Expression]:
    +2533        """Return the parts of a table in order catalog, db, table."""
    +2534        parts: t.List[Expression] = []
    +2535
    +2536        for arg in ("catalog", "db", "this"):
    +2537            part = self.args.get(arg)
    +2538
    +2539            if isinstance(part, Dot):
    +2540                parts.extend(part.flatten())
    +2541            elif isinstance(part, Expression):
    +2542                parts.append(part)
    +2543
    +2544        return parts
     
    @@ -36772,7 +37144,7 @@ Otherwise, this resets the expressions.
    arg_types = - {'this': True, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'index': False} + {'this': True, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'index': False, 'ordinality': False}
    @@ -36940,97 +37312,97 @@ Otherwise, this resets the expressions.
    -
    2530class Union(Subqueryable):
    -2531    arg_types = {
    -2532        "with": False,
    -2533        "this": True,
    -2534        "expression": True,
    -2535        "distinct": False,
    -2536        "by_name": False,
    -2537        **QUERY_MODIFIERS,
    -2538    }
    -2539
    -2540    def limit(
    -2541        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2542    ) -> Select:
    -2543        """
    -2544        Set the LIMIT expression.
    -2545
    -2546        Example:
    -2547            >>> select("1").union(select("1")).limit(1).sql()
    -2548            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
    -2549
    -2550        Args:
    -2551            expression: the SQL code string to parse.
    -2552                This can also be an integer.
    -2553                If a `Limit` instance is passed, this is used as-is.
    -2554                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    -2555            dialect: the dialect used to parse the input expression.
    -2556            copy: if `False`, modify this expression instance in-place.
    -2557            opts: other options to use to parse the input expressions.
    -2558
    -2559        Returns:
    -2560            The limited subqueryable.
    -2561        """
    -2562        return (
    -2563            select("*")
    -2564            .from_(self.subquery(alias="_l_0", copy=copy))
    -2565            .limit(expression, dialect=dialect, copy=False, **opts)
    -2566        )
    -2567
    -2568    def select(
    -2569        self,
    -2570        *expressions: t.Optional[ExpOrStr],
    -2571        append: bool = True,
    -2572        dialect: DialectType = None,
    -2573        copy: bool = True,
    -2574        **opts,
    -2575    ) -> Union:
    -2576        """Append to or set the SELECT of the union recursively.
    -2577
    -2578        Example:
    -2579            >>> from sqlglot import parse_one
    -2580            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
    -2581            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
    -2582
    -2583        Args:
    -2584            *expressions: the SQL code strings to parse.
    -2585                If an `Expression` instance is passed, it will be used as-is.
    -2586            append: if `True`, add to any existing expressions.
    -2587                Otherwise, this resets the expressions.
    -2588            dialect: the dialect used to parse the input expressions.
    -2589            copy: if `False`, modify this expression instance in-place.
    -2590            opts: other options to use to parse the input expressions.
    -2591
    -2592        Returns:
    -2593            Union: the modified expression.
    -2594        """
    -2595        this = self.copy() if copy else self
    -2596        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
    -2597        this.expression.unnest().select(
    -2598            *expressions, append=append, dialect=dialect, copy=False, **opts
    -2599        )
    -2600        return this
    -2601
    -2602    @property
    -2603    def named_selects(self) -> t.List[str]:
    -2604        return self.this.unnest().named_selects
    -2605
    -2606    @property
    -2607    def is_star(self) -> bool:
    -2608        return self.this.is_star or self.expression.is_star
    -2609
    -2610    @property
    -2611    def selects(self) -> t.List[Expression]:
    -2612        return self.this.unnest().selects
    -2613
    -2614    @property
    -2615    def left(self) -> Expression:
    -2616        return self.this
    -2617
    -2618    @property
    -2619    def right(self) -> Expression:
    -2620        return self.expression
    +            
    2547class Union(Subqueryable):
    +2548    arg_types = {
    +2549        "with": False,
    +2550        "this": True,
    +2551        "expression": True,
    +2552        "distinct": False,
    +2553        "by_name": False,
    +2554        **QUERY_MODIFIERS,
    +2555    }
    +2556
    +2557    def limit(
    +2558        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2559    ) -> Select:
    +2560        """
    +2561        Set the LIMIT expression.
    +2562
    +2563        Example:
    +2564            >>> select("1").union(select("1")).limit(1).sql()
    +2565            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
    +2566
    +2567        Args:
    +2568            expression: the SQL code string to parse.
    +2569                This can also be an integer.
    +2570                If a `Limit` instance is passed, this is used as-is.
    +2571                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    +2572            dialect: the dialect used to parse the input expression.
    +2573            copy: if `False`, modify this expression instance in-place.
    +2574            opts: other options to use to parse the input expressions.
    +2575
    +2576        Returns:
    +2577            The limited subqueryable.
    +2578        """
    +2579        return (
    +2580            select("*")
    +2581            .from_(self.subquery(alias="_l_0", copy=copy))
    +2582            .limit(expression, dialect=dialect, copy=False, **opts)
    +2583        )
    +2584
    +2585    def select(
    +2586        self,
    +2587        *expressions: t.Optional[ExpOrStr],
    +2588        append: bool = True,
    +2589        dialect: DialectType = None,
    +2590        copy: bool = True,
    +2591        **opts,
    +2592    ) -> Union:
    +2593        """Append to or set the SELECT of the union recursively.
    +2594
    +2595        Example:
    +2596            >>> from sqlglot import parse_one
    +2597            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
    +2598            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
    +2599
    +2600        Args:
    +2601            *expressions: the SQL code strings to parse.
    +2602                If an `Expression` instance is passed, it will be used as-is.
    +2603            append: if `True`, add to any existing expressions.
    +2604                Otherwise, this resets the expressions.
    +2605            dialect: the dialect used to parse the input expressions.
    +2606            copy: if `False`, modify this expression instance in-place.
    +2607            opts: other options to use to parse the input expressions.
    +2608
    +2609        Returns:
    +2610            Union: the modified expression.
    +2611        """
    +2612        this = self.copy() if copy else self
    +2613        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
    +2614        this.expression.unnest().select(
    +2615            *expressions, append=append, dialect=dialect, copy=False, **opts
    +2616        )
    +2617        return this
    +2618
    +2619    @property
    +2620    def named_selects(self) -> t.List[str]:
    +2621        return self.this.unnest().named_selects
    +2622
    +2623    @property
    +2624    def is_star(self) -> bool:
    +2625        return self.this.is_star or self.expression.is_star
    +2626
    +2627    @property
    +2628    def selects(self) -> t.List[Expression]:
    +2629        return self.this.unnest().selects
    +2630
    +2631    @property
    +2632    def left(self) -> Expression:
    +2633        return self.this
    +2634
    +2635    @property
    +2636    def right(self) -> Expression:
    +2637        return self.expression
     
    @@ -37060,33 +37432,33 @@ Otherwise, this resets the expressions.
    -
    2540    def limit(
    -2541        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2542    ) -> Select:
    -2543        """
    -2544        Set the LIMIT expression.
    -2545
    -2546        Example:
    -2547            >>> select("1").union(select("1")).limit(1).sql()
    -2548            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
    -2549
    -2550        Args:
    -2551            expression: the SQL code string to parse.
    -2552                This can also be an integer.
    -2553                If a `Limit` instance is passed, this is used as-is.
    -2554                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    -2555            dialect: the dialect used to parse the input expression.
    -2556            copy: if `False`, modify this expression instance in-place.
    -2557            opts: other options to use to parse the input expressions.
    -2558
    -2559        Returns:
    -2560            The limited subqueryable.
    -2561        """
    -2562        return (
    -2563            select("*")
    -2564            .from_(self.subquery(alias="_l_0", copy=copy))
    -2565            .limit(expression, dialect=dialect, copy=False, **opts)
    -2566        )
    +            
    2557    def limit(
    +2558        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2559    ) -> Select:
    +2560        """
    +2561        Set the LIMIT expression.
    +2562
    +2563        Example:
    +2564            >>> select("1").union(select("1")).limit(1).sql()
    +2565            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
    +2566
    +2567        Args:
    +2568            expression: the SQL code string to parse.
    +2569                This can also be an integer.
    +2570                If a `Limit` instance is passed, this is used as-is.
    +2571                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    +2572            dialect: the dialect used to parse the input expression.
    +2573            copy: if `False`, modify this expression instance in-place.
    +2574            opts: other options to use to parse the input expressions.
    +2575
    +2576        Returns:
    +2577            The limited subqueryable.
    +2578        """
    +2579        return (
    +2580            select("*")
    +2581            .from_(self.subquery(alias="_l_0", copy=copy))
    +2582            .limit(expression, dialect=dialect, copy=False, **opts)
    +2583        )
     
    @@ -37134,39 +37506,39 @@ If another Expression instance is passed,
    -
    2568    def select(
    -2569        self,
    -2570        *expressions: t.Optional[ExpOrStr],
    -2571        append: bool = True,
    -2572        dialect: DialectType = None,
    -2573        copy: bool = True,
    -2574        **opts,
    -2575    ) -> Union:
    -2576        """Append to or set the SELECT of the union recursively.
    -2577
    -2578        Example:
    -2579            >>> from sqlglot import parse_one
    -2580            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
    -2581            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
    -2582
    -2583        Args:
    -2584            *expressions: the SQL code strings to parse.
    -2585                If an `Expression` instance is passed, it will be used as-is.
    -2586            append: if `True`, add to any existing expressions.
    -2587                Otherwise, this resets the expressions.
    -2588            dialect: the dialect used to parse the input expressions.
    -2589            copy: if `False`, modify this expression instance in-place.
    -2590            opts: other options to use to parse the input expressions.
    -2591
    -2592        Returns:
    -2593            Union: the modified expression.
    -2594        """
    -2595        this = self.copy() if copy else self
    -2596        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
    -2597        this.expression.unnest().select(
    -2598            *expressions, append=append, dialect=dialect, copy=False, **opts
    -2599        )
    -2600        return this
    +            
    2585    def select(
    +2586        self,
    +2587        *expressions: t.Optional[ExpOrStr],
    +2588        append: bool = True,
    +2589        dialect: DialectType = None,
    +2590        copy: bool = True,
    +2591        **opts,
    +2592    ) -> Union:
    +2593        """Append to or set the SELECT of the union recursively.
    +2594
    +2595        Example:
    +2596            >>> from sqlglot import parse_one
    +2597            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
    +2598            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
    +2599
    +2600        Args:
    +2601            *expressions: the SQL code strings to parse.
    +2602                If an `Expression` instance is passed, it will be used as-is.
    +2603            append: if `True`, add to any existing expressions.
    +2604                Otherwise, this resets the expressions.
    +2605            dialect: the dialect used to parse the input expressions.
    +2606            copy: if `False`, modify this expression instance in-place.
    +2607            opts: other options to use to parse the input expressions.
    +2608
    +2609        Returns:
    +2610            Union: the modified expression.
    +2611        """
    +2612        this = self.copy() if copy else self
    +2613        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
    +2614        this.expression.unnest().select(
    +2615            *expressions, append=append, dialect=dialect, copy=False, **opts
    +2616        )
    +2617        return this
     
    @@ -37364,8 +37736,8 @@ Otherwise, this resets the expressions.
    -
    2623class Except(Union):
    -2624    pass
    +            
    2640class Except(Union):
    +2641    pass
     
    @@ -37485,8 +37857,8 @@ Otherwise, this resets the expressions.
    -
    2627class Intersect(Union):
    -2628    pass
    +            
    2644class Intersect(Union):
    +2645    pass
     
    @@ -37606,12 +37978,12 @@ Otherwise, this resets the expressions.
    -
    2631class Unnest(UDTF):
    -2632    arg_types = {
    -2633        "expressions": True,
    -2634        "alias": False,
    -2635        "offset": False,
    -2636    }
    +            
    2648class Unnest(UDTF):
    +2649    arg_types = {
    +2650        "expressions": True,
    +2651        "alias": False,
    +2652        "offset": False,
    +2653    }
     
    @@ -37735,17 +38107,17 @@ Otherwise, this resets the expressions.
    -
    2639class Update(Expression):
    -2640    arg_types = {
    -2641        "with": False,
    -2642        "this": False,
    -2643        "expressions": True,
    -2644        "from": False,
    -2645        "where": False,
    -2646        "returning": False,
    -2647        "order": False,
    -2648        "limit": False,
    -2649    }
    +            
    2656class Update(Expression):
    +2657    arg_types = {
    +2658        "with": False,
    +2659        "this": False,
    +2660        "expressions": True,
    +2661        "from": False,
    +2662        "where": False,
    +2663        "returning": False,
    +2664        "order": False,
    +2665        "limit": False,
    +2666    }
     
    @@ -37856,12 +38228,8 @@ Otherwise, this resets the expressions.
    -
    2652class Values(UDTF):
    -2653    arg_types = {
    -2654        "expressions": True,
    -2655        "ordinality": False,
    -2656        "alias": False,
    -2657    }
    +            
    2669class Values(UDTF):
    +2670    arg_types = {"expressions": True, "alias": False}
     
    @@ -37870,7 +38238,7 @@ Otherwise, this resets the expressions.
    arg_types = -{'expressions': True, 'ordinality': False, 'alias': False} +{'expressions': True, 'alias': False}
    @@ -37985,8 +38353,8 @@ Otherwise, this resets the expressions.
    -
    2660class Var(Expression):
    -2661    pass
    +            
    2673class Var(Expression):
    +2674    pass
     
    @@ -38085,18 +38453,18 @@ Otherwise, this resets the expressions.
    -
    2664class Version(Expression):
    -2665    """
    -2666    Time travel, iceberg, bigquery etc
    -2667    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
    -2668    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
    -2669    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
    -2670    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
    -2671    this is either TIMESTAMP or VERSION
    -2672    kind is ("AS OF", "BETWEEN")
    -2673    """
    -2674
    -2675    arg_types = {"this": True, "kind": True, "expression": False}
    +            
    2677class Version(Expression):
    +2678    """
    +2679    Time travel, iceberg, bigquery etc
    +2680    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
    +2681    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
    +2682    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
    +2683    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
    +2684    this is either TIMESTAMP or VERSION
    +2685    kind is ("AS OF", "BETWEEN")
    +2686    """
    +2687
    +2688    arg_types = {"this": True, "kind": True, "expression": False}
     
    @@ -38214,8 +38582,8 @@ kind is ("AS OF", "BETWEEN")

    -
    2678class Schema(Expression):
    -2679    arg_types = {"this": False, "expressions": False}
    +            
    2691class Schema(Expression):
    +2692    arg_types = {"this": False, "expressions": False}
     
    @@ -38325,8 +38693,8 @@ kind is ("AS OF", "BETWEEN")

    -
    2684class Lock(Expression):
    -2685    arg_types = {"update": True, "expressions": False, "wait": False}
    +            
    2697class Lock(Expression):
    +2698    arg_types = {"update": True, "expressions": False, "wait": False}
     
    @@ -38436,697 +38804,697 @@ kind is ("AS OF", "BETWEEN")

    -
    2688class Select(Subqueryable):
    -2689    arg_types = {
    -2690        "with": False,
    -2691        "kind": False,
    -2692        "expressions": False,
    -2693        "hint": False,
    -2694        "distinct": False,
    -2695        "into": False,
    -2696        "from": False,
    -2697        **QUERY_MODIFIERS,
    -2698    }
    -2699
    -2700    def from_(
    -2701        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    -2702    ) -> Select:
    -2703        """
    -2704        Set the FROM expression.
    -2705
    -2706        Example:
    -2707            >>> Select().from_("tbl").select("x").sql()
    -2708            'SELECT x FROM tbl'
    -2709
    -2710        Args:
    -2711            expression : the SQL code strings to parse.
    -2712                If a `From` instance is passed, this is used as-is.
    -2713                If another `Expression` instance is passed, it will be wrapped in a `From`.
    -2714            dialect: the dialect used to parse the input expression.
    -2715            copy: if `False`, modify this expression instance in-place.
    -2716            opts: other options to use to parse the input expressions.
    -2717
    -2718        Returns:
    -2719            The modified Select expression.
    -2720        """
    -2721        return _apply_builder(
    -2722            expression=expression,
    -2723            instance=self,
    -2724            arg="from",
    -2725            into=From,
    -2726            prefix="FROM",
    -2727            dialect=dialect,
    -2728            copy=copy,
    -2729            **opts,
    -2730        )
    -2731
    -2732    def group_by(
    -2733        self,
    -2734        *expressions: t.Optional[ExpOrStr],
    -2735        append: bool = True,
    -2736        dialect: DialectType = None,
    -2737        copy: bool = True,
    -2738        **opts,
    -2739    ) -> Select:
    -2740        """
    -2741        Set the GROUP BY expression.
    -2742
    -2743        Example:
    -2744            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
    -2745            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
    -2746
    -2747        Args:
    -2748            *expressions: the SQL code strings to parse.
    -2749                If a `Group` instance is passed, this is used as-is.
    -2750                If another `Expression` instance is passed, it will be wrapped in a `Group`.
    -2751                If nothing is passed in then a group by is not applied to the expression
    -2752            append: if `True`, add to any existing expressions.
    -2753                Otherwise, this flattens all the `Group` expression into a single expression.
    -2754            dialect: the dialect used to parse the input expression.
    -2755            copy: if `False`, modify this expression instance in-place.
    -2756            opts: other options to use to parse the input expressions.
    -2757
    -2758        Returns:
    -2759            The modified Select expression.
    -2760        """
    -2761        if not expressions:
    -2762            return self if not copy else self.copy()
    -2763
    -2764        return _apply_child_list_builder(
    -2765            *expressions,
    -2766            instance=self,
    -2767            arg="group",
    -2768            append=append,
    -2769            copy=copy,
    -2770            prefix="GROUP BY",
    -2771            into=Group,
    -2772            dialect=dialect,
    -2773            **opts,
    -2774        )
    -2775
    -2776    def order_by(
    -2777        self,
    -2778        *expressions: t.Optional[ExpOrStr],
    -2779        append: bool = True,
    -2780        dialect: DialectType = None,
    -2781        copy: bool = True,
    -2782        **opts,
    -2783    ) -> Select:
    -2784        """
    -2785        Set the ORDER BY expression.
    -2786
    -2787        Example:
    -2788            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
    -2789            'SELECT x FROM tbl ORDER BY x DESC'
    -2790
    -2791        Args:
    -2792            *expressions: the SQL code strings to parse.
    -2793                If a `Group` instance is passed, this is used as-is.
    -2794                If another `Expression` instance is passed, it will be wrapped in a `Order`.
    -2795            append: if `True`, add to any existing expressions.
    -2796                Otherwise, this flattens all the `Order` expression into a single expression.
    -2797            dialect: the dialect used to parse the input expression.
    -2798            copy: if `False`, modify this expression instance in-place.
    -2799            opts: other options to use to parse the input expressions.
    -2800
    -2801        Returns:
    -2802            The modified Select expression.
    -2803        """
    -2804        return _apply_child_list_builder(
    -2805            *expressions,
    -2806            instance=self,
    -2807            arg="order",
    -2808            append=append,
    -2809            copy=copy,
    -2810            prefix="ORDER BY",
    -2811            into=Order,
    -2812            dialect=dialect,
    -2813            **opts,
    -2814        )
    -2815
    -2816    def sort_by(
    -2817        self,
    -2818        *expressions: t.Optional[ExpOrStr],
    -2819        append: bool = True,
    -2820        dialect: DialectType = None,
    -2821        copy: bool = True,
    -2822        **opts,
    -2823    ) -> Select:
    -2824        """
    -2825        Set the SORT BY expression.
    -2826
    -2827        Example:
    -2828            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
    -2829            'SELECT x FROM tbl SORT BY x DESC'
    -2830
    -2831        Args:
    -2832            *expressions: the SQL code strings to parse.
    -2833                If a `Group` instance is passed, this is used as-is.
    -2834                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
    -2835            append: if `True`, add to any existing expressions.
    -2836                Otherwise, this flattens all the `Order` expression into a single expression.
    -2837            dialect: the dialect used to parse the input expression.
    -2838            copy: if `False`, modify this expression instance in-place.
    -2839            opts: other options to use to parse the input expressions.
    -2840
    -2841        Returns:
    -2842            The modified Select expression.
    -2843        """
    -2844        return _apply_child_list_builder(
    -2845            *expressions,
    -2846            instance=self,
    -2847            arg="sort",
    -2848            append=append,
    -2849            copy=copy,
    -2850            prefix="SORT BY",
    -2851            into=Sort,
    -2852            dialect=dialect,
    -2853            **opts,
    -2854        )
    -2855
    -2856    def cluster_by(
    -2857        self,
    -2858        *expressions: t.Optional[ExpOrStr],
    -2859        append: bool = True,
    -2860        dialect: DialectType = None,
    -2861        copy: bool = True,
    -2862        **opts,
    -2863    ) -> Select:
    -2864        """
    -2865        Set the CLUSTER BY expression.
    -2866
    -2867        Example:
    -2868            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
    -2869            'SELECT x FROM tbl CLUSTER BY x DESC'
    -2870
    -2871        Args:
    -2872            *expressions: the SQL code strings to parse.
    -2873                If a `Group` instance is passed, this is used as-is.
    -2874                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
    -2875            append: if `True`, add to any existing expressions.
    -2876                Otherwise, this flattens all the `Order` expression into a single expression.
    -2877            dialect: the dialect used to parse the input expression.
    -2878            copy: if `False`, modify this expression instance in-place.
    -2879            opts: other options to use to parse the input expressions.
    -2880
    -2881        Returns:
    -2882            The modified Select expression.
    -2883        """
    -2884        return _apply_child_list_builder(
    -2885            *expressions,
    -2886            instance=self,
    -2887            arg="cluster",
    -2888            append=append,
    -2889            copy=copy,
    -2890            prefix="CLUSTER BY",
    -2891            into=Cluster,
    -2892            dialect=dialect,
    -2893            **opts,
    -2894        )
    -2895
    -2896    def limit(
    -2897        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2898    ) -> Select:
    -2899        """
    -2900        Set the LIMIT expression.
    -2901
    -2902        Example:
    -2903            >>> Select().from_("tbl").select("x").limit(10).sql()
    -2904            'SELECT x FROM tbl LIMIT 10'
    -2905
    -2906        Args:
    -2907            expression: the SQL code string to parse.
    -2908                This can also be an integer.
    -2909                If a `Limit` instance is passed, this is used as-is.
    -2910                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    -2911            dialect: the dialect used to parse the input expression.
    -2912            copy: if `False`, modify this expression instance in-place.
    -2913            opts: other options to use to parse the input expressions.
    +            
    2701class Select(Subqueryable):
    +2702    arg_types = {
    +2703        "with": False,
    +2704        "kind": False,
    +2705        "expressions": False,
    +2706        "hint": False,
    +2707        "distinct": False,
    +2708        "into": False,
    +2709        "from": False,
    +2710        **QUERY_MODIFIERS,
    +2711    }
    +2712
    +2713    def from_(
    +2714        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    +2715    ) -> Select:
    +2716        """
    +2717        Set the FROM expression.
    +2718
    +2719        Example:
    +2720            >>> Select().from_("tbl").select("x").sql()
    +2721            'SELECT x FROM tbl'
    +2722
    +2723        Args:
    +2724            expression : the SQL code strings to parse.
    +2725                If a `From` instance is passed, this is used as-is.
    +2726                If another `Expression` instance is passed, it will be wrapped in a `From`.
    +2727            dialect: the dialect used to parse the input expression.
    +2728            copy: if `False`, modify this expression instance in-place.
    +2729            opts: other options to use to parse the input expressions.
    +2730
    +2731        Returns:
    +2732            The modified Select expression.
    +2733        """
    +2734        return _apply_builder(
    +2735            expression=expression,
    +2736            instance=self,
    +2737            arg="from",
    +2738            into=From,
    +2739            prefix="FROM",
    +2740            dialect=dialect,
    +2741            copy=copy,
    +2742            **opts,
    +2743        )
    +2744
    +2745    def group_by(
    +2746        self,
    +2747        *expressions: t.Optional[ExpOrStr],
    +2748        append: bool = True,
    +2749        dialect: DialectType = None,
    +2750        copy: bool = True,
    +2751        **opts,
    +2752    ) -> Select:
    +2753        """
    +2754        Set the GROUP BY expression.
    +2755
    +2756        Example:
    +2757            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
    +2758            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
    +2759
    +2760        Args:
    +2761            *expressions: the SQL code strings to parse.
    +2762                If a `Group` instance is passed, this is used as-is.
    +2763                If another `Expression` instance is passed, it will be wrapped in a `Group`.
    +2764                If nothing is passed in then a group by is not applied to the expression
    +2765            append: if `True`, add to any existing expressions.
    +2766                Otherwise, this flattens all the `Group` expression into a single expression.
    +2767            dialect: the dialect used to parse the input expression.
    +2768            copy: if `False`, modify this expression instance in-place.
    +2769            opts: other options to use to parse the input expressions.
    +2770
    +2771        Returns:
    +2772            The modified Select expression.
    +2773        """
    +2774        if not expressions:
    +2775            return self if not copy else self.copy()
    +2776
    +2777        return _apply_child_list_builder(
    +2778            *expressions,
    +2779            instance=self,
    +2780            arg="group",
    +2781            append=append,
    +2782            copy=copy,
    +2783            prefix="GROUP BY",
    +2784            into=Group,
    +2785            dialect=dialect,
    +2786            **opts,
    +2787        )
    +2788
    +2789    def order_by(
    +2790        self,
    +2791        *expressions: t.Optional[ExpOrStr],
    +2792        append: bool = True,
    +2793        dialect: DialectType = None,
    +2794        copy: bool = True,
    +2795        **opts,
    +2796    ) -> Select:
    +2797        """
    +2798        Set the ORDER BY expression.
    +2799
    +2800        Example:
    +2801            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
    +2802            'SELECT x FROM tbl ORDER BY x DESC'
    +2803
    +2804        Args:
    +2805            *expressions: the SQL code strings to parse.
    +2806                If a `Group` instance is passed, this is used as-is.
    +2807                If another `Expression` instance is passed, it will be wrapped in a `Order`.
    +2808            append: if `True`, add to any existing expressions.
    +2809                Otherwise, this flattens all the `Order` expression into a single expression.
    +2810            dialect: the dialect used to parse the input expression.
    +2811            copy: if `False`, modify this expression instance in-place.
    +2812            opts: other options to use to parse the input expressions.
    +2813
    +2814        Returns:
    +2815            The modified Select expression.
    +2816        """
    +2817        return _apply_child_list_builder(
    +2818            *expressions,
    +2819            instance=self,
    +2820            arg="order",
    +2821            append=append,
    +2822            copy=copy,
    +2823            prefix="ORDER BY",
    +2824            into=Order,
    +2825            dialect=dialect,
    +2826            **opts,
    +2827        )
    +2828
    +2829    def sort_by(
    +2830        self,
    +2831        *expressions: t.Optional[ExpOrStr],
    +2832        append: bool = True,
    +2833        dialect: DialectType = None,
    +2834        copy: bool = True,
    +2835        **opts,
    +2836    ) -> Select:
    +2837        """
    +2838        Set the SORT BY expression.
    +2839
    +2840        Example:
    +2841            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
    +2842            'SELECT x FROM tbl SORT BY x DESC'
    +2843
    +2844        Args:
    +2845            *expressions: the SQL code strings to parse.
    +2846                If a `Group` instance is passed, this is used as-is.
    +2847                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
    +2848            append: if `True`, add to any existing expressions.
    +2849                Otherwise, this flattens all the `Order` expression into a single expression.
    +2850            dialect: the dialect used to parse the input expression.
    +2851            copy: if `False`, modify this expression instance in-place.
    +2852            opts: other options to use to parse the input expressions.
    +2853
    +2854        Returns:
    +2855            The modified Select expression.
    +2856        """
    +2857        return _apply_child_list_builder(
    +2858            *expressions,
    +2859            instance=self,
    +2860            arg="sort",
    +2861            append=append,
    +2862            copy=copy,
    +2863            prefix="SORT BY",
    +2864            into=Sort,
    +2865            dialect=dialect,
    +2866            **opts,
    +2867        )
    +2868
    +2869    def cluster_by(
    +2870        self,
    +2871        *expressions: t.Optional[ExpOrStr],
    +2872        append: bool = True,
    +2873        dialect: DialectType = None,
    +2874        copy: bool = True,
    +2875        **opts,
    +2876    ) -> Select:
    +2877        """
    +2878        Set the CLUSTER BY expression.
    +2879
    +2880        Example:
    +2881            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
    +2882            'SELECT x FROM tbl CLUSTER BY x DESC'
    +2883
    +2884        Args:
    +2885            *expressions: the SQL code strings to parse.
    +2886                If a `Group` instance is passed, this is used as-is.
    +2887                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
    +2888            append: if `True`, add to any existing expressions.
    +2889                Otherwise, this flattens all the `Order` expression into a single expression.
    +2890            dialect: the dialect used to parse the input expression.
    +2891            copy: if `False`, modify this expression instance in-place.
    +2892            opts: other options to use to parse the input expressions.
    +2893
    +2894        Returns:
    +2895            The modified Select expression.
    +2896        """
    +2897        return _apply_child_list_builder(
    +2898            *expressions,
    +2899            instance=self,
    +2900            arg="cluster",
    +2901            append=append,
    +2902            copy=copy,
    +2903            prefix="CLUSTER BY",
    +2904            into=Cluster,
    +2905            dialect=dialect,
    +2906            **opts,
    +2907        )
    +2908
    +2909    def limit(
    +2910        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2911    ) -> Select:
    +2912        """
    +2913        Set the LIMIT expression.
     2914
    -2915        Returns:
    -2916            Select: the modified expression.
    -2917        """
    -2918        return _apply_builder(
    -2919            expression=expression,
    -2920            instance=self,
    -2921            arg="limit",
    -2922            into=Limit,
    -2923            prefix="LIMIT",
    -2924            dialect=dialect,
    -2925            copy=copy,
    -2926            into_arg="expression",
    -2927            **opts,
    -2928        )
    -2929
    -2930    def offset(
    -2931        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2932    ) -> Select:
    -2933        """
    -2934        Set the OFFSET expression.
    -2935
    -2936        Example:
    -2937            >>> Select().from_("tbl").select("x").offset(10).sql()
    -2938            'SELECT x FROM tbl OFFSET 10'
    -2939
    -2940        Args:
    -2941            expression: the SQL code string to parse.
    -2942                This can also be an integer.
    -2943                If a `Offset` instance is passed, this is used as-is.
    -2944                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
    -2945            dialect: the dialect used to parse the input expression.
    -2946            copy: if `False`, modify this expression instance in-place.
    -2947            opts: other options to use to parse the input expressions.
    +2915        Example:
    +2916            >>> Select().from_("tbl").select("x").limit(10).sql()
    +2917            'SELECT x FROM tbl LIMIT 10'
    +2918
    +2919        Args:
    +2920            expression: the SQL code string to parse.
    +2921                This can also be an integer.
    +2922                If a `Limit` instance is passed, this is used as-is.
    +2923                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    +2924            dialect: the dialect used to parse the input expression.
    +2925            copy: if `False`, modify this expression instance in-place.
    +2926            opts: other options to use to parse the input expressions.
    +2927
    +2928        Returns:
    +2929            Select: the modified expression.
    +2930        """
    +2931        return _apply_builder(
    +2932            expression=expression,
    +2933            instance=self,
    +2934            arg="limit",
    +2935            into=Limit,
    +2936            prefix="LIMIT",
    +2937            dialect=dialect,
    +2938            copy=copy,
    +2939            into_arg="expression",
    +2940            **opts,
    +2941        )
    +2942
    +2943    def offset(
    +2944        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2945    ) -> Select:
    +2946        """
    +2947        Set the OFFSET expression.
     2948
    -2949        Returns:
    -2950            The modified Select expression.
    -2951        """
    -2952        return _apply_builder(
    -2953            expression=expression,
    -2954            instance=self,
    -2955            arg="offset",
    -2956            into=Offset,
    -2957            prefix="OFFSET",
    -2958            dialect=dialect,
    -2959            copy=copy,
    -2960            into_arg="expression",
    -2961            **opts,
    -2962        )
    -2963
    -2964    def select(
    -2965        self,
    -2966        *expressions: t.Optional[ExpOrStr],
    -2967        append: bool = True,
    -2968        dialect: DialectType = None,
    -2969        copy: bool = True,
    -2970        **opts,
    -2971    ) -> Select:
    -2972        """
    -2973        Append to or set the SELECT expressions.
    -2974
    -2975        Example:
    -2976            >>> Select().select("x", "y").sql()
    -2977            'SELECT x, y'
    -2978
    -2979        Args:
    -2980            *expressions: the SQL code strings to parse.
    -2981                If an `Expression` instance is passed, it will be used as-is.
    -2982            append: if `True`, add to any existing expressions.
    -2983                Otherwise, this resets the expressions.
    -2984            dialect: the dialect used to parse the input expressions.
    -2985            copy: if `False`, modify this expression instance in-place.
    -2986            opts: other options to use to parse the input expressions.
    +2949        Example:
    +2950            >>> Select().from_("tbl").select("x").offset(10).sql()
    +2951            'SELECT x FROM tbl OFFSET 10'
    +2952
    +2953        Args:
    +2954            expression: the SQL code string to parse.
    +2955                This can also be an integer.
    +2956                If a `Offset` instance is passed, this is used as-is.
    +2957                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
    +2958            dialect: the dialect used to parse the input expression.
    +2959            copy: if `False`, modify this expression instance in-place.
    +2960            opts: other options to use to parse the input expressions.
    +2961
    +2962        Returns:
    +2963            The modified Select expression.
    +2964        """
    +2965        return _apply_builder(
    +2966            expression=expression,
    +2967            instance=self,
    +2968            arg="offset",
    +2969            into=Offset,
    +2970            prefix="OFFSET",
    +2971            dialect=dialect,
    +2972            copy=copy,
    +2973            into_arg="expression",
    +2974            **opts,
    +2975        )
    +2976
    +2977    def select(
    +2978        self,
    +2979        *expressions: t.Optional[ExpOrStr],
    +2980        append: bool = True,
    +2981        dialect: DialectType = None,
    +2982        copy: bool = True,
    +2983        **opts,
    +2984    ) -> Select:
    +2985        """
    +2986        Append to or set the SELECT expressions.
     2987
    -2988        Returns:
    -2989            The modified Select expression.
    -2990        """
    -2991        return _apply_list_builder(
    -2992            *expressions,
    -2993            instance=self,
    -2994            arg="expressions",
    -2995            append=append,
    -2996            dialect=dialect,
    -2997            copy=copy,
    -2998            **opts,
    -2999        )
    +2988        Example:
    +2989            >>> Select().select("x", "y").sql()
    +2990            'SELECT x, y'
    +2991
    +2992        Args:
    +2993            *expressions: the SQL code strings to parse.
    +2994                If an `Expression` instance is passed, it will be used as-is.
    +2995            append: if `True`, add to any existing expressions.
    +2996                Otherwise, this resets the expressions.
    +2997            dialect: the dialect used to parse the input expressions.
    +2998            copy: if `False`, modify this expression instance in-place.
    +2999            opts: other options to use to parse the input expressions.
     3000
    -3001    def lateral(
    -3002        self,
    -3003        *expressions: t.Optional[ExpOrStr],
    -3004        append: bool = True,
    -3005        dialect: DialectType = None,
    -3006        copy: bool = True,
    -3007        **opts,
    -3008    ) -> Select:
    -3009        """
    -3010        Append to or set the LATERAL expressions.
    -3011
    -3012        Example:
    -3013            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
    -3014            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
    -3015
    -3016        Args:
    -3017            *expressions: the SQL code strings to parse.
    -3018                If an `Expression` instance is passed, it will be used as-is.
    -3019            append: if `True`, add to any existing expressions.
    -3020                Otherwise, this resets the expressions.
    -3021            dialect: the dialect used to parse the input expressions.
    -3022            copy: if `False`, modify this expression instance in-place.
    -3023            opts: other options to use to parse the input expressions.
    +3001        Returns:
    +3002            The modified Select expression.
    +3003        """
    +3004        return _apply_list_builder(
    +3005            *expressions,
    +3006            instance=self,
    +3007            arg="expressions",
    +3008            append=append,
    +3009            dialect=dialect,
    +3010            copy=copy,
    +3011            **opts,
    +3012        )
    +3013
    +3014    def lateral(
    +3015        self,
    +3016        *expressions: t.Optional[ExpOrStr],
    +3017        append: bool = True,
    +3018        dialect: DialectType = None,
    +3019        copy: bool = True,
    +3020        **opts,
    +3021    ) -> Select:
    +3022        """
    +3023        Append to or set the LATERAL expressions.
     3024
    -3025        Returns:
    -3026            The modified Select expression.
    -3027        """
    -3028        return _apply_list_builder(
    -3029            *expressions,
    -3030            instance=self,
    -3031            arg="laterals",
    -3032            append=append,
    -3033            into=Lateral,
    -3034            prefix="LATERAL VIEW",
    -3035            dialect=dialect,
    -3036            copy=copy,
    -3037            **opts,
    -3038        )
    -3039
    -3040    def join(
    -3041        self,
    -3042        expression: ExpOrStr,
    -3043        on: t.Optional[ExpOrStr] = None,
    -3044        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
    -3045        append: bool = True,
    -3046        join_type: t.Optional[str] = None,
    -3047        join_alias: t.Optional[Identifier | str] = None,
    -3048        dialect: DialectType = None,
    -3049        copy: bool = True,
    -3050        **opts,
    -3051    ) -> Select:
    -3052        """
    -3053        Append to or set the JOIN expressions.
    -3054
    -3055        Example:
    -3056            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
    -3057            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
    -3058
    -3059            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
    -3060            'SELECT 1 FROM a JOIN b USING (x, y, z)'
    -3061
    -3062            Use `join_type` to change the type of join:
    -3063
    -3064            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
    -3065            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
    -3066
    -3067        Args:
    -3068            expression: the SQL code string to parse.
    -3069                If an `Expression` instance is passed, it will be used as-is.
    -3070            on: optionally specify the join "on" criteria as a SQL string.
    -3071                If an `Expression` instance is passed, it will be used as-is.
    -3072            using: optionally specify the join "using" criteria as a SQL string.
    -3073                If an `Expression` instance is passed, it will be used as-is.
    -3074            append: if `True`, add to any existing expressions.
    -3075                Otherwise, this resets the expressions.
    -3076            join_type: if set, alter the parsed join type.
    -3077            join_alias: an optional alias for the joined source.
    -3078            dialect: the dialect used to parse the input expressions.
    -3079            copy: if `False`, modify this expression instance in-place.
    -3080            opts: other options to use to parse the input expressions.
    -3081
    -3082        Returns:
    -3083            Select: the modified expression.
    -3084        """
    -3085        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
    -3086
    -3087        try:
    -3088            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
    -3089        except ParseError:
    -3090            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
    -3091
    -3092        join = expression if isinstance(expression, Join) else Join(this=expression)
    -3093
    -3094        if isinstance(join.this, Select):
    -3095            join.this.replace(join.this.subquery())
    -3096
    -3097        if join_type:
    -3098            method: t.Optional[Token]
    -3099            side: t.Optional[Token]
    -3100            kind: t.Optional[Token]
    -3101
    -3102            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
    -3103
    -3104            if method:
    -3105                join.set("method", method.text)
    -3106            if side:
    -3107                join.set("side", side.text)
    -3108            if kind:
    -3109                join.set("kind", kind.text)
    -3110
    -3111        if on:
    -3112            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
    -3113            join.set("on", on)
    +3025        Example:
    +3026            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
    +3027            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
    +3028
    +3029        Args:
    +3030            *expressions: the SQL code strings to parse.
    +3031                If an `Expression` instance is passed, it will be used as-is.
    +3032            append: if `True`, add to any existing expressions.
    +3033                Otherwise, this resets the expressions.
    +3034            dialect: the dialect used to parse the input expressions.
    +3035            copy: if `False`, modify this expression instance in-place.
    +3036            opts: other options to use to parse the input expressions.
    +3037
    +3038        Returns:
    +3039            The modified Select expression.
    +3040        """
    +3041        return _apply_list_builder(
    +3042            *expressions,
    +3043            instance=self,
    +3044            arg="laterals",
    +3045            append=append,
    +3046            into=Lateral,
    +3047            prefix="LATERAL VIEW",
    +3048            dialect=dialect,
    +3049            copy=copy,
    +3050            **opts,
    +3051        )
    +3052
    +3053    def join(
    +3054        self,
    +3055        expression: ExpOrStr,
    +3056        on: t.Optional[ExpOrStr] = None,
    +3057        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
    +3058        append: bool = True,
    +3059        join_type: t.Optional[str] = None,
    +3060        join_alias: t.Optional[Identifier | str] = None,
    +3061        dialect: DialectType = None,
    +3062        copy: bool = True,
    +3063        **opts,
    +3064    ) -> Select:
    +3065        """
    +3066        Append to or set the JOIN expressions.
    +3067
    +3068        Example:
    +3069            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
    +3070            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
    +3071
    +3072            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
    +3073            'SELECT 1 FROM a JOIN b USING (x, y, z)'
    +3074
    +3075            Use `join_type` to change the type of join:
    +3076
    +3077            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
    +3078            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
    +3079
    +3080        Args:
    +3081            expression: the SQL code string to parse.
    +3082                If an `Expression` instance is passed, it will be used as-is.
    +3083            on: optionally specify the join "on" criteria as a SQL string.
    +3084                If an `Expression` instance is passed, it will be used as-is.
    +3085            using: optionally specify the join "using" criteria as a SQL string.
    +3086                If an `Expression` instance is passed, it will be used as-is.
    +3087            append: if `True`, add to any existing expressions.
    +3088                Otherwise, this resets the expressions.
    +3089            join_type: if set, alter the parsed join type.
    +3090            join_alias: an optional alias for the joined source.
    +3091            dialect: the dialect used to parse the input expressions.
    +3092            copy: if `False`, modify this expression instance in-place.
    +3093            opts: other options to use to parse the input expressions.
    +3094
    +3095        Returns:
    +3096            Select: the modified expression.
    +3097        """
    +3098        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
    +3099
    +3100        try:
    +3101            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
    +3102        except ParseError:
    +3103            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
    +3104
    +3105        join = expression if isinstance(expression, Join) else Join(this=expression)
    +3106
    +3107        if isinstance(join.this, Select):
    +3108            join.this.replace(join.this.subquery())
    +3109
    +3110        if join_type:
    +3111            method: t.Optional[Token]
    +3112            side: t.Optional[Token]
    +3113            kind: t.Optional[Token]
     3114
    -3115        if using:
    -3116            join = _apply_list_builder(
    -3117                *ensure_list(using),
    -3118                instance=join,
    -3119                arg="using",
    -3120                append=append,
    -3121                copy=copy,
    -3122                into=Identifier,
    -3123                **opts,
    -3124            )
    -3125
    -3126        if join_alias:
    -3127            join.set("this", alias_(join.this, join_alias, table=True))
    -3128
    -3129        return _apply_list_builder(
    -3130            join,
    -3131            instance=self,
    -3132            arg="joins",
    -3133            append=append,
    -3134            copy=copy,
    -3135            **opts,
    -3136        )
    -3137
    -3138    def where(
    -3139        self,
    -3140        *expressions: t.Optional[ExpOrStr],
    -3141        append: bool = True,
    -3142        dialect: DialectType = None,
    -3143        copy: bool = True,
    -3144        **opts,
    -3145    ) -> Select:
    -3146        """
    -3147        Append to or set the WHERE expressions.
    -3148
    -3149        Example:
    -3150            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
    -3151            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
    -3152
    -3153        Args:
    -3154            *expressions: the SQL code strings to parse.
    -3155                If an `Expression` instance is passed, it will be used as-is.
    -3156                Multiple expressions are combined with an AND operator.
    -3157            append: if `True`, AND the new expressions to any existing expression.
    -3158                Otherwise, this resets the expression.
    -3159            dialect: the dialect used to parse the input expressions.
    -3160            copy: if `False`, modify this expression instance in-place.
    -3161            opts: other options to use to parse the input expressions.
    -3162
    -3163        Returns:
    -3164            Select: the modified expression.
    -3165        """
    -3166        return _apply_conjunction_builder(
    -3167            *expressions,
    -3168            instance=self,
    -3169            arg="where",
    -3170            append=append,
    -3171            into=Where,
    -3172            dialect=dialect,
    -3173            copy=copy,
    -3174            **opts,
    -3175        )
    -3176
    -3177    def having(
    -3178        self,
    -3179        *expressions: t.Optional[ExpOrStr],
    -3180        append: bool = True,
    -3181        dialect: DialectType = None,
    -3182        copy: bool = True,
    -3183        **opts,
    -3184    ) -> Select:
    -3185        """
    -3186        Append to or set the HAVING expressions.
    -3187
    -3188        Example:
    -3189            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
    -3190            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
    -3191
    -3192        Args:
    -3193            *expressions: the SQL code strings to parse.
    -3194                If an `Expression` instance is passed, it will be used as-is.
    -3195                Multiple expressions are combined with an AND operator.
    -3196            append: if `True`, AND the new expressions to any existing expression.
    -3197                Otherwise, this resets the expression.
    -3198            dialect: the dialect used to parse the input expressions.
    -3199            copy: if `False`, modify this expression instance in-place.
    -3200            opts: other options to use to parse the input expressions.
    -3201
    -3202        Returns:
    -3203            The modified Select expression.
    -3204        """
    -3205        return _apply_conjunction_builder(
    -3206            *expressions,
    -3207            instance=self,
    -3208            arg="having",
    -3209            append=append,
    -3210            into=Having,
    -3211            dialect=dialect,
    -3212            copy=copy,
    -3213            **opts,
    -3214        )
    -3215
    -3216    def window(
    -3217        self,
    -3218        *expressions: t.Optional[ExpOrStr],
    -3219        append: bool = True,
    -3220        dialect: DialectType = None,
    -3221        copy: bool = True,
    -3222        **opts,
    -3223    ) -> Select:
    -3224        return _apply_list_builder(
    -3225            *expressions,
    -3226            instance=self,
    -3227            arg="windows",
    -3228            append=append,
    -3229            into=Window,
    -3230            dialect=dialect,
    -3231            copy=copy,
    -3232            **opts,
    -3233        )
    -3234
    -3235    def qualify(
    -3236        self,
    -3237        *expressions: t.Optional[ExpOrStr],
    -3238        append: bool = True,
    -3239        dialect: DialectType = None,
    -3240        copy: bool = True,
    -3241        **opts,
    -3242    ) -> Select:
    -3243        return _apply_conjunction_builder(
    -3244            *expressions,
    -3245            instance=self,
    -3246            arg="qualify",
    -3247            append=append,
    -3248            into=Qualify,
    -3249            dialect=dialect,
    -3250            copy=copy,
    -3251            **opts,
    -3252        )
    -3253
    -3254    def distinct(
    -3255        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
    -3256    ) -> Select:
    -3257        """
    -3258        Set the OFFSET expression.
    -3259
    -3260        Example:
    -3261            >>> Select().from_("tbl").select("x").distinct().sql()
    -3262            'SELECT DISTINCT x FROM tbl'
    -3263
    -3264        Args:
    -3265            ons: the expressions to distinct on
    -3266            distinct: whether the Select should be distinct
    -3267            copy: if `False`, modify this expression instance in-place.
    -3268
    -3269        Returns:
    -3270            Select: the modified expression.
    -3271        """
    -3272        instance = maybe_copy(self, copy)
    -3273        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
    -3274        instance.set("distinct", Distinct(on=on) if distinct else None)
    -3275        return instance
    +3115            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
    +3116
    +3117            if method:
    +3118                join.set("method", method.text)
    +3119            if side:
    +3120                join.set("side", side.text)
    +3121            if kind:
    +3122                join.set("kind", kind.text)
    +3123
    +3124        if on:
    +3125            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
    +3126            join.set("on", on)
    +3127
    +3128        if using:
    +3129            join = _apply_list_builder(
    +3130                *ensure_list(using),
    +3131                instance=join,
    +3132                arg="using",
    +3133                append=append,
    +3134                copy=copy,
    +3135                into=Identifier,
    +3136                **opts,
    +3137            )
    +3138
    +3139        if join_alias:
    +3140            join.set("this", alias_(join.this, join_alias, table=True))
    +3141
    +3142        return _apply_list_builder(
    +3143            join,
    +3144            instance=self,
    +3145            arg="joins",
    +3146            append=append,
    +3147            copy=copy,
    +3148            **opts,
    +3149        )
    +3150
    +3151    def where(
    +3152        self,
    +3153        *expressions: t.Optional[ExpOrStr],
    +3154        append: bool = True,
    +3155        dialect: DialectType = None,
    +3156        copy: bool = True,
    +3157        **opts,
    +3158    ) -> Select:
    +3159        """
    +3160        Append to or set the WHERE expressions.
    +3161
    +3162        Example:
    +3163            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
    +3164            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
    +3165
    +3166        Args:
    +3167            *expressions: the SQL code strings to parse.
    +3168                If an `Expression` instance is passed, it will be used as-is.
    +3169                Multiple expressions are combined with an AND operator.
    +3170            append: if `True`, AND the new expressions to any existing expression.
    +3171                Otherwise, this resets the expression.
    +3172            dialect: the dialect used to parse the input expressions.
    +3173            copy: if `False`, modify this expression instance in-place.
    +3174            opts: other options to use to parse the input expressions.
    +3175
    +3176        Returns:
    +3177            Select: the modified expression.
    +3178        """
    +3179        return _apply_conjunction_builder(
    +3180            *expressions,
    +3181            instance=self,
    +3182            arg="where",
    +3183            append=append,
    +3184            into=Where,
    +3185            dialect=dialect,
    +3186            copy=copy,
    +3187            **opts,
    +3188        )
    +3189
    +3190    def having(
    +3191        self,
    +3192        *expressions: t.Optional[ExpOrStr],
    +3193        append: bool = True,
    +3194        dialect: DialectType = None,
    +3195        copy: bool = True,
    +3196        **opts,
    +3197    ) -> Select:
    +3198        """
    +3199        Append to or set the HAVING expressions.
    +3200
    +3201        Example:
    +3202            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
    +3203            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
    +3204
    +3205        Args:
    +3206            *expressions: the SQL code strings to parse.
    +3207                If an `Expression` instance is passed, it will be used as-is.
    +3208                Multiple expressions are combined with an AND operator.
    +3209            append: if `True`, AND the new expressions to any existing expression.
    +3210                Otherwise, this resets the expression.
    +3211            dialect: the dialect used to parse the input expressions.
    +3212            copy: if `False`, modify this expression instance in-place.
    +3213            opts: other options to use to parse the input expressions.
    +3214
    +3215        Returns:
    +3216            The modified Select expression.
    +3217        """
    +3218        return _apply_conjunction_builder(
    +3219            *expressions,
    +3220            instance=self,
    +3221            arg="having",
    +3222            append=append,
    +3223            into=Having,
    +3224            dialect=dialect,
    +3225            copy=copy,
    +3226            **opts,
    +3227        )
    +3228
    +3229    def window(
    +3230        self,
    +3231        *expressions: t.Optional[ExpOrStr],
    +3232        append: bool = True,
    +3233        dialect: DialectType = None,
    +3234        copy: bool = True,
    +3235        **opts,
    +3236    ) -> Select:
    +3237        return _apply_list_builder(
    +3238            *expressions,
    +3239            instance=self,
    +3240            arg="windows",
    +3241            append=append,
    +3242            into=Window,
    +3243            dialect=dialect,
    +3244            copy=copy,
    +3245            **opts,
    +3246        )
    +3247
    +3248    def qualify(
    +3249        self,
    +3250        *expressions: t.Optional[ExpOrStr],
    +3251        append: bool = True,
    +3252        dialect: DialectType = None,
    +3253        copy: bool = True,
    +3254        **opts,
    +3255    ) -> Select:
    +3256        return _apply_conjunction_builder(
    +3257            *expressions,
    +3258            instance=self,
    +3259            arg="qualify",
    +3260            append=append,
    +3261            into=Qualify,
    +3262            dialect=dialect,
    +3263            copy=copy,
    +3264            **opts,
    +3265        )
    +3266
    +3267    def distinct(
    +3268        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
    +3269    ) -> Select:
    +3270        """
    +3271        Set the OFFSET expression.
    +3272
    +3273        Example:
    +3274            >>> Select().from_("tbl").select("x").distinct().sql()
    +3275            'SELECT DISTINCT x FROM tbl'
     3276
    -3277    def ctas(
    -3278        self,
    -3279        table: ExpOrStr,
    -3280        properties: t.Optional[t.Dict] = None,
    -3281        dialect: DialectType = None,
    -3282        copy: bool = True,
    -3283        **opts,
    -3284    ) -> Create:
    -3285        """
    -3286        Convert this expression to a CREATE TABLE AS statement.
    -3287
    -3288        Example:
    -3289            >>> Select().select("*").from_("tbl").ctas("x").sql()
    -3290            'CREATE TABLE x AS SELECT * FROM tbl'
    -3291
    -3292        Args:
    -3293            table: the SQL code string to parse as the table name.
    -3294                If another `Expression` instance is passed, it will be used as-is.
    -3295            properties: an optional mapping of table properties
    -3296            dialect: the dialect used to parse the input table.
    -3297            copy: if `False`, modify this expression instance in-place.
    -3298            opts: other options to use to parse the input table.
    -3299
    -3300        Returns:
    -3301            The new Create expression.
    -3302        """
    -3303        instance = maybe_copy(self, copy)
    -3304        table_expression = maybe_parse(
    -3305            table,
    -3306            into=Table,
    -3307            dialect=dialect,
    -3308            **opts,
    -3309        )
    -3310        properties_expression = None
    -3311        if properties:
    -3312            properties_expression = Properties.from_dict(properties)
    -3313
    -3314        return Create(
    -3315            this=table_expression,
    -3316            kind="table",
    -3317            expression=instance,
    -3318            properties=properties_expression,
    -3319        )
    -3320
    -3321    def lock(self, update: bool = True, copy: bool = True) -> Select:
    -3322        """
    -3323        Set the locking read mode for this expression.
    -3324
    -3325        Examples:
    -3326            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
    -3327            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
    -3328
    -3329            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
    -3330            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
    -3331
    -3332        Args:
    -3333            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
    -3334            copy: if `False`, modify this expression instance in-place.
    -3335
    -3336        Returns:
    -3337            The modified expression.
    -3338        """
    -3339        inst = maybe_copy(self, copy)
    -3340        inst.set("locks", [Lock(update=update)])
    +3277        Args:
    +3278            ons: the expressions to distinct on
    +3279            distinct: whether the Select should be distinct
    +3280            copy: if `False`, modify this expression instance in-place.
    +3281
    +3282        Returns:
    +3283            Select: the modified expression.
    +3284        """
    +3285        instance = maybe_copy(self, copy)
    +3286        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
    +3287        instance.set("distinct", Distinct(on=on) if distinct else None)
    +3288        return instance
    +3289
    +3290    def ctas(
    +3291        self,
    +3292        table: ExpOrStr,
    +3293        properties: t.Optional[t.Dict] = None,
    +3294        dialect: DialectType = None,
    +3295        copy: bool = True,
    +3296        **opts,
    +3297    ) -> Create:
    +3298        """
    +3299        Convert this expression to a CREATE TABLE AS statement.
    +3300
    +3301        Example:
    +3302            >>> Select().select("*").from_("tbl").ctas("x").sql()
    +3303            'CREATE TABLE x AS SELECT * FROM tbl'
    +3304
    +3305        Args:
    +3306            table: the SQL code string to parse as the table name.
    +3307                If another `Expression` instance is passed, it will be used as-is.
    +3308            properties: an optional mapping of table properties
    +3309            dialect: the dialect used to parse the input table.
    +3310            copy: if `False`, modify this expression instance in-place.
    +3311            opts: other options to use to parse the input table.
    +3312
    +3313        Returns:
    +3314            The new Create expression.
    +3315        """
    +3316        instance = maybe_copy(self, copy)
    +3317        table_expression = maybe_parse(
    +3318            table,
    +3319            into=Table,
    +3320            dialect=dialect,
    +3321            **opts,
    +3322        )
    +3323        properties_expression = None
    +3324        if properties:
    +3325            properties_expression = Properties.from_dict(properties)
    +3326
    +3327        return Create(
    +3328            this=table_expression,
    +3329            kind="table",
    +3330            expression=instance,
    +3331            properties=properties_expression,
    +3332        )
    +3333
    +3334    def lock(self, update: bool = True, copy: bool = True) -> Select:
    +3335        """
    +3336        Set the locking read mode for this expression.
    +3337
    +3338        Examples:
    +3339            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
    +3340            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
     3341
    -3342        return inst
    -3343
    -3344    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
    -3345        """
    -3346        Set hints for this expression.
    -3347
    -3348        Examples:
    -3349            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
    -3350            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
    -3351
    -3352        Args:
    -3353            hints: The SQL code strings to parse as the hints.
    -3354                If an `Expression` instance is passed, it will be used as-is.
    -3355            dialect: The dialect used to parse the hints.
    -3356            copy: If `False`, modify this expression instance in-place.
    -3357
    -3358        Returns:
    -3359            The modified expression.
    -3360        """
    -3361        inst = maybe_copy(self, copy)
    -3362        inst.set(
    -3363            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
    -3364        )
    -3365
    -3366        return inst
    -3367
    -3368    @property
    -3369    def named_selects(self) -> t.List[str]:
    -3370        return [e.output_name for e in self.expressions if e.alias_or_name]
    -3371
    -3372    @property
    -3373    def is_star(self) -> bool:
    -3374        return any(expression.is_star for expression in self.expressions)
    -3375
    -3376    @property
    -3377    def selects(self) -> t.List[Expression]:
    -3378        return self.expressions
    +3342            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
    +3343            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
    +3344
    +3345        Args:
    +3346            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
    +3347            copy: if `False`, modify this expression instance in-place.
    +3348
    +3349        Returns:
    +3350            The modified expression.
    +3351        """
    +3352        inst = maybe_copy(self, copy)
    +3353        inst.set("locks", [Lock(update=update)])
    +3354
    +3355        return inst
    +3356
    +3357    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
    +3358        """
    +3359        Set hints for this expression.
    +3360
    +3361        Examples:
    +3362            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
    +3363            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
    +3364
    +3365        Args:
    +3366            hints: The SQL code strings to parse as the hints.
    +3367                If an `Expression` instance is passed, it will be used as-is.
    +3368            dialect: The dialect used to parse the hints.
    +3369            copy: If `False`, modify this expression instance in-place.
    +3370
    +3371        Returns:
    +3372            The modified expression.
    +3373        """
    +3374        inst = maybe_copy(self, copy)
    +3375        inst.set(
    +3376            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
    +3377        )
    +3378
    +3379        return inst
    +3380
    +3381    @property
    +3382    def named_selects(self) -> t.List[str]:
    +3383        return [e.output_name for e in self.expressions if e.alias_or_name]
    +3384
    +3385    @property
    +3386    def is_star(self) -> bool:
    +3387        return any(expression.is_star for expression in self.expressions)
    +3388
    +3389    @property
    +3390    def selects(self) -> t.List[Expression]:
    +3391        return self.expressions
     
    @@ -39156,37 +39524,37 @@ kind is ("AS OF", "BETWEEN")

    -
    2700    def from_(
    -2701        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    -2702    ) -> Select:
    -2703        """
    -2704        Set the FROM expression.
    -2705
    -2706        Example:
    -2707            >>> Select().from_("tbl").select("x").sql()
    -2708            'SELECT x FROM tbl'
    -2709
    -2710        Args:
    -2711            expression : the SQL code strings to parse.
    -2712                If a `From` instance is passed, this is used as-is.
    -2713                If another `Expression` instance is passed, it will be wrapped in a `From`.
    -2714            dialect: the dialect used to parse the input expression.
    -2715            copy: if `False`, modify this expression instance in-place.
    -2716            opts: other options to use to parse the input expressions.
    -2717
    -2718        Returns:
    -2719            The modified Select expression.
    -2720        """
    -2721        return _apply_builder(
    -2722            expression=expression,
    -2723            instance=self,
    -2724            arg="from",
    -2725            into=From,
    -2726            prefix="FROM",
    -2727            dialect=dialect,
    -2728            copy=copy,
    -2729            **opts,
    -2730        )
    +            
    2713    def from_(
    +2714        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    +2715    ) -> Select:
    +2716        """
    +2717        Set the FROM expression.
    +2718
    +2719        Example:
    +2720            >>> Select().from_("tbl").select("x").sql()
    +2721            'SELECT x FROM tbl'
    +2722
    +2723        Args:
    +2724            expression : the SQL code strings to parse.
    +2725                If a `From` instance is passed, this is used as-is.
    +2726                If another `Expression` instance is passed, it will be wrapped in a `From`.
    +2727            dialect: the dialect used to parse the input expression.
    +2728            copy: if `False`, modify this expression instance in-place.
    +2729            opts: other options to use to parse the input expressions.
    +2730
    +2731        Returns:
    +2732            The modified Select expression.
    +2733        """
    +2734        return _apply_builder(
    +2735            expression=expression,
    +2736            instance=self,
    +2737            arg="from",
    +2738            into=From,
    +2739            prefix="FROM",
    +2740            dialect=dialect,
    +2741            copy=copy,
    +2742            **opts,
    +2743        )
     
    @@ -39233,49 +39601,49 @@ If another Expression instance is passed,
    -
    2732    def group_by(
    -2733        self,
    -2734        *expressions: t.Optional[ExpOrStr],
    -2735        append: bool = True,
    -2736        dialect: DialectType = None,
    -2737        copy: bool = True,
    -2738        **opts,
    -2739    ) -> Select:
    -2740        """
    -2741        Set the GROUP BY expression.
    -2742
    -2743        Example:
    -2744            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
    -2745            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
    -2746
    -2747        Args:
    -2748            *expressions: the SQL code strings to parse.
    -2749                If a `Group` instance is passed, this is used as-is.
    -2750                If another `Expression` instance is passed, it will be wrapped in a `Group`.
    -2751                If nothing is passed in then a group by is not applied to the expression
    -2752            append: if `True`, add to any existing expressions.
    -2753                Otherwise, this flattens all the `Group` expression into a single expression.
    -2754            dialect: the dialect used to parse the input expression.
    -2755            copy: if `False`, modify this expression instance in-place.
    -2756            opts: other options to use to parse the input expressions.
    -2757
    -2758        Returns:
    -2759            The modified Select expression.
    -2760        """
    -2761        if not expressions:
    -2762            return self if not copy else self.copy()
    -2763
    -2764        return _apply_child_list_builder(
    -2765            *expressions,
    -2766            instance=self,
    -2767            arg="group",
    -2768            append=append,
    -2769            copy=copy,
    -2770            prefix="GROUP BY",
    -2771            into=Group,
    -2772            dialect=dialect,
    -2773            **opts,
    -2774        )
    +            
    2745    def group_by(
    +2746        self,
    +2747        *expressions: t.Optional[ExpOrStr],
    +2748        append: bool = True,
    +2749        dialect: DialectType = None,
    +2750        copy: bool = True,
    +2751        **opts,
    +2752    ) -> Select:
    +2753        """
    +2754        Set the GROUP BY expression.
    +2755
    +2756        Example:
    +2757            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
    +2758            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
    +2759
    +2760        Args:
    +2761            *expressions: the SQL code strings to parse.
    +2762                If a `Group` instance is passed, this is used as-is.
    +2763                If another `Expression` instance is passed, it will be wrapped in a `Group`.
    +2764                If nothing is passed in then a group by is not applied to the expression
    +2765            append: if `True`, add to any existing expressions.
    +2766                Otherwise, this flattens all the `Group` expression into a single expression.
    +2767            dialect: the dialect used to parse the input expression.
    +2768            copy: if `False`, modify this expression instance in-place.
    +2769            opts: other options to use to parse the input expressions.
    +2770
    +2771        Returns:
    +2772            The modified Select expression.
    +2773        """
    +2774        if not expressions:
    +2775            return self if not copy else self.copy()
    +2776
    +2777        return _apply_child_list_builder(
    +2778            *expressions,
    +2779            instance=self,
    +2780            arg="group",
    +2781            append=append,
    +2782            copy=copy,
    +2783            prefix="GROUP BY",
    +2784            into=Group,
    +2785            dialect=dialect,
    +2786            **opts,
    +2787        )
     
    @@ -39325,45 +39693,45 @@ Otherwise, this flattens all the Group express
    -
    2776    def order_by(
    -2777        self,
    -2778        *expressions: t.Optional[ExpOrStr],
    -2779        append: bool = True,
    -2780        dialect: DialectType = None,
    -2781        copy: bool = True,
    -2782        **opts,
    -2783    ) -> Select:
    -2784        """
    -2785        Set the ORDER BY expression.
    -2786
    -2787        Example:
    -2788            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
    -2789            'SELECT x FROM tbl ORDER BY x DESC'
    -2790
    -2791        Args:
    -2792            *expressions: the SQL code strings to parse.
    -2793                If a `Group` instance is passed, this is used as-is.
    -2794                If another `Expression` instance is passed, it will be wrapped in a `Order`.
    -2795            append: if `True`, add to any existing expressions.
    -2796                Otherwise, this flattens all the `Order` expression into a single expression.
    -2797            dialect: the dialect used to parse the input expression.
    -2798            copy: if `False`, modify this expression instance in-place.
    -2799            opts: other options to use to parse the input expressions.
    -2800
    -2801        Returns:
    -2802            The modified Select expression.
    -2803        """
    -2804        return _apply_child_list_builder(
    -2805            *expressions,
    -2806            instance=self,
    -2807            arg="order",
    -2808            append=append,
    -2809            copy=copy,
    -2810            prefix="ORDER BY",
    -2811            into=Order,
    -2812            dialect=dialect,
    -2813            **opts,
    -2814        )
    +            
    2789    def order_by(
    +2790        self,
    +2791        *expressions: t.Optional[ExpOrStr],
    +2792        append: bool = True,
    +2793        dialect: DialectType = None,
    +2794        copy: bool = True,
    +2795        **opts,
    +2796    ) -> Select:
    +2797        """
    +2798        Set the ORDER BY expression.
    +2799
    +2800        Example:
    +2801            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
    +2802            'SELECT x FROM tbl ORDER BY x DESC'
    +2803
    +2804        Args:
    +2805            *expressions: the SQL code strings to parse.
    +2806                If a `Group` instance is passed, this is used as-is.
    +2807                If another `Expression` instance is passed, it will be wrapped in a `Order`.
    +2808            append: if `True`, add to any existing expressions.
    +2809                Otherwise, this flattens all the `Order` expression into a single expression.
    +2810            dialect: the dialect used to parse the input expression.
    +2811            copy: if `False`, modify this expression instance in-place.
    +2812            opts: other options to use to parse the input expressions.
    +2813
    +2814        Returns:
    +2815            The modified Select expression.
    +2816        """
    +2817        return _apply_child_list_builder(
    +2818            *expressions,
    +2819            instance=self,
    +2820            arg="order",
    +2821            append=append,
    +2822            copy=copy,
    +2823            prefix="ORDER BY",
    +2824            into=Order,
    +2825            dialect=dialect,
    +2826            **opts,
    +2827        )
     
    @@ -39412,45 +39780,45 @@ Otherwise, this flattens all the Order express
    -
    2816    def sort_by(
    -2817        self,
    -2818        *expressions: t.Optional[ExpOrStr],
    -2819        append: bool = True,
    -2820        dialect: DialectType = None,
    -2821        copy: bool = True,
    -2822        **opts,
    -2823    ) -> Select:
    -2824        """
    -2825        Set the SORT BY expression.
    -2826
    -2827        Example:
    -2828            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
    -2829            'SELECT x FROM tbl SORT BY x DESC'
    -2830
    -2831        Args:
    -2832            *expressions: the SQL code strings to parse.
    -2833                If a `Group` instance is passed, this is used as-is.
    -2834                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
    -2835            append: if `True`, add to any existing expressions.
    -2836                Otherwise, this flattens all the `Order` expression into a single expression.
    -2837            dialect: the dialect used to parse the input expression.
    -2838            copy: if `False`, modify this expression instance in-place.
    -2839            opts: other options to use to parse the input expressions.
    -2840
    -2841        Returns:
    -2842            The modified Select expression.
    -2843        """
    -2844        return _apply_child_list_builder(
    -2845            *expressions,
    -2846            instance=self,
    -2847            arg="sort",
    -2848            append=append,
    -2849            copy=copy,
    -2850            prefix="SORT BY",
    -2851            into=Sort,
    -2852            dialect=dialect,
    -2853            **opts,
    -2854        )
    +            
    2829    def sort_by(
    +2830        self,
    +2831        *expressions: t.Optional[ExpOrStr],
    +2832        append: bool = True,
    +2833        dialect: DialectType = None,
    +2834        copy: bool = True,
    +2835        **opts,
    +2836    ) -> Select:
    +2837        """
    +2838        Set the SORT BY expression.
    +2839
    +2840        Example:
    +2841            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
    +2842            'SELECT x FROM tbl SORT BY x DESC'
    +2843
    +2844        Args:
    +2845            *expressions: the SQL code strings to parse.
    +2846                If a `Group` instance is passed, this is used as-is.
    +2847                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
    +2848            append: if `True`, add to any existing expressions.
    +2849                Otherwise, this flattens all the `Order` expression into a single expression.
    +2850            dialect: the dialect used to parse the input expression.
    +2851            copy: if `False`, modify this expression instance in-place.
    +2852            opts: other options to use to parse the input expressions.
    +2853
    +2854        Returns:
    +2855            The modified Select expression.
    +2856        """
    +2857        return _apply_child_list_builder(
    +2858            *expressions,
    +2859            instance=self,
    +2860            arg="sort",
    +2861            append=append,
    +2862            copy=copy,
    +2863            prefix="SORT BY",
    +2864            into=Sort,
    +2865            dialect=dialect,
    +2866            **opts,
    +2867        )
     
    @@ -39499,45 +39867,45 @@ Otherwise, this flattens all the Order express
    -
    2856    def cluster_by(
    -2857        self,
    -2858        *expressions: t.Optional[ExpOrStr],
    -2859        append: bool = True,
    -2860        dialect: DialectType = None,
    -2861        copy: bool = True,
    -2862        **opts,
    -2863    ) -> Select:
    -2864        """
    -2865        Set the CLUSTER BY expression.
    -2866
    -2867        Example:
    -2868            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
    -2869            'SELECT x FROM tbl CLUSTER BY x DESC'
    -2870
    -2871        Args:
    -2872            *expressions: the SQL code strings to parse.
    -2873                If a `Group` instance is passed, this is used as-is.
    -2874                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
    -2875            append: if `True`, add to any existing expressions.
    -2876                Otherwise, this flattens all the `Order` expression into a single expression.
    -2877            dialect: the dialect used to parse the input expression.
    -2878            copy: if `False`, modify this expression instance in-place.
    -2879            opts: other options to use to parse the input expressions.
    -2880
    -2881        Returns:
    -2882            The modified Select expression.
    -2883        """
    -2884        return _apply_child_list_builder(
    -2885            *expressions,
    -2886            instance=self,
    -2887            arg="cluster",
    -2888            append=append,
    -2889            copy=copy,
    -2890            prefix="CLUSTER BY",
    -2891            into=Cluster,
    -2892            dialect=dialect,
    -2893            **opts,
    -2894        )
    +            
    2869    def cluster_by(
    +2870        self,
    +2871        *expressions: t.Optional[ExpOrStr],
    +2872        append: bool = True,
    +2873        dialect: DialectType = None,
    +2874        copy: bool = True,
    +2875        **opts,
    +2876    ) -> Select:
    +2877        """
    +2878        Set the CLUSTER BY expression.
    +2879
    +2880        Example:
    +2881            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
    +2882            'SELECT x FROM tbl CLUSTER BY x DESC'
    +2883
    +2884        Args:
    +2885            *expressions: the SQL code strings to parse.
    +2886                If a `Group` instance is passed, this is used as-is.
    +2887                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
    +2888            append: if `True`, add to any existing expressions.
    +2889                Otherwise, this flattens all the `Order` expression into a single expression.
    +2890            dialect: the dialect used to parse the input expression.
    +2891            copy: if `False`, modify this expression instance in-place.
    +2892            opts: other options to use to parse the input expressions.
    +2893
    +2894        Returns:
    +2895            The modified Select expression.
    +2896        """
    +2897        return _apply_child_list_builder(
    +2898            *expressions,
    +2899            instance=self,
    +2900            arg="cluster",
    +2901            append=append,
    +2902            copy=copy,
    +2903            prefix="CLUSTER BY",
    +2904            into=Cluster,
    +2905            dialect=dialect,
    +2906            **opts,
    +2907        )
     
    @@ -39586,39 +39954,39 @@ Otherwise, this flattens all the Order express
    -
    2896    def limit(
    -2897        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2898    ) -> Select:
    -2899        """
    -2900        Set the LIMIT expression.
    -2901
    -2902        Example:
    -2903            >>> Select().from_("tbl").select("x").limit(10).sql()
    -2904            'SELECT x FROM tbl LIMIT 10'
    -2905
    -2906        Args:
    -2907            expression: the SQL code string to parse.
    -2908                This can also be an integer.
    -2909                If a `Limit` instance is passed, this is used as-is.
    -2910                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    -2911            dialect: the dialect used to parse the input expression.
    -2912            copy: if `False`, modify this expression instance in-place.
    -2913            opts: other options to use to parse the input expressions.
    +            
    2909    def limit(
    +2910        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2911    ) -> Select:
    +2912        """
    +2913        Set the LIMIT expression.
     2914
    -2915        Returns:
    -2916            Select: the modified expression.
    -2917        """
    -2918        return _apply_builder(
    -2919            expression=expression,
    -2920            instance=self,
    -2921            arg="limit",
    -2922            into=Limit,
    -2923            prefix="LIMIT",
    -2924            dialect=dialect,
    -2925            copy=copy,
    -2926            into_arg="expression",
    -2927            **opts,
    -2928        )
    +2915        Example:
    +2916            >>> Select().from_("tbl").select("x").limit(10).sql()
    +2917            'SELECT x FROM tbl LIMIT 10'
    +2918
    +2919        Args:
    +2920            expression: the SQL code string to parse.
    +2921                This can also be an integer.
    +2922                If a `Limit` instance is passed, this is used as-is.
    +2923                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
    +2924            dialect: the dialect used to parse the input expression.
    +2925            copy: if `False`, modify this expression instance in-place.
    +2926            opts: other options to use to parse the input expressions.
    +2927
    +2928        Returns:
    +2929            Select: the modified expression.
    +2930        """
    +2931        return _apply_builder(
    +2932            expression=expression,
    +2933            instance=self,
    +2934            arg="limit",
    +2935            into=Limit,
    +2936            prefix="LIMIT",
    +2937            dialect=dialect,
    +2938            copy=copy,
    +2939            into_arg="expression",
    +2940            **opts,
    +2941        )
     
    @@ -39666,39 +40034,39 @@ If another Expression instance is passed,
    -
    2930    def offset(
    -2931        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    -2932    ) -> Select:
    -2933        """
    -2934        Set the OFFSET expression.
    -2935
    -2936        Example:
    -2937            >>> Select().from_("tbl").select("x").offset(10).sql()
    -2938            'SELECT x FROM tbl OFFSET 10'
    -2939
    -2940        Args:
    -2941            expression: the SQL code string to parse.
    -2942                This can also be an integer.
    -2943                If a `Offset` instance is passed, this is used as-is.
    -2944                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
    -2945            dialect: the dialect used to parse the input expression.
    -2946            copy: if `False`, modify this expression instance in-place.
    -2947            opts: other options to use to parse the input expressions.
    +            
    2943    def offset(
    +2944        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
    +2945    ) -> Select:
    +2946        """
    +2947        Set the OFFSET expression.
     2948
    -2949        Returns:
    -2950            The modified Select expression.
    -2951        """
    -2952        return _apply_builder(
    -2953            expression=expression,
    -2954            instance=self,
    -2955            arg="offset",
    -2956            into=Offset,
    -2957            prefix="OFFSET",
    -2958            dialect=dialect,
    -2959            copy=copy,
    -2960            into_arg="expression",
    -2961            **opts,
    -2962        )
    +2949        Example:
    +2950            >>> Select().from_("tbl").select("x").offset(10).sql()
    +2951            'SELECT x FROM tbl OFFSET 10'
    +2952
    +2953        Args:
    +2954            expression: the SQL code string to parse.
    +2955                This can also be an integer.
    +2956                If a `Offset` instance is passed, this is used as-is.
    +2957                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
    +2958            dialect: the dialect used to parse the input expression.
    +2959            copy: if `False`, modify this expression instance in-place.
    +2960            opts: other options to use to parse the input expressions.
    +2961
    +2962        Returns:
    +2963            The modified Select expression.
    +2964        """
    +2965        return _apply_builder(
    +2966            expression=expression,
    +2967            instance=self,
    +2968            arg="offset",
    +2969            into=Offset,
    +2970            prefix="OFFSET",
    +2971            dialect=dialect,
    +2972            copy=copy,
    +2973            into_arg="expression",
    +2974            **opts,
    +2975        )
     
    @@ -39746,42 +40114,42 @@ If another Expression instance is passed,
    -
    2964    def select(
    -2965        self,
    -2966        *expressions: t.Optional[ExpOrStr],
    -2967        append: bool = True,
    -2968        dialect: DialectType = None,
    -2969        copy: bool = True,
    -2970        **opts,
    -2971    ) -> Select:
    -2972        """
    -2973        Append to or set the SELECT expressions.
    -2974
    -2975        Example:
    -2976            >>> Select().select("x", "y").sql()
    -2977            'SELECT x, y'
    -2978
    -2979        Args:
    -2980            *expressions: the SQL code strings to parse.
    -2981                If an `Expression` instance is passed, it will be used as-is.
    -2982            append: if `True`, add to any existing expressions.
    -2983                Otherwise, this resets the expressions.
    -2984            dialect: the dialect used to parse the input expressions.
    -2985            copy: if `False`, modify this expression instance in-place.
    -2986            opts: other options to use to parse the input expressions.
    +            
    2977    def select(
    +2978        self,
    +2979        *expressions: t.Optional[ExpOrStr],
    +2980        append: bool = True,
    +2981        dialect: DialectType = None,
    +2982        copy: bool = True,
    +2983        **opts,
    +2984    ) -> Select:
    +2985        """
    +2986        Append to or set the SELECT expressions.
     2987
    -2988        Returns:
    -2989            The modified Select expression.
    -2990        """
    -2991        return _apply_list_builder(
    -2992            *expressions,
    -2993            instance=self,
    -2994            arg="expressions",
    -2995            append=append,
    -2996            dialect=dialect,
    -2997            copy=copy,
    -2998            **opts,
    -2999        )
    +2988        Example:
    +2989            >>> Select().select("x", "y").sql()
    +2990            'SELECT x, y'
    +2991
    +2992        Args:
    +2993            *expressions: the SQL code strings to parse.
    +2994                If an `Expression` instance is passed, it will be used as-is.
    +2995            append: if `True`, add to any existing expressions.
    +2996                Otherwise, this resets the expressions.
    +2997            dialect: the dialect used to parse the input expressions.
    +2998            copy: if `False`, modify this expression instance in-place.
    +2999            opts: other options to use to parse the input expressions.
    +3000
    +3001        Returns:
    +3002            The modified Select expression.
    +3003        """
    +3004        return _apply_list_builder(
    +3005            *expressions,
    +3006            instance=self,
    +3007            arg="expressions",
    +3008            append=append,
    +3009            dialect=dialect,
    +3010            copy=copy,
    +3011            **opts,
    +3012        )
     
    @@ -39829,44 +40197,44 @@ Otherwise, this resets the expressions.
    -
    3001    def lateral(
    -3002        self,
    -3003        *expressions: t.Optional[ExpOrStr],
    -3004        append: bool = True,
    -3005        dialect: DialectType = None,
    -3006        copy: bool = True,
    -3007        **opts,
    -3008    ) -> Select:
    -3009        """
    -3010        Append to or set the LATERAL expressions.
    -3011
    -3012        Example:
    -3013            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
    -3014            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
    -3015
    -3016        Args:
    -3017            *expressions: the SQL code strings to parse.
    -3018                If an `Expression` instance is passed, it will be used as-is.
    -3019            append: if `True`, add to any existing expressions.
    -3020                Otherwise, this resets the expressions.
    -3021            dialect: the dialect used to parse the input expressions.
    -3022            copy: if `False`, modify this expression instance in-place.
    -3023            opts: other options to use to parse the input expressions.
    +            
    3014    def lateral(
    +3015        self,
    +3016        *expressions: t.Optional[ExpOrStr],
    +3017        append: bool = True,
    +3018        dialect: DialectType = None,
    +3019        copy: bool = True,
    +3020        **opts,
    +3021    ) -> Select:
    +3022        """
    +3023        Append to or set the LATERAL expressions.
     3024
    -3025        Returns:
    -3026            The modified Select expression.
    -3027        """
    -3028        return _apply_list_builder(
    -3029            *expressions,
    -3030            instance=self,
    -3031            arg="laterals",
    -3032            append=append,
    -3033            into=Lateral,
    -3034            prefix="LATERAL VIEW",
    -3035            dialect=dialect,
    -3036            copy=copy,
    -3037            **opts,
    -3038        )
    +3025        Example:
    +3026            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
    +3027            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
    +3028
    +3029        Args:
    +3030            *expressions: the SQL code strings to parse.
    +3031                If an `Expression` instance is passed, it will be used as-is.
    +3032            append: if `True`, add to any existing expressions.
    +3033                Otherwise, this resets the expressions.
    +3034            dialect: the dialect used to parse the input expressions.
    +3035            copy: if `False`, modify this expression instance in-place.
    +3036            opts: other options to use to parse the input expressions.
    +3037
    +3038        Returns:
    +3039            The modified Select expression.
    +3040        """
    +3041        return _apply_list_builder(
    +3042            *expressions,
    +3043            instance=self,
    +3044            arg="laterals",
    +3045            append=append,
    +3046            into=Lateral,
    +3047            prefix="LATERAL VIEW",
    +3048            dialect=dialect,
    +3049            copy=copy,
    +3050            **opts,
    +3051        )
     
    @@ -39914,103 +40282,103 @@ Otherwise, this resets the expressions.
    -
    3040    def join(
    -3041        self,
    -3042        expression: ExpOrStr,
    -3043        on: t.Optional[ExpOrStr] = None,
    -3044        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
    -3045        append: bool = True,
    -3046        join_type: t.Optional[str] = None,
    -3047        join_alias: t.Optional[Identifier | str] = None,
    -3048        dialect: DialectType = None,
    -3049        copy: bool = True,
    -3050        **opts,
    -3051    ) -> Select:
    -3052        """
    -3053        Append to or set the JOIN expressions.
    -3054
    -3055        Example:
    -3056            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
    -3057            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
    -3058
    -3059            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
    -3060            'SELECT 1 FROM a JOIN b USING (x, y, z)'
    -3061
    -3062            Use `join_type` to change the type of join:
    -3063
    -3064            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
    -3065            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
    -3066
    -3067        Args:
    -3068            expression: the SQL code string to parse.
    -3069                If an `Expression` instance is passed, it will be used as-is.
    -3070            on: optionally specify the join "on" criteria as a SQL string.
    -3071                If an `Expression` instance is passed, it will be used as-is.
    -3072            using: optionally specify the join "using" criteria as a SQL string.
    -3073                If an `Expression` instance is passed, it will be used as-is.
    -3074            append: if `True`, add to any existing expressions.
    -3075                Otherwise, this resets the expressions.
    -3076            join_type: if set, alter the parsed join type.
    -3077            join_alias: an optional alias for the joined source.
    -3078            dialect: the dialect used to parse the input expressions.
    -3079            copy: if `False`, modify this expression instance in-place.
    -3080            opts: other options to use to parse the input expressions.
    -3081
    -3082        Returns:
    -3083            Select: the modified expression.
    -3084        """
    -3085        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
    -3086
    -3087        try:
    -3088            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
    -3089        except ParseError:
    -3090            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
    -3091
    -3092        join = expression if isinstance(expression, Join) else Join(this=expression)
    -3093
    -3094        if isinstance(join.this, Select):
    -3095            join.this.replace(join.this.subquery())
    -3096
    -3097        if join_type:
    -3098            method: t.Optional[Token]
    -3099            side: t.Optional[Token]
    -3100            kind: t.Optional[Token]
    -3101
    -3102            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
    -3103
    -3104            if method:
    -3105                join.set("method", method.text)
    -3106            if side:
    -3107                join.set("side", side.text)
    -3108            if kind:
    -3109                join.set("kind", kind.text)
    -3110
    -3111        if on:
    -3112            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
    -3113            join.set("on", on)
    +            
    3053    def join(
    +3054        self,
    +3055        expression: ExpOrStr,
    +3056        on: t.Optional[ExpOrStr] = None,
    +3057        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
    +3058        append: bool = True,
    +3059        join_type: t.Optional[str] = None,
    +3060        join_alias: t.Optional[Identifier | str] = None,
    +3061        dialect: DialectType = None,
    +3062        copy: bool = True,
    +3063        **opts,
    +3064    ) -> Select:
    +3065        """
    +3066        Append to or set the JOIN expressions.
    +3067
    +3068        Example:
    +3069            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
    +3070            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
    +3071
    +3072            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
    +3073            'SELECT 1 FROM a JOIN b USING (x, y, z)'
    +3074
    +3075            Use `join_type` to change the type of join:
    +3076
    +3077            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
    +3078            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
    +3079
    +3080        Args:
    +3081            expression: the SQL code string to parse.
    +3082                If an `Expression` instance is passed, it will be used as-is.
    +3083            on: optionally specify the join "on" criteria as a SQL string.
    +3084                If an `Expression` instance is passed, it will be used as-is.
    +3085            using: optionally specify the join "using" criteria as a SQL string.
    +3086                If an `Expression` instance is passed, it will be used as-is.
    +3087            append: if `True`, add to any existing expressions.
    +3088                Otherwise, this resets the expressions.
    +3089            join_type: if set, alter the parsed join type.
    +3090            join_alias: an optional alias for the joined source.
    +3091            dialect: the dialect used to parse the input expressions.
    +3092            copy: if `False`, modify this expression instance in-place.
    +3093            opts: other options to use to parse the input expressions.
    +3094
    +3095        Returns:
    +3096            Select: the modified expression.
    +3097        """
    +3098        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
    +3099
    +3100        try:
    +3101            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
    +3102        except ParseError:
    +3103            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
    +3104
    +3105        join = expression if isinstance(expression, Join) else Join(this=expression)
    +3106
    +3107        if isinstance(join.this, Select):
    +3108            join.this.replace(join.this.subquery())
    +3109
    +3110        if join_type:
    +3111            method: t.Optional[Token]
    +3112            side: t.Optional[Token]
    +3113            kind: t.Optional[Token]
     3114
    -3115        if using:
    -3116            join = _apply_list_builder(
    -3117                *ensure_list(using),
    -3118                instance=join,
    -3119                arg="using",
    -3120                append=append,
    -3121                copy=copy,
    -3122                into=Identifier,
    -3123                **opts,
    -3124            )
    -3125
    -3126        if join_alias:
    -3127            join.set("this", alias_(join.this, join_alias, table=True))
    -3128
    -3129        return _apply_list_builder(
    -3130            join,
    -3131            instance=self,
    -3132            arg="joins",
    -3133            append=append,
    -3134            copy=copy,
    -3135            **opts,
    -3136        )
    +3115            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
    +3116
    +3117            if method:
    +3118                join.set("method", method.text)
    +3119            if side:
    +3120                join.set("side", side.text)
    +3121            if kind:
    +3122                join.set("kind", kind.text)
    +3123
    +3124        if on:
    +3125            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
    +3126            join.set("on", on)
    +3127
    +3128        if using:
    +3129            join = _apply_list_builder(
    +3130                *ensure_list(using),
    +3131                instance=join,
    +3132                arg="using",
    +3133                append=append,
    +3134                copy=copy,
    +3135                into=Identifier,
    +3136                **opts,
    +3137            )
    +3138
    +3139        if join_alias:
    +3140            join.set("this", alias_(join.this, join_alias, table=True))
    +3141
    +3142        return _apply_list_builder(
    +3143            join,
    +3144            instance=self,
    +3145            arg="joins",
    +3146            append=append,
    +3147            copy=copy,
    +3148            **opts,
    +3149        )
     
    @@ -40078,44 +40446,44 @@ Otherwise, this resets the expressions.
    -
    3138    def where(
    -3139        self,
    -3140        *expressions: t.Optional[ExpOrStr],
    -3141        append: bool = True,
    -3142        dialect: DialectType = None,
    -3143        copy: bool = True,
    -3144        **opts,
    -3145    ) -> Select:
    -3146        """
    -3147        Append to or set the WHERE expressions.
    -3148
    -3149        Example:
    -3150            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
    -3151            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
    -3152
    -3153        Args:
    -3154            *expressions: the SQL code strings to parse.
    -3155                If an `Expression` instance is passed, it will be used as-is.
    -3156                Multiple expressions are combined with an AND operator.
    -3157            append: if `True`, AND the new expressions to any existing expression.
    -3158                Otherwise, this resets the expression.
    -3159            dialect: the dialect used to parse the input expressions.
    -3160            copy: if `False`, modify this expression instance in-place.
    -3161            opts: other options to use to parse the input expressions.
    -3162
    -3163        Returns:
    -3164            Select: the modified expression.
    -3165        """
    -3166        return _apply_conjunction_builder(
    -3167            *expressions,
    -3168            instance=self,
    -3169            arg="where",
    -3170            append=append,
    -3171            into=Where,
    -3172            dialect=dialect,
    -3173            copy=copy,
    -3174            **opts,
    -3175        )
    +            
    3151    def where(
    +3152        self,
    +3153        *expressions: t.Optional[ExpOrStr],
    +3154        append: bool = True,
    +3155        dialect: DialectType = None,
    +3156        copy: bool = True,
    +3157        **opts,
    +3158    ) -> Select:
    +3159        """
    +3160        Append to or set the WHERE expressions.
    +3161
    +3162        Example:
    +3163            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
    +3164            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
    +3165
    +3166        Args:
    +3167            *expressions: the SQL code strings to parse.
    +3168                If an `Expression` instance is passed, it will be used as-is.
    +3169                Multiple expressions are combined with an AND operator.
    +3170            append: if `True`, AND the new expressions to any existing expression.
    +3171                Otherwise, this resets the expression.
    +3172            dialect: the dialect used to parse the input expressions.
    +3173            copy: if `False`, modify this expression instance in-place.
    +3174            opts: other options to use to parse the input expressions.
    +3175
    +3176        Returns:
    +3177            Select: the modified expression.
    +3178        """
    +3179        return _apply_conjunction_builder(
    +3180            *expressions,
    +3181            instance=self,
    +3182            arg="where",
    +3183            append=append,
    +3184            into=Where,
    +3185            dialect=dialect,
    +3186            copy=copy,
    +3187            **opts,
    +3188        )
     
    @@ -40164,44 +40532,44 @@ Otherwise, this resets the expression.
    -
    3177    def having(
    -3178        self,
    -3179        *expressions: t.Optional[ExpOrStr],
    -3180        append: bool = True,
    -3181        dialect: DialectType = None,
    -3182        copy: bool = True,
    -3183        **opts,
    -3184    ) -> Select:
    -3185        """
    -3186        Append to or set the HAVING expressions.
    -3187
    -3188        Example:
    -3189            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
    -3190            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
    -3191
    -3192        Args:
    -3193            *expressions: the SQL code strings to parse.
    -3194                If an `Expression` instance is passed, it will be used as-is.
    -3195                Multiple expressions are combined with an AND operator.
    -3196            append: if `True`, AND the new expressions to any existing expression.
    -3197                Otherwise, this resets the expression.
    -3198            dialect: the dialect used to parse the input expressions.
    -3199            copy: if `False`, modify this expression instance in-place.
    -3200            opts: other options to use to parse the input expressions.
    -3201
    -3202        Returns:
    -3203            The modified Select expression.
    -3204        """
    -3205        return _apply_conjunction_builder(
    -3206            *expressions,
    -3207            instance=self,
    -3208            arg="having",
    -3209            append=append,
    -3210            into=Having,
    -3211            dialect=dialect,
    -3212            copy=copy,
    -3213            **opts,
    -3214        )
    +            
    3190    def having(
    +3191        self,
    +3192        *expressions: t.Optional[ExpOrStr],
    +3193        append: bool = True,
    +3194        dialect: DialectType = None,
    +3195        copy: bool = True,
    +3196        **opts,
    +3197    ) -> Select:
    +3198        """
    +3199        Append to or set the HAVING expressions.
    +3200
    +3201        Example:
    +3202            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
    +3203            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
    +3204
    +3205        Args:
    +3206            *expressions: the SQL code strings to parse.
    +3207                If an `Expression` instance is passed, it will be used as-is.
    +3208                Multiple expressions are combined with an AND operator.
    +3209            append: if `True`, AND the new expressions to any existing expression.
    +3210                Otherwise, this resets the expression.
    +3211            dialect: the dialect used to parse the input expressions.
    +3212            copy: if `False`, modify this expression instance in-place.
    +3213            opts: other options to use to parse the input expressions.
    +3214
    +3215        Returns:
    +3216            The modified Select expression.
    +3217        """
    +3218        return _apply_conjunction_builder(
    +3219            *expressions,
    +3220            instance=self,
    +3221            arg="having",
    +3222            append=append,
    +3223            into=Having,
    +3224            dialect=dialect,
    +3225            copy=copy,
    +3226            **opts,
    +3227        )
     
    @@ -40250,24 +40618,24 @@ Otherwise, this resets the expression.
    -
    3216    def window(
    -3217        self,
    -3218        *expressions: t.Optional[ExpOrStr],
    -3219        append: bool = True,
    -3220        dialect: DialectType = None,
    -3221        copy: bool = True,
    -3222        **opts,
    -3223    ) -> Select:
    -3224        return _apply_list_builder(
    -3225            *expressions,
    -3226            instance=self,
    -3227            arg="windows",
    -3228            append=append,
    -3229            into=Window,
    -3230            dialect=dialect,
    -3231            copy=copy,
    -3232            **opts,
    -3233        )
    +            
    3229    def window(
    +3230        self,
    +3231        *expressions: t.Optional[ExpOrStr],
    +3232        append: bool = True,
    +3233        dialect: DialectType = None,
    +3234        copy: bool = True,
    +3235        **opts,
    +3236    ) -> Select:
    +3237        return _apply_list_builder(
    +3238            *expressions,
    +3239            instance=self,
    +3240            arg="windows",
    +3241            append=append,
    +3242            into=Window,
    +3243            dialect=dialect,
    +3244            copy=copy,
    +3245            **opts,
    +3246        )
     
    @@ -40285,24 +40653,24 @@ Otherwise, this resets the expression.
    -
    3235    def qualify(
    -3236        self,
    -3237        *expressions: t.Optional[ExpOrStr],
    -3238        append: bool = True,
    -3239        dialect: DialectType = None,
    -3240        copy: bool = True,
    -3241        **opts,
    -3242    ) -> Select:
    -3243        return _apply_conjunction_builder(
    -3244            *expressions,
    -3245            instance=self,
    -3246            arg="qualify",
    -3247            append=append,
    -3248            into=Qualify,
    -3249            dialect=dialect,
    -3250            copy=copy,
    -3251            **opts,
    -3252        )
    +            
    3248    def qualify(
    +3249        self,
    +3250        *expressions: t.Optional[ExpOrStr],
    +3251        append: bool = True,
    +3252        dialect: DialectType = None,
    +3253        copy: bool = True,
    +3254        **opts,
    +3255    ) -> Select:
    +3256        return _apply_conjunction_builder(
    +3257            *expressions,
    +3258            instance=self,
    +3259            arg="qualify",
    +3260            append=append,
    +3261            into=Qualify,
    +3262            dialect=dialect,
    +3263            copy=copy,
    +3264            **opts,
    +3265        )
     
    @@ -40320,28 +40688,28 @@ Otherwise, this resets the expression.
    -
    3254    def distinct(
    -3255        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
    -3256    ) -> Select:
    -3257        """
    -3258        Set the OFFSET expression.
    -3259
    -3260        Example:
    -3261            >>> Select().from_("tbl").select("x").distinct().sql()
    -3262            'SELECT DISTINCT x FROM tbl'
    -3263
    -3264        Args:
    -3265            ons: the expressions to distinct on
    -3266            distinct: whether the Select should be distinct
    -3267            copy: if `False`, modify this expression instance in-place.
    -3268
    -3269        Returns:
    -3270            Select: the modified expression.
    -3271        """
    -3272        instance = maybe_copy(self, copy)
    -3273        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
    -3274        instance.set("distinct", Distinct(on=on) if distinct else None)
    -3275        return instance
    +            
    3267    def distinct(
    +3268        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
    +3269    ) -> Select:
    +3270        """
    +3271        Set the OFFSET expression.
    +3272
    +3273        Example:
    +3274            >>> Select().from_("tbl").select("x").distinct().sql()
    +3275            'SELECT DISTINCT x FROM tbl'
    +3276
    +3277        Args:
    +3278            ons: the expressions to distinct on
    +3279            distinct: whether the Select should be distinct
    +3280            copy: if `False`, modify this expression instance in-place.
    +3281
    +3282        Returns:
    +3283            Select: the modified expression.
    +3284        """
    +3285        instance = maybe_copy(self, copy)
    +3286        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
    +3287        instance.set("distinct", Distinct(on=on) if distinct else None)
    +3288        return instance
     
    @@ -40385,49 +40753,49 @@ Otherwise, this resets the expression.
    -
    3277    def ctas(
    -3278        self,
    -3279        table: ExpOrStr,
    -3280        properties: t.Optional[t.Dict] = None,
    -3281        dialect: DialectType = None,
    -3282        copy: bool = True,
    -3283        **opts,
    -3284    ) -> Create:
    -3285        """
    -3286        Convert this expression to a CREATE TABLE AS statement.
    -3287
    -3288        Example:
    -3289            >>> Select().select("*").from_("tbl").ctas("x").sql()
    -3290            'CREATE TABLE x AS SELECT * FROM tbl'
    -3291
    -3292        Args:
    -3293            table: the SQL code string to parse as the table name.
    -3294                If another `Expression` instance is passed, it will be used as-is.
    -3295            properties: an optional mapping of table properties
    -3296            dialect: the dialect used to parse the input table.
    -3297            copy: if `False`, modify this expression instance in-place.
    -3298            opts: other options to use to parse the input table.
    -3299
    -3300        Returns:
    -3301            The new Create expression.
    -3302        """
    -3303        instance = maybe_copy(self, copy)
    -3304        table_expression = maybe_parse(
    -3305            table,
    -3306            into=Table,
    -3307            dialect=dialect,
    -3308            **opts,
    -3309        )
    -3310        properties_expression = None
    -3311        if properties:
    -3312            properties_expression = Properties.from_dict(properties)
    -3313
    -3314        return Create(
    -3315            this=table_expression,
    -3316            kind="table",
    -3317            expression=instance,
    -3318            properties=properties_expression,
    -3319        )
    +            
    3290    def ctas(
    +3291        self,
    +3292        table: ExpOrStr,
    +3293        properties: t.Optional[t.Dict] = None,
    +3294        dialect: DialectType = None,
    +3295        copy: bool = True,
    +3296        **opts,
    +3297    ) -> Create:
    +3298        """
    +3299        Convert this expression to a CREATE TABLE AS statement.
    +3300
    +3301        Example:
    +3302            >>> Select().select("*").from_("tbl").ctas("x").sql()
    +3303            'CREATE TABLE x AS SELECT * FROM tbl'
    +3304
    +3305        Args:
    +3306            table: the SQL code string to parse as the table name.
    +3307                If another `Expression` instance is passed, it will be used as-is.
    +3308            properties: an optional mapping of table properties
    +3309            dialect: the dialect used to parse the input table.
    +3310            copy: if `False`, modify this expression instance in-place.
    +3311            opts: other options to use to parse the input table.
    +3312
    +3313        Returns:
    +3314            The new Create expression.
    +3315        """
    +3316        instance = maybe_copy(self, copy)
    +3317        table_expression = maybe_parse(
    +3318            table,
    +3319            into=Table,
    +3320            dialect=dialect,
    +3321            **opts,
    +3322        )
    +3323        properties_expression = None
    +3324        if properties:
    +3325            properties_expression = Properties.from_dict(properties)
    +3326
    +3327        return Create(
    +3328            this=table_expression,
    +3329            kind="table",
    +3330            expression=instance,
    +3331            properties=properties_expression,
    +3332        )
     
    @@ -40474,28 +40842,28 @@ If another Expression instance is passed,
    -
    3321    def lock(self, update: bool = True, copy: bool = True) -> Select:
    -3322        """
    -3323        Set the locking read mode for this expression.
    -3324
    -3325        Examples:
    -3326            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
    -3327            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
    -3328
    -3329            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
    -3330            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
    -3331
    -3332        Args:
    -3333            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
    -3334            copy: if `False`, modify this expression instance in-place.
    -3335
    -3336        Returns:
    -3337            The modified expression.
    -3338        """
    -3339        inst = maybe_copy(self, copy)
    -3340        inst.set("locks", [Lock(update=update)])
    +            
    3334    def lock(self, update: bool = True, copy: bool = True) -> Select:
    +3335        """
    +3336        Set the locking read mode for this expression.
    +3337
    +3338        Examples:
    +3339            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
    +3340            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
     3341
    -3342        return inst
    +3342            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
    +3343            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
    +3344
    +3345        Args:
    +3346            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
    +3347            copy: if `False`, modify this expression instance in-place.
    +3348
    +3349        Returns:
    +3350            The modified expression.
    +3351        """
    +3352        inst = maybe_copy(self, copy)
    +3353        inst.set("locks", [Lock(update=update)])
    +3354
    +3355        return inst
     
    @@ -40544,29 +40912,29 @@ If another Expression instance is passed,
    -
    3344    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
    -3345        """
    -3346        Set hints for this expression.
    -3347
    -3348        Examples:
    -3349            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
    -3350            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
    -3351
    -3352        Args:
    -3353            hints: The SQL code strings to parse as the hints.
    -3354                If an `Expression` instance is passed, it will be used as-is.
    -3355            dialect: The dialect used to parse the hints.
    -3356            copy: If `False`, modify this expression instance in-place.
    -3357
    -3358        Returns:
    -3359            The modified expression.
    -3360        """
    -3361        inst = maybe_copy(self, copy)
    -3362        inst.set(
    -3363            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
    -3364        )
    -3365
    -3366        return inst
    +            
    3357    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
    +3358        """
    +3359        Set hints for this expression.
    +3360
    +3361        Examples:
    +3362            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
    +3363            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
    +3364
    +3365        Args:
    +3366            hints: The SQL code strings to parse as the hints.
    +3367                If an `Expression` instance is passed, it will be used as-is.
    +3368            dialect: The dialect used to parse the hints.
    +3369            copy: If `False`, modify this expression instance in-place.
    +3370
    +3371        Returns:
    +3372            The modified expression.
    +3373        """
    +3374        inst = maybe_copy(self, copy)
    +3375        inst.set(
    +3376            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
    +3377        )
    +3378
    +3379        return inst
     
    @@ -40738,47 +41106,47 @@ If an Expression instance is passed, it w
    -
    3381class Subquery(DerivedTable, Unionable):
    -3382    arg_types = {
    -3383        "this": True,
    -3384        "alias": False,
    -3385        "with": False,
    -3386        **QUERY_MODIFIERS,
    -3387    }
    -3388
    -3389    def unnest(self):
    -3390        """
    -3391        Returns the first non subquery.
    -3392        """
    -3393        expression = self
    -3394        while isinstance(expression, Subquery):
    -3395            expression = expression.this
    -3396        return expression
    -3397
    -3398    def unwrap(self) -> Subquery:
    -3399        expression = self
    -3400        while expression.same_parent and expression.is_wrapper:
    -3401            expression = t.cast(Subquery, expression.parent)
    -3402        return expression
    -3403
    -3404    @property
    -3405    def is_wrapper(self) -> bool:
    -3406        """
    -3407        Whether this Subquery acts as a simple wrapper around another expression.
    -3408
    -3409        SELECT * FROM (((SELECT * FROM t)))
    -3410                      ^
    -3411                      This corresponds to a "wrapper" Subquery node
    -3412        """
    -3413        return all(v is None for k, v in self.args.items() if k != "this")
    -3414
    -3415    @property
    -3416    def is_star(self) -> bool:
    -3417        return self.this.is_star
    -3418
    -3419    @property
    -3420    def output_name(self) -> str:
    -3421        return self.alias
    +            
    3394class Subquery(DerivedTable, Unionable):
    +3395    arg_types = {
    +3396        "this": True,
    +3397        "alias": False,
    +3398        "with": False,
    +3399        **QUERY_MODIFIERS,
    +3400    }
    +3401
    +3402    def unnest(self):
    +3403        """
    +3404        Returns the first non subquery.
    +3405        """
    +3406        expression = self
    +3407        while isinstance(expression, Subquery):
    +3408            expression = expression.this
    +3409        return expression
    +3410
    +3411    def unwrap(self) -> Subquery:
    +3412        expression = self
    +3413        while expression.same_parent and expression.is_wrapper:
    +3414            expression = t.cast(Subquery, expression.parent)
    +3415        return expression
    +3416
    +3417    @property
    +3418    def is_wrapper(self) -> bool:
    +3419        """
    +3420        Whether this Subquery acts as a simple wrapper around another expression.
    +3421
    +3422        SELECT * FROM (((SELECT * FROM t)))
    +3423                      ^
    +3424                      This corresponds to a "wrapper" Subquery node
    +3425        """
    +3426        return all(v is None for k, v in self.args.items() if k != "this")
    +3427
    +3428    @property
    +3429    def is_star(self) -> bool:
    +3430        return self.this.is_star
    +3431
    +3432    @property
    +3433    def output_name(self) -> str:
    +3434        return self.alias
     
    @@ -40808,14 +41176,14 @@ If an Expression instance is passed, it w
    -
    3389    def unnest(self):
    -3390        """
    -3391        Returns the first non subquery.
    -3392        """
    -3393        expression = self
    -3394        while isinstance(expression, Subquery):
    -3395            expression = expression.this
    -3396        return expression
    +            
    3402    def unnest(self):
    +3403        """
    +3404        Returns the first non subquery.
    +3405        """
    +3406        expression = self
    +3407        while isinstance(expression, Subquery):
    +3408            expression = expression.this
    +3409        return expression
     
    @@ -40835,11 +41203,11 @@ If an Expression instance is passed, it w
    -
    3398    def unwrap(self) -> Subquery:
    -3399        expression = self
    -3400        while expression.same_parent and expression.is_wrapper:
    -3401            expression = t.cast(Subquery, expression.parent)
    -3402        return expression
    +            
    3411    def unwrap(self) -> Subquery:
    +3412        expression = self
    +3413        while expression.same_parent and expression.is_wrapper:
    +3414            expression = t.cast(Subquery, expression.parent)
    +3415        return expression
     
    @@ -41006,20 +41374,20 @@ If an Expression instance is passed, it w
    -
    3424class TableSample(Expression):
    -3425    arg_types = {
    -3426        "this": False,
    -3427        "expressions": False,
    -3428        "method": False,
    -3429        "bucket_numerator": False,
    -3430        "bucket_denominator": False,
    -3431        "bucket_field": False,
    -3432        "percent": False,
    -3433        "rows": False,
    -3434        "size": False,
    -3435        "seed": False,
    -3436        "kind": False,
    -3437    }
    +            
    3437class TableSample(Expression):
    +3438    arg_types = {
    +3439        "this": False,
    +3440        "expressions": False,
    +3441        "method": False,
    +3442        "bucket_numerator": False,
    +3443        "bucket_denominator": False,
    +3444        "bucket_field": False,
    +3445        "percent": False,
    +3446        "rows": False,
    +3447        "size": False,
    +3448        "seed": False,
    +3449        "kind": False,
    +3450    }
     
    @@ -41130,14 +41498,14 @@ If an Expression instance is passed, it w
    -
    3440class Tag(Expression):
    -3441    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
    -3442
    -3443    arg_types = {
    -3444        "this": False,
    -3445        "prefix": False,
    -3446        "postfix": False,
    -3447    }
    +            
    3453class Tag(Expression):
    +3454    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
    +3455
    +3456    arg_types = {
    +3457        "this": False,
    +3458        "prefix": False,
    +3459        "postfix": False,
    +3460    }
     
    @@ -41249,18 +41617,18 @@ If an Expression instance is passed, it w
    -
    3452class Pivot(Expression):
    -3453    arg_types = {
    -3454        "this": False,
    -3455        "alias": False,
    -3456        "expressions": False,
    -3457        "field": False,
    -3458        "unpivot": False,
    -3459        "using": False,
    -3460        "group": False,
    -3461        "columns": False,
    -3462        "include_nulls": False,
    -3463    }
    +            
    3465class Pivot(Expression):
    +3466    arg_types = {
    +3467        "this": False,
    +3468        "alias": False,
    +3469        "expressions": False,
    +3470        "field": False,
    +3471        "unpivot": False,
    +3472        "using": False,
    +3473        "group": False,
    +3474        "columns": False,
    +3475        "include_nulls": False,
    +3476    }
     
    @@ -41371,16 +41739,16 @@ If an Expression instance is passed, it w
    -
    3466class Window(Condition):
    -3467    arg_types = {
    -3468        "this": True,
    -3469        "partition_by": False,
    -3470        "order": False,
    -3471        "spec": False,
    -3472        "alias": False,
    -3473        "over": False,
    -3474        "first": False,
    -3475    }
    +            
    3479class Window(Condition):
    +3480    arg_types = {
    +3481        "this": True,
    +3482        "partition_by": False,
    +3483        "order": False,
    +3484        "spec": False,
    +3485        "alias": False,
    +3486        "over": False,
    +3487        "first": False,
    +3488    }
     
    @@ -41491,14 +41859,14 @@ If an Expression instance is passed, it w
    -
    3478class WindowSpec(Expression):
    -3479    arg_types = {
    -3480        "kind": False,
    -3481        "start": False,
    -3482        "start_side": False,
    -3483        "end": False,
    -3484        "end_side": False,
    -3485    }
    +            
    3491class WindowSpec(Expression):
    +3492    arg_types = {
    +3493        "kind": False,
    +3494        "start": False,
    +3495        "start_side": False,
    +3496        "end": False,
    +3497        "end_side": False,
    +3498    }
     
    @@ -41608,8 +41976,8 @@ If an Expression instance is passed, it w
    -
    3488class Where(Expression):
    -3489    pass
    +            
    3501class Where(Expression):
    +3502    pass
     
    @@ -41708,16 +42076,16 @@ If an Expression instance is passed, it w
    -
    3492class Star(Expression):
    -3493    arg_types = {"except": False, "replace": False}
    -3494
    -3495    @property
    -3496    def name(self) -> str:
    -3497        return "*"
    -3498
    -3499    @property
    -3500    def output_name(self) -> str:
    -3501        return self.name
    +            
    3505class Star(Expression):
    +3506    arg_types = {"except": False, "replace": False}
    +3507
    +3508    @property
    +3509    def name(self) -> str:
    +3510        return "*"
    +3511
    +3512    @property
    +3513    def output_name(self) -> str:
    +3514        return self.name
     
    @@ -41866,8 +42234,8 @@ If an Expression instance is passed, it w
    -
    3504class Parameter(Condition):
    -3505    arg_types = {"this": True, "wrapped": False}
    +            
    3517class Parameter(Condition):
    +3518    arg_types = {"this": True, "expression": False}
     
    @@ -41876,7 +42244,7 @@ If an Expression instance is passed, it w
    arg_types = -{'this': True, 'wrapped': False} +{'this': True, 'expression': False}
    @@ -41977,8 +42345,8 @@ If an Expression instance is passed, it w
    -
    3508class SessionParameter(Condition):
    -3509    arg_types = {"this": True, "kind": False}
    +            
    3521class SessionParameter(Condition):
    +3522    arg_types = {"this": True, "kind": False}
     
    @@ -42088,8 +42456,8 @@ If an Expression instance is passed, it w
    -
    3512class Placeholder(Condition):
    -3513    arg_types = {"this": False, "kind": False}
    +            
    3525class Placeholder(Condition):
    +3526    arg_types = {"this": False, "kind": False}
     
    @@ -42199,12 +42567,12 @@ If an Expression instance is passed, it w
    -
    3516class Null(Condition):
    -3517    arg_types: t.Dict[str, t.Any] = {}
    -3518
    -3519    @property
    -3520    def name(self) -> str:
    -3521        return "NULL"
    +            
    3529class Null(Condition):
    +3530    arg_types: t.Dict[str, t.Any] = {}
    +3531
    +3532    @property
    +3533    def name(self) -> str:
    +3534        return "NULL"
     
    @@ -42324,8 +42692,8 @@ If an Expression instance is passed, it w
    -
    3524class Boolean(Condition):
    -3525    pass
    +            
    3537class Boolean(Condition):
    +3538    pass
     
    @@ -42424,8 +42792,8 @@ If an Expression instance is passed, it w
    -
    3528class DataTypeParam(Expression):
    -3529    arg_types = {"this": True, "expression": False}
    +            
    3541class DataTypeParam(Expression):
    +3542    arg_types = {"this": True, "expression": False}
     
    @@ -42535,224 +42903,224 @@ If an Expression instance is passed, it w
    -
    3532class DataType(Expression):
    -3533    arg_types = {
    -3534        "this": True,
    -3535        "expressions": False,
    -3536        "nested": False,
    -3537        "values": False,
    -3538        "prefix": False,
    -3539        "kind": False,
    -3540    }
    -3541
    -3542    class Type(AutoName):
    -3543        ARRAY = auto()
    -3544        BIGDECIMAL = auto()
    -3545        BIGINT = auto()
    -3546        BIGSERIAL = auto()
    -3547        BINARY = auto()
    -3548        BIT = auto()
    -3549        BOOLEAN = auto()
    -3550        CHAR = auto()
    -3551        DATE = auto()
    -3552        DATEMULTIRANGE = auto()
    -3553        DATERANGE = auto()
    -3554        DATETIME = auto()
    -3555        DATETIME64 = auto()
    -3556        DECIMAL = auto()
    -3557        DOUBLE = auto()
    -3558        ENUM = auto()
    -3559        ENUM8 = auto()
    -3560        ENUM16 = auto()
    -3561        FIXEDSTRING = auto()
    -3562        FLOAT = auto()
    -3563        GEOGRAPHY = auto()
    -3564        GEOMETRY = auto()
    -3565        HLLSKETCH = auto()
    -3566        HSTORE = auto()
    -3567        IMAGE = auto()
    -3568        INET = auto()
    -3569        INT = auto()
    -3570        INT128 = auto()
    -3571        INT256 = auto()
    -3572        INT4MULTIRANGE = auto()
    -3573        INT4RANGE = auto()
    -3574        INT8MULTIRANGE = auto()
    -3575        INT8RANGE = auto()
    -3576        INTERVAL = auto()
    -3577        IPADDRESS = auto()
    -3578        IPPREFIX = auto()
    -3579        JSON = auto()
    -3580        JSONB = auto()
    -3581        LONGBLOB = auto()
    -3582        LONGTEXT = auto()
    -3583        LOWCARDINALITY = auto()
    -3584        MAP = auto()
    -3585        MEDIUMBLOB = auto()
    -3586        MEDIUMINT = auto()
    -3587        MEDIUMTEXT = auto()
    -3588        MONEY = auto()
    -3589        NCHAR = auto()
    -3590        NESTED = auto()
    -3591        NULL = auto()
    -3592        NULLABLE = auto()
    -3593        NUMMULTIRANGE = auto()
    -3594        NUMRANGE = auto()
    -3595        NVARCHAR = auto()
    -3596        OBJECT = auto()
    -3597        ROWVERSION = auto()
    -3598        SERIAL = auto()
    -3599        SET = auto()
    -3600        SMALLINT = auto()
    -3601        SMALLMONEY = auto()
    -3602        SMALLSERIAL = auto()
    -3603        STRUCT = auto()
    -3604        SUPER = auto()
    -3605        TEXT = auto()
    -3606        TINYBLOB = auto()
    -3607        TINYTEXT = auto()
    -3608        TIME = auto()
    -3609        TIMETZ = auto()
    -3610        TIMESTAMP = auto()
    -3611        TIMESTAMPLTZ = auto()
    -3612        TIMESTAMPTZ = auto()
    -3613        TIMESTAMP_S = auto()
    -3614        TIMESTAMP_MS = auto()
    -3615        TIMESTAMP_NS = auto()
    -3616        TINYINT = auto()
    -3617        TSMULTIRANGE = auto()
    -3618        TSRANGE = auto()
    -3619        TSTZMULTIRANGE = auto()
    -3620        TSTZRANGE = auto()
    -3621        UBIGINT = auto()
    -3622        UINT = auto()
    -3623        UINT128 = auto()
    -3624        UINT256 = auto()
    -3625        UMEDIUMINT = auto()
    -3626        UDECIMAL = auto()
    -3627        UNIQUEIDENTIFIER = auto()
    -3628        UNKNOWN = auto()  # Sentinel value, useful for type annotation
    -3629        USERDEFINED = "USER-DEFINED"
    -3630        USMALLINT = auto()
    -3631        UTINYINT = auto()
    -3632        UUID = auto()
    -3633        VARBINARY = auto()
    -3634        VARCHAR = auto()
    -3635        VARIANT = auto()
    -3636        XML = auto()
    -3637        YEAR = auto()
    -3638
    -3639    TEXT_TYPES = {
    -3640        Type.CHAR,
    -3641        Type.NCHAR,
    -3642        Type.VARCHAR,
    -3643        Type.NVARCHAR,
    -3644        Type.TEXT,
    -3645    }
    -3646
    -3647    INTEGER_TYPES = {
    -3648        Type.INT,
    -3649        Type.TINYINT,
    -3650        Type.SMALLINT,
    -3651        Type.BIGINT,
    -3652        Type.INT128,
    -3653        Type.INT256,
    -3654    }
    -3655
    -3656    FLOAT_TYPES = {
    -3657        Type.FLOAT,
    -3658        Type.DOUBLE,
    -3659    }
    -3660
    -3661    NUMERIC_TYPES = {
    -3662        *INTEGER_TYPES,
    -3663        *FLOAT_TYPES,
    -3664    }
    -3665
    -3666    TEMPORAL_TYPES = {
    -3667        Type.TIME,
    -3668        Type.TIMETZ,
    -3669        Type.TIMESTAMP,
    -3670        Type.TIMESTAMPTZ,
    -3671        Type.TIMESTAMPLTZ,
    -3672        Type.TIMESTAMP_S,
    -3673        Type.TIMESTAMP_MS,
    -3674        Type.TIMESTAMP_NS,
    -3675        Type.DATE,
    -3676        Type.DATETIME,
    -3677        Type.DATETIME64,
    -3678    }
    -3679
    -3680    @classmethod
    -3681    def build(
    -3682        cls,
    -3683        dtype: str | DataType | DataType.Type,
    -3684        dialect: DialectType = None,
    -3685        udt: bool = False,
    -3686        **kwargs,
    -3687    ) -> DataType:
    -3688        """
    -3689        Constructs a DataType object.
    -3690
    -3691        Args:
    -3692            dtype: the data type of interest.
    -3693            dialect: the dialect to use for parsing `dtype`, in case it's a string.
    -3694            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
    -3695                DataType, thus creating a user-defined type.
    -3696            kawrgs: additional arguments to pass in the constructor of DataType.
    -3697
    -3698        Returns:
    -3699            The constructed DataType object.
    -3700        """
    -3701        from sqlglot import parse_one
    -3702
    -3703        if isinstance(dtype, str):
    -3704            if dtype.upper() == "UNKNOWN":
    -3705                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
    -3706
    -3707            try:
    -3708                data_type_exp = parse_one(
    -3709                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
    -3710                )
    -3711            except ParseError:
    -3712                if udt:
    -3713                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
    -3714                raise
    -3715        elif isinstance(dtype, DataType.Type):
    -3716            data_type_exp = DataType(this=dtype)
    -3717        elif isinstance(dtype, DataType):
    -3718            return dtype
    -3719        else:
    -3720            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
    -3721
    -3722        return DataType(**{**data_type_exp.args, **kwargs})
    -3723
    -3724    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    -3725        """
    -3726        Checks whether this DataType matches one of the provided data types. Nested types or precision
    -3727        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
    -3728
    -3729        Args:
    -3730            dtypes: the data types to compare this DataType to.
    -3731
    -3732        Returns:
    -3733            True, if and only if there is a type in `dtypes` which is equal to this DataType.
    -3734        """
    -3735        for dtype in dtypes:
    -3736            other = DataType.build(dtype, udt=True)
    -3737
    -3738            if (
    -3739                other.expressions
    -3740                or self.this == DataType.Type.USERDEFINED
    -3741                or other.this == DataType.Type.USERDEFINED
    -3742            ):
    -3743                matches = self == other
    -3744            else:
    -3745                matches = self.this == other.this
    -3746
    -3747            if matches:
    -3748                return True
    -3749        return False
    +            
    3545class DataType(Expression):
    +3546    arg_types = {
    +3547        "this": True,
    +3548        "expressions": False,
    +3549        "nested": False,
    +3550        "values": False,
    +3551        "prefix": False,
    +3552        "kind": False,
    +3553    }
    +3554
    +3555    class Type(AutoName):
    +3556        ARRAY = auto()
    +3557        BIGDECIMAL = auto()
    +3558        BIGINT = auto()
    +3559        BIGSERIAL = auto()
    +3560        BINARY = auto()
    +3561        BIT = auto()
    +3562        BOOLEAN = auto()
    +3563        CHAR = auto()
    +3564        DATE = auto()
    +3565        DATEMULTIRANGE = auto()
    +3566        DATERANGE = auto()
    +3567        DATETIME = auto()
    +3568        DATETIME64 = auto()
    +3569        DECIMAL = auto()
    +3570        DOUBLE = auto()
    +3571        ENUM = auto()
    +3572        ENUM8 = auto()
    +3573        ENUM16 = auto()
    +3574        FIXEDSTRING = auto()
    +3575        FLOAT = auto()
    +3576        GEOGRAPHY = auto()
    +3577        GEOMETRY = auto()
    +3578        HLLSKETCH = auto()
    +3579        HSTORE = auto()
    +3580        IMAGE = auto()
    +3581        INET = auto()
    +3582        INT = auto()
    +3583        INT128 = auto()
    +3584        INT256 = auto()
    +3585        INT4MULTIRANGE = auto()
    +3586        INT4RANGE = auto()
    +3587        INT8MULTIRANGE = auto()
    +3588        INT8RANGE = auto()
    +3589        INTERVAL = auto()
    +3590        IPADDRESS = auto()
    +3591        IPPREFIX = auto()
    +3592        JSON = auto()
    +3593        JSONB = auto()
    +3594        LONGBLOB = auto()
    +3595        LONGTEXT = auto()
    +3596        LOWCARDINALITY = auto()
    +3597        MAP = auto()
    +3598        MEDIUMBLOB = auto()
    +3599        MEDIUMINT = auto()
    +3600        MEDIUMTEXT = auto()
    +3601        MONEY = auto()
    +3602        NCHAR = auto()
    +3603        NESTED = auto()
    +3604        NULL = auto()
    +3605        NULLABLE = auto()
    +3606        NUMMULTIRANGE = auto()
    +3607        NUMRANGE = auto()
    +3608        NVARCHAR = auto()
    +3609        OBJECT = auto()
    +3610        ROWVERSION = auto()
    +3611        SERIAL = auto()
    +3612        SET = auto()
    +3613        SMALLINT = auto()
    +3614        SMALLMONEY = auto()
    +3615        SMALLSERIAL = auto()
    +3616        STRUCT = auto()
    +3617        SUPER = auto()
    +3618        TEXT = auto()
    +3619        TINYBLOB = auto()
    +3620        TINYTEXT = auto()
    +3621        TIME = auto()
    +3622        TIMETZ = auto()
    +3623        TIMESTAMP = auto()
    +3624        TIMESTAMPLTZ = auto()
    +3625        TIMESTAMPTZ = auto()
    +3626        TIMESTAMP_S = auto()
    +3627        TIMESTAMP_MS = auto()
    +3628        TIMESTAMP_NS = auto()
    +3629        TINYINT = auto()
    +3630        TSMULTIRANGE = auto()
    +3631        TSRANGE = auto()
    +3632        TSTZMULTIRANGE = auto()
    +3633        TSTZRANGE = auto()
    +3634        UBIGINT = auto()
    +3635        UINT = auto()
    +3636        UINT128 = auto()
    +3637        UINT256 = auto()
    +3638        UMEDIUMINT = auto()
    +3639        UDECIMAL = auto()
    +3640        UNIQUEIDENTIFIER = auto()
    +3641        UNKNOWN = auto()  # Sentinel value, useful for type annotation
    +3642        USERDEFINED = "USER-DEFINED"
    +3643        USMALLINT = auto()
    +3644        UTINYINT = auto()
    +3645        UUID = auto()
    +3646        VARBINARY = auto()
    +3647        VARCHAR = auto()
    +3648        VARIANT = auto()
    +3649        XML = auto()
    +3650        YEAR = auto()
    +3651
    +3652    TEXT_TYPES = {
    +3653        Type.CHAR,
    +3654        Type.NCHAR,
    +3655        Type.VARCHAR,
    +3656        Type.NVARCHAR,
    +3657        Type.TEXT,
    +3658    }
    +3659
    +3660    INTEGER_TYPES = {
    +3661        Type.INT,
    +3662        Type.TINYINT,
    +3663        Type.SMALLINT,
    +3664        Type.BIGINT,
    +3665        Type.INT128,
    +3666        Type.INT256,
    +3667    }
    +3668
    +3669    FLOAT_TYPES = {
    +3670        Type.FLOAT,
    +3671        Type.DOUBLE,
    +3672    }
    +3673
    +3674    NUMERIC_TYPES = {
    +3675        *INTEGER_TYPES,
    +3676        *FLOAT_TYPES,
    +3677    }
    +3678
    +3679    TEMPORAL_TYPES = {
    +3680        Type.TIME,
    +3681        Type.TIMETZ,
    +3682        Type.TIMESTAMP,
    +3683        Type.TIMESTAMPTZ,
    +3684        Type.TIMESTAMPLTZ,
    +3685        Type.TIMESTAMP_S,
    +3686        Type.TIMESTAMP_MS,
    +3687        Type.TIMESTAMP_NS,
    +3688        Type.DATE,
    +3689        Type.DATETIME,
    +3690        Type.DATETIME64,
    +3691    }
    +3692
    +3693    @classmethod
    +3694    def build(
    +3695        cls,
    +3696        dtype: str | DataType | DataType.Type,
    +3697        dialect: DialectType = None,
    +3698        udt: bool = False,
    +3699        **kwargs,
    +3700    ) -> DataType:
    +3701        """
    +3702        Constructs a DataType object.
    +3703
    +3704        Args:
    +3705            dtype: the data type of interest.
    +3706            dialect: the dialect to use for parsing `dtype`, in case it's a string.
    +3707            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
    +3708                DataType, thus creating a user-defined type.
    +3709            kawrgs: additional arguments to pass in the constructor of DataType.
    +3710
    +3711        Returns:
    +3712            The constructed DataType object.
    +3713        """
    +3714        from sqlglot import parse_one
    +3715
    +3716        if isinstance(dtype, str):
    +3717            if dtype.upper() == "UNKNOWN":
    +3718                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
    +3719
    +3720            try:
    +3721                data_type_exp = parse_one(
    +3722                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
    +3723                )
    +3724            except ParseError:
    +3725                if udt:
    +3726                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
    +3727                raise
    +3728        elif isinstance(dtype, DataType.Type):
    +3729            data_type_exp = DataType(this=dtype)
    +3730        elif isinstance(dtype, DataType):
    +3731            return dtype
    +3732        else:
    +3733            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
    +3734
    +3735        return DataType(**{**data_type_exp.args, **kwargs})
    +3736
    +3737    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    +3738        """
    +3739        Checks whether this DataType matches one of the provided data types. Nested types or precision
    +3740        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
    +3741
    +3742        Args:
    +3743            dtypes: the data types to compare this DataType to.
    +3744
    +3745        Returns:
    +3746            True, if and only if there is a type in `dtypes` which is equal to this DataType.
    +3747        """
    +3748        for dtype in dtypes:
    +3749            other = DataType.build(dtype, udt=True)
    +3750
    +3751            if (
    +3752                other.expressions
    +3753                or self.this == DataType.Type.USERDEFINED
    +3754                or other.this == DataType.Type.USERDEFINED
    +3755            ):
    +3756                matches = self == other
    +3757            else:
    +3758                matches = self.this == other.this
    +3759
    +3760            if matches:
    +3761                return True
    +3762        return False
     
    @@ -42775,7 +43143,7 @@ If an Expression instance is passed, it w
    TEXT_TYPES = - {<Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>} + {<Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>}
    @@ -42788,7 +43156,7 @@ If an Expression instance is passed, it w
    INTEGER_TYPES = - {<Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>} + {<Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>}
    @@ -42800,7 +43168,7 @@ If an Expression instance is passed, it w
    FLOAT_TYPES = -{<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>} +{<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
    @@ -42813,7 +43181,7 @@ If an Expression instance is passed, it w
    NUMERIC_TYPES = - {<Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>} + {<Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
    @@ -42826,7 +43194,7 @@ If an Expression instance is passed, it w
    TEMPORAL_TYPES = - {<Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>} + {<Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME64: 'DATETIME64'>}
    @@ -42847,49 +43215,49 @@ If an Expression instance is passed, it w
    -
    3680    @classmethod
    -3681    def build(
    -3682        cls,
    -3683        dtype: str | DataType | DataType.Type,
    -3684        dialect: DialectType = None,
    -3685        udt: bool = False,
    -3686        **kwargs,
    -3687    ) -> DataType:
    -3688        """
    -3689        Constructs a DataType object.
    -3690
    -3691        Args:
    -3692            dtype: the data type of interest.
    -3693            dialect: the dialect to use for parsing `dtype`, in case it's a string.
    -3694            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
    -3695                DataType, thus creating a user-defined type.
    -3696            kawrgs: additional arguments to pass in the constructor of DataType.
    -3697
    -3698        Returns:
    -3699            The constructed DataType object.
    -3700        """
    -3701        from sqlglot import parse_one
    -3702
    -3703        if isinstance(dtype, str):
    -3704            if dtype.upper() == "UNKNOWN":
    -3705                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
    -3706
    -3707            try:
    -3708                data_type_exp = parse_one(
    -3709                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
    -3710                )
    -3711            except ParseError:
    -3712                if udt:
    -3713                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
    -3714                raise
    -3715        elif isinstance(dtype, DataType.Type):
    -3716            data_type_exp = DataType(this=dtype)
    -3717        elif isinstance(dtype, DataType):
    -3718            return dtype
    -3719        else:
    -3720            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
    -3721
    -3722        return DataType(**{**data_type_exp.args, **kwargs})
    +            
    3693    @classmethod
    +3694    def build(
    +3695        cls,
    +3696        dtype: str | DataType | DataType.Type,
    +3697        dialect: DialectType = None,
    +3698        udt: bool = False,
    +3699        **kwargs,
    +3700    ) -> DataType:
    +3701        """
    +3702        Constructs a DataType object.
    +3703
    +3704        Args:
    +3705            dtype: the data type of interest.
    +3706            dialect: the dialect to use for parsing `dtype`, in case it's a string.
    +3707            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
    +3708                DataType, thus creating a user-defined type.
    +3709            kawrgs: additional arguments to pass in the constructor of DataType.
    +3710
    +3711        Returns:
    +3712            The constructed DataType object.
    +3713        """
    +3714        from sqlglot import parse_one
    +3715
    +3716        if isinstance(dtype, str):
    +3717            if dtype.upper() == "UNKNOWN":
    +3718                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
    +3719
    +3720            try:
    +3721                data_type_exp = parse_one(
    +3722                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
    +3723                )
    +3724            except ParseError:
    +3725                if udt:
    +3726                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
    +3727                raise
    +3728        elif isinstance(dtype, DataType.Type):
    +3729            data_type_exp = DataType(this=dtype)
    +3730        elif isinstance(dtype, DataType):
    +3731            return dtype
    +3732        else:
    +3733            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
    +3734
    +3735        return DataType(**{**data_type_exp.args, **kwargs})
     
    @@ -42925,32 +43293,32 @@ DataType, thus creating a user-defined type.
    -
    3724    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    -3725        """
    -3726        Checks whether this DataType matches one of the provided data types. Nested types or precision
    -3727        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
    -3728
    -3729        Args:
    -3730            dtypes: the data types to compare this DataType to.
    -3731
    -3732        Returns:
    -3733            True, if and only if there is a type in `dtypes` which is equal to this DataType.
    -3734        """
    -3735        for dtype in dtypes:
    -3736            other = DataType.build(dtype, udt=True)
    -3737
    -3738            if (
    -3739                other.expressions
    -3740                or self.this == DataType.Type.USERDEFINED
    -3741                or other.this == DataType.Type.USERDEFINED
    -3742            ):
    -3743                matches = self == other
    -3744            else:
    -3745                matches = self.this == other.this
    -3746
    -3747            if matches:
    -3748                return True
    -3749        return False
    +            
    3737    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    +3738        """
    +3739        Checks whether this DataType matches one of the provided data types. Nested types or precision
    +3740        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
    +3741
    +3742        Args:
    +3743            dtypes: the data types to compare this DataType to.
    +3744
    +3745        Returns:
    +3746            True, if and only if there is a type in `dtypes` which is equal to this DataType.
    +3747        """
    +3748        for dtype in dtypes:
    +3749            other = DataType.build(dtype, udt=True)
    +3750
    +3751            if (
    +3752                other.expressions
    +3753                or self.this == DataType.Type.USERDEFINED
    +3754                or other.this == DataType.Type.USERDEFINED
    +3755            ):
    +3756                matches = self == other
    +3757            else:
    +3758                matches = self.this == other.this
    +3759
    +3760            if matches:
    +3761                return True
    +3762        return False
     
    @@ -43064,102 +43432,102 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3542    class Type(AutoName):
    -3543        ARRAY = auto()
    -3544        BIGDECIMAL = auto()
    -3545        BIGINT = auto()
    -3546        BIGSERIAL = auto()
    -3547        BINARY = auto()
    -3548        BIT = auto()
    -3549        BOOLEAN = auto()
    -3550        CHAR = auto()
    -3551        DATE = auto()
    -3552        DATEMULTIRANGE = auto()
    -3553        DATERANGE = auto()
    -3554        DATETIME = auto()
    -3555        DATETIME64 = auto()
    -3556        DECIMAL = auto()
    -3557        DOUBLE = auto()
    -3558        ENUM = auto()
    -3559        ENUM8 = auto()
    -3560        ENUM16 = auto()
    -3561        FIXEDSTRING = auto()
    -3562        FLOAT = auto()
    -3563        GEOGRAPHY = auto()
    -3564        GEOMETRY = auto()
    -3565        HLLSKETCH = auto()
    -3566        HSTORE = auto()
    -3567        IMAGE = auto()
    -3568        INET = auto()
    -3569        INT = auto()
    -3570        INT128 = auto()
    -3571        INT256 = auto()
    -3572        INT4MULTIRANGE = auto()
    -3573        INT4RANGE = auto()
    -3574        INT8MULTIRANGE = auto()
    -3575        INT8RANGE = auto()
    -3576        INTERVAL = auto()
    -3577        IPADDRESS = auto()
    -3578        IPPREFIX = auto()
    -3579        JSON = auto()
    -3580        JSONB = auto()
    -3581        LONGBLOB = auto()
    -3582        LONGTEXT = auto()
    -3583        LOWCARDINALITY = auto()
    -3584        MAP = auto()
    -3585        MEDIUMBLOB = auto()
    -3586        MEDIUMINT = auto()
    -3587        MEDIUMTEXT = auto()
    -3588        MONEY = auto()
    -3589        NCHAR = auto()
    -3590        NESTED = auto()
    -3591        NULL = auto()
    -3592        NULLABLE = auto()
    -3593        NUMMULTIRANGE = auto()
    -3594        NUMRANGE = auto()
    -3595        NVARCHAR = auto()
    -3596        OBJECT = auto()
    -3597        ROWVERSION = auto()
    -3598        SERIAL = auto()
    -3599        SET = auto()
    -3600        SMALLINT = auto()
    -3601        SMALLMONEY = auto()
    -3602        SMALLSERIAL = auto()
    -3603        STRUCT = auto()
    -3604        SUPER = auto()
    -3605        TEXT = auto()
    -3606        TINYBLOB = auto()
    -3607        TINYTEXT = auto()
    -3608        TIME = auto()
    -3609        TIMETZ = auto()
    -3610        TIMESTAMP = auto()
    -3611        TIMESTAMPLTZ = auto()
    -3612        TIMESTAMPTZ = auto()
    -3613        TIMESTAMP_S = auto()
    -3614        TIMESTAMP_MS = auto()
    -3615        TIMESTAMP_NS = auto()
    -3616        TINYINT = auto()
    -3617        TSMULTIRANGE = auto()
    -3618        TSRANGE = auto()
    -3619        TSTZMULTIRANGE = auto()
    -3620        TSTZRANGE = auto()
    -3621        UBIGINT = auto()
    -3622        UINT = auto()
    -3623        UINT128 = auto()
    -3624        UINT256 = auto()
    -3625        UMEDIUMINT = auto()
    -3626        UDECIMAL = auto()
    -3627        UNIQUEIDENTIFIER = auto()
    -3628        UNKNOWN = auto()  # Sentinel value, useful for type annotation
    -3629        USERDEFINED = "USER-DEFINED"
    -3630        USMALLINT = auto()
    -3631        UTINYINT = auto()
    -3632        UUID = auto()
    -3633        VARBINARY = auto()
    -3634        VARCHAR = auto()
    -3635        VARIANT = auto()
    -3636        XML = auto()
    -3637        YEAR = auto()
    +            
    3555    class Type(AutoName):
    +3556        ARRAY = auto()
    +3557        BIGDECIMAL = auto()
    +3558        BIGINT = auto()
    +3559        BIGSERIAL = auto()
    +3560        BINARY = auto()
    +3561        BIT = auto()
    +3562        BOOLEAN = auto()
    +3563        CHAR = auto()
    +3564        DATE = auto()
    +3565        DATEMULTIRANGE = auto()
    +3566        DATERANGE = auto()
    +3567        DATETIME = auto()
    +3568        DATETIME64 = auto()
    +3569        DECIMAL = auto()
    +3570        DOUBLE = auto()
    +3571        ENUM = auto()
    +3572        ENUM8 = auto()
    +3573        ENUM16 = auto()
    +3574        FIXEDSTRING = auto()
    +3575        FLOAT = auto()
    +3576        GEOGRAPHY = auto()
    +3577        GEOMETRY = auto()
    +3578        HLLSKETCH = auto()
    +3579        HSTORE = auto()
    +3580        IMAGE = auto()
    +3581        INET = auto()
    +3582        INT = auto()
    +3583        INT128 = auto()
    +3584        INT256 = auto()
    +3585        INT4MULTIRANGE = auto()
    +3586        INT4RANGE = auto()
    +3587        INT8MULTIRANGE = auto()
    +3588        INT8RANGE = auto()
    +3589        INTERVAL = auto()
    +3590        IPADDRESS = auto()
    +3591        IPPREFIX = auto()
    +3592        JSON = auto()
    +3593        JSONB = auto()
    +3594        LONGBLOB = auto()
    +3595        LONGTEXT = auto()
    +3596        LOWCARDINALITY = auto()
    +3597        MAP = auto()
    +3598        MEDIUMBLOB = auto()
    +3599        MEDIUMINT = auto()
    +3600        MEDIUMTEXT = auto()
    +3601        MONEY = auto()
    +3602        NCHAR = auto()
    +3603        NESTED = auto()
    +3604        NULL = auto()
    +3605        NULLABLE = auto()
    +3606        NUMMULTIRANGE = auto()
    +3607        NUMRANGE = auto()
    +3608        NVARCHAR = auto()
    +3609        OBJECT = auto()
    +3610        ROWVERSION = auto()
    +3611        SERIAL = auto()
    +3612        SET = auto()
    +3613        SMALLINT = auto()
    +3614        SMALLMONEY = auto()
    +3615        SMALLSERIAL = auto()
    +3616        STRUCT = auto()
    +3617        SUPER = auto()
    +3618        TEXT = auto()
    +3619        TINYBLOB = auto()
    +3620        TINYTEXT = auto()
    +3621        TIME = auto()
    +3622        TIMETZ = auto()
    +3623        TIMESTAMP = auto()
    +3624        TIMESTAMPLTZ = auto()
    +3625        TIMESTAMPTZ = auto()
    +3626        TIMESTAMP_S = auto()
    +3627        TIMESTAMP_MS = auto()
    +3628        TIMESTAMP_NS = auto()
    +3629        TINYINT = auto()
    +3630        TSMULTIRANGE = auto()
    +3631        TSRANGE = auto()
    +3632        TSTZMULTIRANGE = auto()
    +3633        TSTZRANGE = auto()
    +3634        UBIGINT = auto()
    +3635        UINT = auto()
    +3636        UINT128 = auto()
    +3637        UINT256 = auto()
    +3638        UMEDIUMINT = auto()
    +3639        UDECIMAL = auto()
    +3640        UNIQUEIDENTIFIER = auto()
    +3641        UNKNOWN = auto()  # Sentinel value, useful for type annotation
    +3642        USERDEFINED = "USER-DEFINED"
    +3643        USMALLINT = auto()
    +3644        UTINYINT = auto()
    +3645        UUID = auto()
    +3646        VARBINARY = auto()
    +3647        VARCHAR = auto()
    +3648        VARIANT = auto()
    +3649        XML = auto()
    +3650        YEAR = auto()
     
    @@ -44329,8 +44697,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3753class PseudoType(DataType):
    -3754    arg_types = {"this": True}
    +            
    3766class PseudoType(DataType):
    +3767    arg_types = {"this": True}
     
    @@ -44451,8 +44819,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3758class ObjectIdentifier(DataType):
    -3759    arg_types = {"this": True}
    +            
    3771class ObjectIdentifier(DataType):
    +3772    arg_types = {"this": True}
     
    @@ -44573,8 +44941,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3763class SubqueryPredicate(Predicate):
    -3764    pass
    +            
    3776class SubqueryPredicate(Predicate):
    +3777    pass
     
    @@ -44673,8 +45041,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3767class All(SubqueryPredicate):
    -3768    pass
    +            
    3780class All(SubqueryPredicate):
    +3781    pass
     
    @@ -44773,8 +45141,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3771class Any(SubqueryPredicate):
    -3772    pass
    +            
    3784class Any(SubqueryPredicate):
    +3785    pass
     
    @@ -44873,8 +45241,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3775class Exists(SubqueryPredicate):
    -3776    pass
    +            
    3788class Exists(SubqueryPredicate):
    +3789    pass
     
    @@ -44973,8 +45341,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3781class Command(Expression):
    -3782    arg_types = {"this": True, "expression": False}
    +            
    3794class Command(Expression):
    +3795    arg_types = {"this": True, "expression": False}
     
    @@ -45084,8 +45452,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3785class Transaction(Expression):
    -3786    arg_types = {"this": False, "modes": False, "mark": False}
    +            
    3798class Transaction(Expression):
    +3799    arg_types = {"this": False, "modes": False, "mark": False}
     
    @@ -45195,8 +45563,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3789class Commit(Expression):
    -3790    arg_types = {"chain": False, "this": False, "durability": False}
    +            
    3802class Commit(Expression):
    +3803    arg_types = {"chain": False, "this": False, "durability": False}
     
    @@ -45306,8 +45674,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3793class Rollback(Expression):
    -3794    arg_types = {"savepoint": False, "this": False}
    +            
    3806class Rollback(Expression):
    +3807    arg_types = {"savepoint": False, "this": False}
     
    @@ -45417,8 +45785,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3797class AlterTable(Expression):
    -3798    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
    +            
    3810class AlterTable(Expression):
    +3811    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
     
    @@ -45528,8 +45896,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3801class AddConstraint(Expression):
    -3802    arg_types = {"this": False, "expression": False, "enforced": False}
    +            
    3814class AddConstraint(Expression):
    +3815    arg_types = {"this": False, "expression": False, "enforced": False}
     
    @@ -45639,8 +46007,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3805class DropPartition(Expression):
    -3806    arg_types = {"expressions": True, "exists": False}
    +            
    3818class DropPartition(Expression):
    +3819    arg_types = {"expressions": True, "exists": False}
     
    @@ -45750,16 +46118,16 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3810class Binary(Condition):
    -3811    arg_types = {"this": True, "expression": True}
    -3812
    -3813    @property
    -3814    def left(self) -> Expression:
    -3815        return self.this
    -3816
    -3817    @property
    -3818    def right(self) -> Expression:
    -3819        return self.expression
    +            
    3823class Binary(Condition):
    +3824    arg_types = {"this": True, "expression": True}
    +3825
    +3826    @property
    +3827    def left(self) -> Expression:
    +3828        return self.this
    +3829
    +3830    @property
    +3831    def right(self) -> Expression:
    +3832        return self.expression
     
    @@ -45891,8 +46259,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3822class Add(Binary):
    -3823    pass
    +            
    3835class Add(Binary):
    +3836    pass
     
    @@ -45996,8 +46364,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3826class Connector(Binary):
    -3827    pass
    +            
    3839class Connector(Binary):
    +3840    pass
     
    @@ -46101,8 +46469,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3830class And(Connector):
    -3831    pass
    +            
    3843class And(Connector):
    +3844    pass
     
    @@ -46206,8 +46574,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3834class Or(Connector):
    -3835    pass
    +            
    3847class Or(Connector):
    +3848    pass
     
    @@ -46311,8 +46679,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3838class BitwiseAnd(Binary):
    -3839    pass
    +            
    3851class BitwiseAnd(Binary):
    +3852    pass
     
    @@ -46416,8 +46784,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3842class BitwiseLeftShift(Binary):
    -3843    pass
    +            
    3855class BitwiseLeftShift(Binary):
    +3856    pass
     
    @@ -46521,8 +46889,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3846class BitwiseOr(Binary):
    -3847    pass
    +            
    3859class BitwiseOr(Binary):
    +3860    pass
     
    @@ -46626,8 +46994,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3850class BitwiseRightShift(Binary):
    -3851    pass
    +            
    3863class BitwiseRightShift(Binary):
    +3864    pass
     
    @@ -46731,8 +47099,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3854class BitwiseXor(Binary):
    -3855    pass
    +            
    3867class BitwiseXor(Binary):
    +3868    pass
     
    @@ -46836,8 +47204,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3858class Div(Binary):
    -3859    pass
    +            
    3871class Div(Binary):
    +3872    pass
     
    @@ -46941,8 +47309,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3862class Overlaps(Binary):
    -3863    pass
    +            
    3875class Overlaps(Binary):
    +3876    pass
     
    @@ -47046,22 +47414,22 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3866class Dot(Binary):
    -3867    @property
    -3868    def name(self) -> str:
    -3869        return self.expression.name
    -3870
    -3871    @property
    -3872    def output_name(self) -> str:
    -3873        return self.name
    -3874
    -3875    @classmethod
    -3876    def build(self, expressions: t.Sequence[Expression]) -> Dot:
    -3877        """Build a Dot object with a sequence of expressions."""
    -3878        if len(expressions) < 2:
    -3879            raise ValueError(f"Dot requires >= 2 expressions.")
    -3880
    -3881        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
    +            
    3879class Dot(Binary):
    +3880    @property
    +3881    def name(self) -> str:
    +3882        return self.expression.name
    +3883
    +3884    @property
    +3885    def output_name(self) -> str:
    +3886        return self.name
    +3887
    +3888    @classmethod
    +3889    def build(self, expressions: t.Sequence[Expression]) -> Dot:
    +3890        """Build a Dot object with a sequence of expressions."""
    +3891        if len(expressions) < 2:
    +3892            raise ValueError(f"Dot requires >= 2 expressions.")
    +3893
    +3894        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
     
    @@ -47120,13 +47488,13 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3875    @classmethod
    -3876    def build(self, expressions: t.Sequence[Expression]) -> Dot:
    -3877        """Build a Dot object with a sequence of expressions."""
    -3878        if len(expressions) < 2:
    -3879            raise ValueError(f"Dot requires >= 2 expressions.")
    -3880
    -3881        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
    +            
    3888    @classmethod
    +3889    def build(self, expressions: t.Sequence[Expression]) -> Dot:
    +3890        """Build a Dot object with a sequence of expressions."""
    +3891        if len(expressions) < 2:
    +3892            raise ValueError(f"Dot requires >= 2 expressions.")
    +3893
    +3894        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
     
    @@ -47231,8 +47599,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3884class DPipe(Binary):
    -3885    pass
    +            
    3897class DPipe(Binary):
    +3898    pass
     
    @@ -47336,8 +47704,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3888class SafeDPipe(DPipe):
    -3889    pass
    +            
    3901class SafeDPipe(DPipe):
    +3902    pass
     
    @@ -47441,8 +47809,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3892class EQ(Binary, Predicate):
    -3893    pass
    +            
    3905class EQ(Binary, Predicate):
    +3906    pass
     
    @@ -47546,8 +47914,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3896class NullSafeEQ(Binary, Predicate):
    -3897    pass
    +            
    3909class NullSafeEQ(Binary, Predicate):
    +3910    pass
     
    @@ -47651,8 +48019,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3900class NullSafeNEQ(Binary, Predicate):
    -3901    pass
    +            
    3913class NullSafeNEQ(Binary, Predicate):
    +3914    pass
     
    @@ -47756,8 +48124,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3904class Distance(Binary):
    -3905    pass
    +            
    3917class Distance(Binary):
    +3918    pass
     
    @@ -47861,8 +48229,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3908class Escape(Binary):
    -3909    pass
    +            
    3921class Escape(Binary):
    +3922    pass
     
    @@ -47966,8 +48334,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3912class Glob(Binary, Predicate):
    -3913    pass
    +            
    3925class Glob(Binary, Predicate):
    +3926    pass
     
    @@ -48071,8 +48439,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3916class GT(Binary, Predicate):
    -3917    pass
    +            
    3929class GT(Binary, Predicate):
    +3930    pass
     
    @@ -48176,8 +48544,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3920class GTE(Binary, Predicate):
    -3921    pass
    +            
    3933class GTE(Binary, Predicate):
    +3934    pass
     
    @@ -48281,8 +48649,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3924class ILike(Binary, Predicate):
    -3925    pass
    +            
    3937class ILike(Binary, Predicate):
    +3938    pass
     
    @@ -48386,8 +48754,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3928class ILikeAny(Binary, Predicate):
    -3929    pass
    +            
    3941class ILikeAny(Binary, Predicate):
    +3942    pass
     
    @@ -48491,8 +48859,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3932class IntDiv(Binary):
    -3933    pass
    +            
    3945class IntDiv(Binary):
    +3946    pass
     
    @@ -48596,8 +48964,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3936class Is(Binary, Predicate):
    -3937    pass
    +            
    3949class Is(Binary, Predicate):
    +3950    pass
     
    @@ -48701,8 +49069,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3940class Kwarg(Binary):
    -3941    """Kwarg in special functions like func(kwarg => y)."""
    +            
    3953class Kwarg(Binary):
    +3954    """Kwarg in special functions like func(kwarg => y)."""
     
    @@ -48808,8 +49176,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3944class Like(Binary, Predicate):
    -3945    pass
    +            
    3957class Like(Binary, Predicate):
    +3958    pass
     
    @@ -48913,8 +49281,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3948class LikeAny(Binary, Predicate):
    -3949    pass
    +            
    3961class LikeAny(Binary, Predicate):
    +3962    pass
     
    @@ -49018,8 +49386,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3952class LT(Binary, Predicate):
    -3953    pass
    +            
    3965class LT(Binary, Predicate):
    +3966    pass
     
    @@ -49123,8 +49491,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3956class LTE(Binary, Predicate):
    -3957    pass
    +            
    3969class LTE(Binary, Predicate):
    +3970    pass
     
    @@ -49228,8 +49596,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3960class Mod(Binary):
    -3961    pass
    +            
    3973class Mod(Binary):
    +3974    pass
     
    @@ -49333,8 +49701,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3964class Mul(Binary):
    -3965    pass
    +            
    3977class Mul(Binary):
    +3978    pass
     
    @@ -49438,8 +49806,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3968class NEQ(Binary, Predicate):
    -3969    pass
    +            
    3981class NEQ(Binary, Predicate):
    +3982    pass
     
    @@ -49543,8 +49911,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3972class SimilarTo(Binary, Predicate):
    -3973    pass
    +            
    3985class SimilarTo(Binary, Predicate):
    +3986    pass
     
    @@ -49648,8 +50016,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3976class Slice(Binary):
    -3977    arg_types = {"this": False, "expression": False}
    +            
    3989class Slice(Binary):
    +3990    arg_types = {"this": False, "expression": False}
     
    @@ -49764,8 +50132,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3980class Sub(Binary):
    -3981    pass
    +            
    3993class Sub(Binary):
    +3994    pass
     
    @@ -49869,8 +50237,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3984class ArrayOverlaps(Binary):
    -3985    pass
    +            
    3997class ArrayOverlaps(Binary):
    +3998    pass
     
    @@ -49974,8 +50342,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3990class Unary(Condition):
    -3991    pass
    +            
    4003class Unary(Condition):
    +4004    pass
     
    @@ -50074,8 +50442,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3994class BitwiseNot(Unary):
    -3995    pass
    +            
    4007class BitwiseNot(Unary):
    +4008    pass
     
    @@ -50174,8 +50542,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    3998class Not(Unary):
    -3999    pass
    +            
    4011class Not(Unary):
    +4012    pass
     
    @@ -50274,12 +50642,12 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4002class Paren(Unary):
    -4003    arg_types = {"this": True, "with": False}
    -4004
    -4005    @property
    -4006    def output_name(self) -> str:
    -4007        return self.this.name
    +            
    4015class Paren(Unary):
    +4016    arg_types = {"this": True, "with": False}
    +4017
    +4018    @property
    +4019    def output_name(self) -> str:
    +4020        return self.this.name
     
    @@ -50418,8 +50786,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4010class Neg(Unary):
    -4011    pass
    +            
    4023class Neg(Unary):
    +4024    pass
     
    @@ -50518,12 +50886,12 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4014class Alias(Expression):
    -4015    arg_types = {"this": True, "alias": False}
    -4016
    -4017    @property
    -4018    def output_name(self) -> str:
    -4019        return self.alias
    +            
    4027class Alias(Expression):
    +4028    arg_types = {"this": True, "alias": False}
    +4029
    +4030    @property
    +4031    def output_name(self) -> str:
    +4032        return self.alias
     
    @@ -50662,12 +51030,12 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4022class Aliases(Expression):
    -4023    arg_types = {"this": True, "expressions": True}
    -4024
    -4025    @property
    -4026    def aliases(self):
    -4027        return self.expressions
    +            
    4035class Aliases(Expression):
    +4036    arg_types = {"this": True, "expressions": True}
    +4037
    +4038    @property
    +4039    def aliases(self):
    +4040        return self.expressions
     
    @@ -50788,8 +51156,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4030class AtTimeZone(Expression):
    -4031    arg_types = {"this": True, "zone": True}
    +            
    4043class AtTimeZone(Expression):
    +4044    arg_types = {"this": True, "zone": True}
     
    @@ -50899,8 +51267,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4034class Between(Predicate):
    -4035    arg_types = {"this": True, "low": True, "high": True}
    +            
    4047class Between(Predicate):
    +4048    arg_types = {"this": True, "low": True, "high": True}
     
    @@ -51010,15 +51378,15 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4038class Bracket(Condition):
    -4039    arg_types = {"this": True, "expressions": True}
    -4040
    -4041    @property
    -4042    def output_name(self) -> str:
    -4043        if len(self.expressions) == 1:
    -4044            return self.expressions[0].output_name
    -4045
    -4046        return super().output_name
    +            
    4051class Bracket(Condition):
    +4052    arg_types = {"this": True, "expressions": True}
    +4053
    +4054    @property
    +4055    def output_name(self) -> str:
    +4056        if len(self.expressions) == 1:
    +4057            return self.expressions[0].output_name
    +4058
    +4059        return super().output_name
     
    @@ -51157,8 +51525,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4049class SafeBracket(Bracket):
    -4050    """Represents array lookup where OOB index yields NULL instead of causing a failure."""
    +            
    4062class SafeBracket(Bracket):
    +4063    """Represents array lookup where OOB index yields NULL instead of causing a failure."""
     
    @@ -51262,8 +51630,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4053class Distinct(Expression):
    -4054    arg_types = {"expressions": False, "on": False}
    +            
    4066class Distinct(Expression):
    +4067    arg_types = {"expressions": False, "on": False}
     
    @@ -51373,15 +51741,15 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4057class In(Predicate):
    -4058    arg_types = {
    -4059        "this": True,
    -4060        "expressions": False,
    -4061        "query": False,
    -4062        "unnest": False,
    -4063        "field": False,
    -4064        "is_global": False,
    -4065    }
    +            
    4070class In(Predicate):
    +4071    arg_types = {
    +4072        "this": True,
    +4073        "expressions": False,
    +4074        "query": False,
    +4075        "unnest": False,
    +4076        "field": False,
    +4077        "is_global": False,
    +4078    }
     
    @@ -51492,23 +51860,38 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4068class TimeUnit(Expression):
    -4069    """Automatically converts unit arg into a var."""
    -4070
    -4071    arg_types = {"unit": False}
    -4072
    -4073    def __init__(self, **args):
    -4074        unit = args.get("unit")
    -4075        if isinstance(unit, (Column, Literal)):
    -4076            args["unit"] = Var(this=unit.name)
    -4077        elif isinstance(unit, Week):
    -4078            unit.set("this", Var(this=unit.this.name))
    -4079
    -4080        super().__init__(**args)
    -4081
    -4082    @property
    -4083    def unit(self) -> t.Optional[Var]:
    -4084        return self.args.get("unit")
    +            
    4081class TimeUnit(Expression):
    +4082    """Automatically converts unit arg into a var."""
    +4083
    +4084    arg_types = {"unit": False}
    +4085
    +4086    UNABBREVIATED_UNIT_NAME = {
    +4087        "d": "day",
    +4088        "h": "hour",
    +4089        "m": "minute",
    +4090        "ms": "millisecond",
    +4091        "ns": "nanosecond",
    +4092        "q": "quarter",
    +4093        "s": "second",
    +4094        "us": "microsecond",
    +4095        "w": "week",
    +4096        "y": "year",
    +4097    }
    +4098
    +4099    VAR_LIKE = (Column, Literal, Var)
    +4100
    +4101    def __init__(self, **args):
    +4102        unit = args.get("unit")
    +4103        if isinstance(unit, self.VAR_LIKE):
    +4104            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
    +4105        elif isinstance(unit, Week):
    +4106            unit.set("this", Var(this=unit.this.name))
    +4107
    +4108        super().__init__(**args)
    +4109
    +4110    @property
    +4111    def unit(self) -> t.Optional[Var]:
    +4112        return self.args.get("unit")
     
    @@ -51526,14 +51909,14 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4073    def __init__(self, **args):
    -4074        unit = args.get("unit")
    -4075        if isinstance(unit, (Column, Literal)):
    -4076            args["unit"] = Var(this=unit.name)
    -4077        elif isinstance(unit, Week):
    -4078            unit.set("this", Var(this=unit.this.name))
    -4079
    -4080        super().__init__(**args)
    +            
    4101    def __init__(self, **args):
    +4102        unit = args.get("unit")
    +4103        if isinstance(unit, self.VAR_LIKE):
    +4104            args["unit"] = Var(this=self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name)
    +4105        elif isinstance(unit, Week):
    +4106            unit.set("this", Var(this=unit.this.name))
    +4107
    +4108        super().__init__(**args)
     
    @@ -51551,6 +51934,32 @@ will be compared using "structural equivalence" semantics, so e.g. array != +
    +
    +
    + UNABBREVIATED_UNIT_NAME = + + {'d': 'day', 'h': 'hour', 'm': 'minute', 'ms': 'millisecond', 'ns': 'nanosecond', 'q': 'quarter', 's': 'second', 'us': 'microsecond', 'w': 'week', 'y': 'year'} + + +
    + + + + +
    +
    +
    + VAR_LIKE = + + (<class 'Column'>, <class 'Literal'>, <class 'Var'>) + + +
    + + + +
    @@ -51654,14 +52063,14 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4087class IntervalOp(TimeUnit):
    -4088    arg_types = {"unit": True, "expression": True}
    -4089
    -4090    def interval(self):
    -4091        return Interval(
    -4092            this=self.expression.copy(),
    -4093            unit=self.unit.copy(),
    -4094        )
    +            
    4115class IntervalOp(TimeUnit):
    +4116    arg_types = {"unit": True, "expression": True}
    +4117
    +4118    def interval(self):
    +4119        return Interval(
    +4120            this=self.expression.copy(),
    +4121            unit=self.unit.copy(),
    +4122        )
     
    @@ -51690,11 +52099,11 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4090    def interval(self):
    -4091        return Interval(
    -4092            this=self.expression.copy(),
    -4093            unit=self.unit.copy(),
    -4094        )
    +            
    4118    def interval(self):
    +4119        return Interval(
    +4120            this=self.expression.copy(),
    +4121            unit=self.unit.copy(),
    +4122        )
     
    @@ -51718,6 +52127,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    @@ -51797,8 +52208,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4100class IntervalSpan(DataType):
    -4101    arg_types = {"this": True, "expression": True}
    +            
    4128class IntervalSpan(DataType):
    +4129    arg_types = {"this": True, "expression": True}
     
    @@ -51919,8 +52330,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4104class Interval(TimeUnit):
    -4105    arg_types = {"this": False, "unit": False}
    +            
    4132class Interval(TimeUnit):
    +4133    arg_types = {"this": False, "unit": False}
     
    @@ -51955,6 +52366,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    @@ -52034,8 +52447,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4108class IgnoreNulls(Expression):
    -4109    pass
    +            
    4136class IgnoreNulls(Expression):
    +4137    pass
     
    @@ -52134,8 +52547,8 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4112class RespectNulls(Expression):
    -4113    pass
    +            
    4140class RespectNulls(Expression):
    +4141    pass
     
    @@ -52234,53 +52647,53 @@ will be compared using "structural equivalence" semantics, so e.g. array !=
    -
    4117class Func(Condition):
    -4118    """
    -4119    The base class for all function expressions.
    -4120
    -4121    Attributes:
    -4122        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
    -4123            treated as a variable length argument and the argument's value will be stored as a list.
    -4124        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
    -4125            for this function expression. These values are used to map this node to a name during parsing
    -4126            as well as to provide the function's name during SQL string generation. By default the SQL
    -4127            name is set to the expression's class name transformed to snake case.
    -4128    """
    -4129
    -4130    is_var_len_args = False
    -4131
    -4132    @classmethod
    -4133    def from_arg_list(cls, args):
    -4134        if cls.is_var_len_args:
    -4135            all_arg_keys = list(cls.arg_types)
    -4136            # If this function supports variable length argument treat the last argument as such.
    -4137            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
    -4138            num_non_var = len(non_var_len_arg_keys)
    -4139
    -4140            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
    -4141            args_dict[all_arg_keys[-1]] = args[num_non_var:]
    -4142        else:
    -4143            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
    -4144
    -4145        return cls(**args_dict)
    -4146
    -4147    @classmethod
    -4148    def sql_names(cls):
    -4149        if cls is Func:
    -4150            raise NotImplementedError(
    -4151                "SQL name is only supported by concrete function implementations"
    -4152            )
    -4153        if "_sql_names" not in cls.__dict__:
    -4154            cls._sql_names = [camel_to_snake_case(cls.__name__)]
    -4155        return cls._sql_names
    -4156
    -4157    @classmethod
    -4158    def sql_name(cls):
    -4159        return cls.sql_names()[0]
    -4160
    -4161    @classmethod
    -4162    def default_parser_mappings(cls):
    -4163        return {name: cls.from_arg_list for name in cls.sql_names()}
    +            
    4145class Func(Condition):
    +4146    """
    +4147    The base class for all function expressions.
    +4148
    +4149    Attributes:
    +4150        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
    +4151            treated as a variable length argument and the argument's value will be stored as a list.
    +4152        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
    +4153            for this function expression. These values are used to map this node to a name during parsing
    +4154            as well as to provide the function's name during SQL string generation. By default the SQL
    +4155            name is set to the expression's class name transformed to snake case.
    +4156    """
    +4157
    +4158    is_var_len_args = False
    +4159
    +4160    @classmethod
    +4161    def from_arg_list(cls, args):
    +4162        if cls.is_var_len_args:
    +4163            all_arg_keys = list(cls.arg_types)
    +4164            # If this function supports variable length argument treat the last argument as such.
    +4165            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
    +4166            num_non_var = len(non_var_len_arg_keys)
    +4167
    +4168            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
    +4169            args_dict[all_arg_keys[-1]] = args[num_non_var:]
    +4170        else:
    +4171            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
    +4172
    +4173        return cls(**args_dict)
    +4174
    +4175    @classmethod
    +4176    def sql_names(cls):
    +4177        if cls is Func:
    +4178            raise NotImplementedError(
    +4179                "SQL name is only supported by concrete function implementations"
    +4180            )
    +4181        if "_sql_names" not in cls.__dict__:
    +4182            cls._sql_names = [camel_to_snake_case(cls.__name__)]
    +4183        return cls._sql_names
    +4184
    +4185    @classmethod
    +4186    def sql_name(cls):
    +4187        return cls.sql_names()[0]
    +4188
    +4189    @classmethod
    +4190    def default_parser_mappings(cls):
    +4191        return {name: cls.from_arg_list for name in cls.sql_names()}
     
    @@ -52323,20 +52736,20 @@ name is set to the expression's class name transformed to snake case.
    -
    4132    @classmethod
    -4133    def from_arg_list(cls, args):
    -4134        if cls.is_var_len_args:
    -4135            all_arg_keys = list(cls.arg_types)
    -4136            # If this function supports variable length argument treat the last argument as such.
    -4137            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
    -4138            num_non_var = len(non_var_len_arg_keys)
    -4139
    -4140            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
    -4141            args_dict[all_arg_keys[-1]] = args[num_non_var:]
    -4142        else:
    -4143            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
    -4144
    -4145        return cls(**args_dict)
    +            
    4160    @classmethod
    +4161    def from_arg_list(cls, args):
    +4162        if cls.is_var_len_args:
    +4163            all_arg_keys = list(cls.arg_types)
    +4164            # If this function supports variable length argument treat the last argument as such.
    +4165            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
    +4166            num_non_var = len(non_var_len_arg_keys)
    +4167
    +4168            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
    +4169            args_dict[all_arg_keys[-1]] = args[num_non_var:]
    +4170        else:
    +4171            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
    +4172
    +4173        return cls(**args_dict)
     
    @@ -52355,15 +52768,15 @@ name is set to the expression's class name transformed to snake case.
    -
    4147    @classmethod
    -4148    def sql_names(cls):
    -4149        if cls is Func:
    -4150            raise NotImplementedError(
    -4151                "SQL name is only supported by concrete function implementations"
    -4152            )
    -4153        if "_sql_names" not in cls.__dict__:
    -4154            cls._sql_names = [camel_to_snake_case(cls.__name__)]
    -4155        return cls._sql_names
    +            
    4175    @classmethod
    +4176    def sql_names(cls):
    +4177        if cls is Func:
    +4178            raise NotImplementedError(
    +4179                "SQL name is only supported by concrete function implementations"
    +4180            )
    +4181        if "_sql_names" not in cls.__dict__:
    +4182            cls._sql_names = [camel_to_snake_case(cls.__name__)]
    +4183        return cls._sql_names
     
    @@ -52382,9 +52795,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4157    @classmethod
    -4158    def sql_name(cls):
    -4159        return cls.sql_names()[0]
    +            
    4185    @classmethod
    +4186    def sql_name(cls):
    +4187        return cls.sql_names()[0]
     
    @@ -52403,9 +52816,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4161    @classmethod
    -4162    def default_parser_mappings(cls):
    -4163        return {name: cls.from_arg_list for name in cls.sql_names()}
    +            
    4189    @classmethod
    +4190    def default_parser_mappings(cls):
    +4191        return {name: cls.from_arg_list for name in cls.sql_names()}
     
    @@ -52505,8 +52918,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4166class AggFunc(Func):
    -4167    pass
    +            
    4194class AggFunc(Func):
    +4195    pass
     
    @@ -52613,8 +53026,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4170class ParameterizedAgg(AggFunc):
    -4171    arg_types = {"this": True, "expressions": True, "params": True}
    +            
    4198class ParameterizedAgg(AggFunc):
    +4199    arg_types = {"this": True, "expressions": True, "params": True}
     
    @@ -52732,8 +53145,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4174class Abs(Func):
    -4175    pass
    +            
    4202class Abs(Func):
    +4203    pass
     
    @@ -52825,6 +53238,365 @@ name is set to the expression's class name transformed to snake case.
    sql_name
    default_parser_mappings
    +
    + +
    +
    +
    + +
    + + class + ArgMax(AggFunc): + + + +
    + +
    4206class ArgMax(AggFunc):
    +4207    arg_types = {"this": True, "expression": True, "count": False}
    +4208    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
    +
    + + + + +
    +
    + arg_types = +{'this': True, 'expression': True, 'count': False} + + +
    + + + + +
    +
    +
    + key = +'argmax' + + +
    + + + + +
    + +
    +
    + +
    + + class + ArgMin(AggFunc): + + + +
    + +
    4211class ArgMin(AggFunc):
    +4212    arg_types = {"this": True, "expression": True, "count": False}
    +4213    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
    +
    + + + + +
    +
    + arg_types = +{'this': True, 'expression': True, 'count': False} + + +
    + + + + +
    +
    +
    + key = +'argmin' + + +
    + + + + +
    + +
    +
    + +
    + + class + ApproxTopK(AggFunc): + + + +
    + +
    4216class ApproxTopK(AggFunc):
    +4217    arg_types = {"this": True, "expression": False, "counters": False}
    +
    + + + + +
    +
    + arg_types = +{'this': True, 'expression': False, 'counters': False} + + +
    + + + + +
    +
    +
    + key = +'approxtopk' + + +
    + + + + +
    + @@ -52840,8 +53612,8 @@ name is set to the expression's class name transformed to snake case. -
    4178class Flatten(Func):
    -4179    pass
    +            
    4220class Flatten(Func):
    +4221    pass
     
    @@ -52948,8 +53720,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4183class Transform(Func):
    -4184    arg_types = {"this": True, "expression": True}
    +            
    4225class Transform(Func):
    +4226    arg_types = {"this": True, "expression": True}
     
    @@ -53067,9 +53839,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4187class Anonymous(Func):
    -4188    arg_types = {"this": True, "expressions": False}
    -4189    is_var_len_args = True
    +            
    4229class Anonymous(Func):
    +4230    arg_types = {"this": True, "expressions": False}
    +4231    is_var_len_args = True
     
    @@ -53198,9 +53970,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4194class Hll(AggFunc):
    -4195    arg_types = {"this": True, "expressions": False}
    -4196    is_var_len_args = True
    +            
    4236class Hll(AggFunc):
    +4237    arg_types = {"this": True, "expressions": False}
    +4238    is_var_len_args = True
     
    @@ -53329,9 +54101,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4199class ApproxDistinct(AggFunc):
    -4200    arg_types = {"this": True, "accuracy": False}
    -4201    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
    +            
    4241class ApproxDistinct(AggFunc):
    +4242    arg_types = {"this": True, "accuracy": False}
    +4243    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
     
    @@ -53449,9 +54221,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4204class Array(Func):
    -4205    arg_types = {"expressions": False}
    -4206    is_var_len_args = True
    +            
    4246class Array(Func):
    +4247    arg_types = {"expressions": False}
    +4248    is_var_len_args = True
     
    @@ -53580,8 +54352,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4210class ToChar(Func):
    -4211    arg_types = {"this": True, "format": False}
    +            
    4252class ToChar(Func):
    +4253    arg_types = {"this": True, "format": False}
     
    @@ -53699,8 +54471,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4214class GenerateSeries(Func):
    -4215    arg_types = {"start": True, "end": True, "step": False}
    +            
    4256class GenerateSeries(Func):
    +4257    arg_types = {"start": True, "end": True, "step": False}
     
    @@ -53818,8 +54590,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4218class ArrayAgg(AggFunc):
    -4219    pass
    +            
    4260class ArrayAgg(AggFunc):
    +4261    pass
     
    @@ -53926,8 +54698,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4222class ArrayAll(Func):
    -4223    arg_types = {"this": True, "expression": True}
    +            
    4264class ArrayAll(Func):
    +4265    arg_types = {"this": True, "expression": True}
     
    @@ -54045,8 +54817,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4226class ArrayAny(Func):
    -4227    arg_types = {"this": True, "expression": True}
    +            
    4268class ArrayAny(Func):
    +4269    arg_types = {"this": True, "expression": True}
     
    @@ -54164,10 +54936,10 @@ name is set to the expression's class name transformed to snake case.
    -
    4230class ArrayConcat(Func):
    -4231    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
    -4232    arg_types = {"this": True, "expressions": False}
    -4233    is_var_len_args = True
    +            
    4272class ArrayConcat(Func):
    +4273    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
    +4274    arg_types = {"this": True, "expressions": False}
    +4275    is_var_len_args = True
     
    @@ -54296,8 +55068,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4236class ArrayContains(Binary, Func):
    -4237    pass
    +            
    4278class ArrayContains(Binary, Func):
    +4279    pass
     
    @@ -54409,8 +55181,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4240class ArrayContained(Binary):
    -4241    pass
    +            
    4282class ArrayContained(Binary):
    +4283    pass
     
    @@ -54514,9 +55286,9 @@ name is set to the expression's class name transformed to snake case.
    -
    4244class ArrayFilter(Func):
    -4245    arg_types = {"this": True, "expression": True}
    -4246    _sql_names = ["FILTER", "ARRAY_FILTER"]
    +            
    4286class ArrayFilter(Func):
    +4287    arg_types = {"this": True, "expression": True}
    +4288    _sql_names = ["FILTER", "ARRAY_FILTER"]
     
    @@ -54634,8 +55406,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4249class ArrayJoin(Func):
    -4250    arg_types = {"this": True, "expression": True, "null": False}
    +            
    4291class ArrayJoin(Func):
    +4292    arg_types = {"this": True, "expression": True, "null": False}
     
    @@ -54753,8 +55525,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4253class ArraySize(Func):
    -4254    arg_types = {"this": True, "expression": False}
    +            
    4295class ArraySize(Func):
    +4296    arg_types = {"this": True, "expression": False}
     
    @@ -54872,8 +55644,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4257class ArraySort(Func):
    -4258    arg_types = {"this": True, "expression": False}
    +            
    4299class ArraySort(Func):
    +4300    arg_types = {"this": True, "expression": False}
     
    @@ -54991,8 +55763,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4261class ArraySum(Func):
    -4262    pass
    +            
    4303class ArraySum(Func):
    +4304    pass
     
    @@ -55099,8 +55871,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4265class ArrayUnionAgg(AggFunc):
    -4266    pass
    +            
    4307class ArrayUnionAgg(AggFunc):
    +4308    pass
     
    @@ -55207,8 +55979,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4269class Avg(AggFunc):
    -4270    pass
    +            
    4311class Avg(AggFunc):
    +4312    pass
     
    @@ -55315,8 +56087,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4273class AnyValue(AggFunc):
    -4274    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
    +            
    4315class AnyValue(AggFunc):
    +4316    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
     
    @@ -55434,8 +56206,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4277class First(Func):
    -4278    arg_types = {"this": True, "ignore_nulls": False}
    +            
    4319class First(Func):
    +4320    arg_types = {"this": True, "ignore_nulls": False}
     
    @@ -55553,8 +56325,8 @@ name is set to the expression's class name transformed to snake case.
    -
    4281class Last(Func):
    -4282    arg_types = {"this": True, "ignore_nulls": False}
    +            
    4323class Last(Func):
    +4324    arg_types = {"this": True, "ignore_nulls": False}
     
    @@ -55672,24 +56444,24 @@ name is set to the expression's class name transformed to snake case.
    -
    4285class Case(Func):
    -4286    arg_types = {"this": False, "ifs": True, "default": False}
    -4287
    -4288    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
    -4289        instance = maybe_copy(self, copy)
    -4290        instance.append(
    -4291            "ifs",
    -4292            If(
    -4293                this=maybe_parse(condition, copy=copy, **opts),
    -4294                true=maybe_parse(then, copy=copy, **opts),
    -4295            ),
    -4296        )
    -4297        return instance
    -4298
    -4299    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
    -4300        instance = maybe_copy(self, copy)
    -4301        instance.set("default", maybe_parse(condition, copy=copy, **opts))
    -4302        return instance
    +            
    4327class Case(Func):
    +4328    arg_types = {"this": False, "ifs": True, "default": False}
    +4329
    +4330    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
    +4331        instance = maybe_copy(self, copy)
    +4332        instance.append(
    +4333            "ifs",
    +4334            If(
    +4335                this=maybe_parse(condition, copy=copy, **opts),
    +4336                true=maybe_parse(then, copy=copy, **opts),
    +4337            ),
    +4338        )
    +4339        return instance
    +4340
    +4341    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
    +4342        instance = maybe_copy(self, copy)
    +4343        instance.set("default", maybe_parse(condition, copy=copy, **opts))
    +4344        return instance
     
    @@ -55718,16 +56490,16 @@ name is set to the expression's class name transformed to snake case.
    -
    4288    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
    -4289        instance = maybe_copy(self, copy)
    -4290        instance.append(
    -4291            "ifs",
    -4292            If(
    -4293                this=maybe_parse(condition, copy=copy, **opts),
    -4294                true=maybe_parse(then, copy=copy, **opts),
    -4295            ),
    -4296        )
    -4297        return instance
    +            
    4330    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
    +4331        instance = maybe_copy(self, copy)
    +4332        instance.append(
    +4333            "ifs",
    +4334            If(
    +4335                this=maybe_parse(condition, copy=copy, **opts),
    +4336                true=maybe_parse(then, copy=copy, **opts),
    +4337            ),
    +4338        )
    +4339        return instance
     
    @@ -55745,10 +56517,10 @@ name is set to the expression's class name transformed to snake case.
    -
    4299    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
    -4300        instance = maybe_copy(self, copy)
    -4301        instance.set("default", maybe_parse(condition, copy=copy, **opts))
    -4302        return instance
    +            
    4341    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
    +4342        instance = maybe_copy(self, copy)
    +4343        instance.set("default", maybe_parse(condition, copy=copy, **opts))
    +4344        return instance
     
    @@ -55855,34 +56627,34 @@ name is set to the expression's class name transformed to snake case.
    -
    4305class Cast(Func):
    -4306    arg_types = {"this": True, "to": True, "format": False, "safe": False}
    -4307
    -4308    @property
    -4309    def name(self) -> str:
    -4310        return self.this.name
    -4311
    -4312    @property
    -4313    def to(self) -> DataType:
    -4314        return self.args["to"]
    -4315
    -4316    @property
    -4317    def output_name(self) -> str:
    -4318        return self.name
    -4319
    -4320    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    -4321        """
    -4322        Checks whether this Cast's DataType matches one of the provided data types. Nested types
    -4323        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
    -4324        array<int> != array<float>.
    -4325
    -4326        Args:
    -4327            dtypes: the data types to compare this Cast's DataType to.
    -4328
    -4329        Returns:
    -4330            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
    -4331        """
    -4332        return self.to.is_type(*dtypes)
    +            
    4347class Cast(Func):
    +4348    arg_types = {"this": True, "to": True, "format": False, "safe": False}
    +4349
    +4350    @property
    +4351    def name(self) -> str:
    +4352        return self.this.name
    +4353
    +4354    @property
    +4355    def to(self) -> DataType:
    +4356        return self.args["to"]
    +4357
    +4358    @property
    +4359    def output_name(self) -> str:
    +4360        return self.name
    +4361
    +4362    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    +4363        """
    +4364        Checks whether this Cast's DataType matches one of the provided data types. Nested types
    +4365        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
    +4366        array<int> != array<float>.
    +4367
    +4368        Args:
    +4369            dtypes: the data types to compare this Cast's DataType to.
    +4370
    +4371        Returns:
    +4372            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
    +4373        """
    +4374        return self.to.is_type(*dtypes)
     
    @@ -55963,19 +56735,19 @@ name is set to the expression's class name transformed to snake case.
    -
    4320    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    -4321        """
    -4322        Checks whether this Cast's DataType matches one of the provided data types. Nested types
    -4323        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
    -4324        array<int> != array<float>.
    -4325
    -4326        Args:
    -4327            dtypes: the data types to compare this Cast's DataType to.
    -4328
    -4329        Returns:
    -4330            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
    -4331        """
    -4332        return self.to.is_type(*dtypes)
    +            
    4362    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
    +4363        """
    +4364        Checks whether this Cast's DataType matches one of the provided data types. Nested types
    +4365        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
    +4366        array<int> != array<float>.
    +4367
    +4368        Args:
    +4369            dtypes: the data types to compare this Cast's DataType to.
    +4370
    +4371        Returns:
    +4372            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
    +4373        """
    +4374        return self.to.is_type(*dtypes)
     
    @@ -56096,8 +56868,8 @@ array != array.

    -
    4335class TryCast(Cast):
    -4336    pass
    +            
    4377class TryCast(Cast):
    +4378    pass
     
    @@ -56209,8 +56981,8 @@ array != array.

    -
    4339class CastToStrType(Func):
    -4340    arg_types = {"this": True, "to": True}
    +            
    4381class CastToStrType(Func):
    +4382    arg_types = {"this": True, "to": True}
     
    @@ -56328,8 +57100,8 @@ array != array.

    -
    4343class Collate(Binary, Func):
    -4344    pass
    +            
    4385class Collate(Binary, Func):
    +4386    pass
     
    @@ -56441,9 +57213,9 @@ array != array.

    -
    4347class Ceil(Func):
    -4348    arg_types = {"this": True, "decimals": False}
    -4349    _sql_names = ["CEIL", "CEILING"]
    +            
    4389class Ceil(Func):
    +4390    arg_types = {"this": True, "decimals": False}
    +4391    _sql_names = ["CEIL", "CEILING"]
     
    @@ -56561,10 +57333,10 @@ array != array.

    -
    4352class Coalesce(Func):
    -4353    arg_types = {"this": True, "expressions": False}
    -4354    is_var_len_args = True
    -4355    _sql_names = ["COALESCE", "IFNULL", "NVL"]
    +            
    4394class Coalesce(Func):
    +4395    arg_types = {"this": True, "expressions": False}
    +4396    is_var_len_args = True
    +4397    _sql_names = ["COALESCE", "IFNULL", "NVL"]
     
    @@ -56693,10 +57465,10 @@ array != array.

    -
    4358class Chr(Func):
    -4359    arg_types = {"this": True, "charset": False, "expressions": False}
    -4360    is_var_len_args = True
    -4361    _sql_names = ["CHR", "CHAR"]
    +            
    4400class Chr(Func):
    +4401    arg_types = {"this": True, "charset": False, "expressions": False}
    +4402    is_var_len_args = True
    +4403    _sql_names = ["CHR", "CHAR"]
     
    @@ -56825,9 +57597,9 @@ array != array.

    -
    4364class Concat(Func):
    -4365    arg_types = {"expressions": True}
    -4366    is_var_len_args = True
    +            
    4406class Concat(Func):
    +4407    arg_types = {"expressions": True}
    +4408    is_var_len_args = True
     
    @@ -56956,8 +57728,8 @@ array != array.

    -
    4369class SafeConcat(Concat):
    -4370    pass
    +            
    4411class SafeConcat(Concat):
    +4412    pass
     
    @@ -57067,8 +57839,8 @@ array != array.

    -
    4373class ConcatWs(Concat):
    -4374    _sql_names = ["CONCAT_WS"]
    +            
    4415class ConcatWs(Concat):
    +4416    _sql_names = ["CONCAT_WS"]
     
    @@ -57178,9 +57950,9 @@ array != array.

    -
    4377class Count(AggFunc):
    -4378    arg_types = {"this": False, "expressions": False}
    -4379    is_var_len_args = True
    +            
    4419class Count(AggFunc):
    +4420    arg_types = {"this": False, "expressions": False}
    +4421    is_var_len_args = True
     
    @@ -57309,8 +58081,8 @@ array != array.

    -
    4382class CountIf(AggFunc):
    -4383    pass
    +            
    4424class CountIf(AggFunc):
    +4425    pass
     
    @@ -57417,8 +58189,8 @@ array != array.

    -
    4386class CurrentDate(Func):
    -4387    arg_types = {"this": False}
    +            
    4428class CurrentDate(Func):
    +4429    arg_types = {"this": False}
     
    @@ -57536,8 +58308,8 @@ array != array.

    -
    4390class CurrentDatetime(Func):
    -4391    arg_types = {"this": False}
    +            
    4432class CurrentDatetime(Func):
    +4433    arg_types = {"this": False}
     
    @@ -57655,8 +58427,8 @@ array != array.

    -
    4394class CurrentTime(Func):
    -4395    arg_types = {"this": False}
    +            
    4436class CurrentTime(Func):
    +4437    arg_types = {"this": False}
     
    @@ -57774,8 +58546,8 @@ array != array.

    -
    4398class CurrentTimestamp(Func):
    -4399    arg_types = {"this": False}
    +            
    4440class CurrentTimestamp(Func):
    +4441    arg_types = {"this": False}
     
    @@ -57893,8 +58665,8 @@ array != array.

    -
    4402class CurrentUser(Func):
    -4403    arg_types = {"this": False}
    +            
    4444class CurrentUser(Func):
    +4445    arg_types = {"this": False}
     
    @@ -58012,8 +58784,8 @@ array != array.

    -
    4406class DateAdd(Func, IntervalOp):
    -4407    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4448class DateAdd(Func, IntervalOp):
    +4449    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58048,6 +58820,8 @@ array != array.

    @@ -58139,8 +58913,8 @@ array != array.

    -
    4410class DateSub(Func, IntervalOp):
    -4411    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4452class DateSub(Func, IntervalOp):
    +4453    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58175,6 +58949,8 @@ array != array.

    @@ -58266,9 +59042,9 @@ array != array.

    -
    4414class DateDiff(Func, TimeUnit):
    -4415    _sql_names = ["DATEDIFF", "DATE_DIFF"]
    -4416    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4456class DateDiff(Func, TimeUnit):
    +4457    _sql_names = ["DATEDIFF", "DATE_DIFF"]
    +4458    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58303,6 +59079,8 @@ array != array.

    @@ -58390,12 +59168,12 @@ array != array.

    -
    4419class DateTrunc(Func):
    -4420    arg_types = {"unit": True, "this": True, "zone": False}
    -4421
    -4422    @property
    -4423    def unit(self) -> Expression:
    -4424        return self.args["unit"]
    +            
    4461class DateTrunc(Func):
    +4462    arg_types = {"unit": True, "this": True, "zone": False}
    +4463
    +4464    @property
    +4465    def unit(self) -> Expression:
    +4466        return self.args["unit"]
     
    @@ -58524,8 +59302,8 @@ array != array.

    -
    4427class DatetimeAdd(Func, IntervalOp):
    -4428    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4469class DatetimeAdd(Func, IntervalOp):
    +4470    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58560,6 +59338,8 @@ array != array.

    @@ -58651,8 +59431,8 @@ array != array.

    -
    4431class DatetimeSub(Func, IntervalOp):
    -4432    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4473class DatetimeSub(Func, IntervalOp):
    +4474    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58687,6 +59467,8 @@ array != array.

    @@ -58778,8 +59560,8 @@ array != array.

    -
    4435class DatetimeDiff(Func, TimeUnit):
    -4436    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4477class DatetimeDiff(Func, TimeUnit):
    +4478    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -58814,6 +59596,8 @@ array != array.

    @@ -58901,8 +59685,8 @@ array != array.

    -
    4439class DatetimeTrunc(Func, TimeUnit):
    -4440    arg_types = {"this": True, "unit": True, "zone": False}
    +            
    4481class DatetimeTrunc(Func, TimeUnit):
    +4482    arg_types = {"this": True, "unit": True, "zone": False}
     
    @@ -58937,6 +59721,8 @@ array != array.

    @@ -59024,8 +59810,8 @@ array != array.

    -
    4443class DayOfWeek(Func):
    -4444    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
    +            
    4485class DayOfWeek(Func):
    +4486    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
     
    @@ -59132,8 +59918,8 @@ array != array.

    -
    4447class DayOfMonth(Func):
    -4448    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
    +            
    4489class DayOfMonth(Func):
    +4490    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
     
    @@ -59240,8 +60026,8 @@ array != array.

    -
    4451class DayOfYear(Func):
    -4452    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
    +            
    4493class DayOfYear(Func):
    +4494    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
     
    @@ -59348,8 +60134,8 @@ array != array.

    -
    4455class ToDays(Func):
    -4456    pass
    +            
    4497class ToDays(Func):
    +4498    pass
     
    @@ -59456,8 +60242,8 @@ array != array.

    -
    4459class WeekOfYear(Func):
    -4460    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
    +            
    4501class WeekOfYear(Func):
    +4502    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
     
    @@ -59564,8 +60350,8 @@ array != array.

    -
    4463class MonthsBetween(Func):
    -4464    arg_types = {"this": True, "expression": True, "roundoff": False}
    +            
    4505class MonthsBetween(Func):
    +4506    arg_types = {"this": True, "expression": True, "roundoff": False}
     
    @@ -59683,8 +60469,8 @@ array != array.

    -
    4467class LastDateOfMonth(Func):
    -4468    pass
    +            
    4509class LastDateOfMonth(Func):
    +4510    pass
     
    @@ -59791,8 +60577,8 @@ array != array.

    -
    4471class Extract(Func):
    -4472    arg_types = {"this": True, "expression": True}
    +            
    4513class Extract(Func):
    +4514    arg_types = {"this": True, "expression": True}
     
    @@ -59910,8 +60696,8 @@ array != array.

    -
    4475class Timestamp(Func):
    -4476    arg_types = {"this": False, "expression": False}
    +            
    4517class Timestamp(Func):
    +4518    arg_types = {"this": False, "expression": False}
     
    @@ -60029,8 +60815,8 @@ array != array.

    -
    4479class TimestampAdd(Func, TimeUnit):
    -4480    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4521class TimestampAdd(Func, TimeUnit):
    +4522    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60065,6 +60851,8 @@ array != array.

    @@ -60152,8 +60940,8 @@ array != array.

    -
    4483class TimestampSub(Func, TimeUnit):
    -4484    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4525class TimestampSub(Func, TimeUnit):
    +4526    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60188,6 +60976,8 @@ array != array.

    @@ -60275,8 +61065,8 @@ array != array.

    -
    4487class TimestampDiff(Func, TimeUnit):
    -4488    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4529class TimestampDiff(Func, TimeUnit):
    +4530    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60311,6 +61101,8 @@ array != array.

    @@ -60398,8 +61190,8 @@ array != array.

    -
    4491class TimestampTrunc(Func, TimeUnit):
    -4492    arg_types = {"this": True, "unit": True, "zone": False}
    +            
    4533class TimestampTrunc(Func, TimeUnit):
    +4534    arg_types = {"this": True, "unit": True, "zone": False}
     
    @@ -60434,6 +61226,8 @@ array != array.

    @@ -60521,8 +61315,8 @@ array != array.

    -
    4495class TimeAdd(Func, TimeUnit):
    -4496    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4537class TimeAdd(Func, TimeUnit):
    +4538    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60557,6 +61351,8 @@ array != array.

    @@ -60644,8 +61440,8 @@ array != array.

    -
    4499class TimeSub(Func, TimeUnit):
    -4500    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4541class TimeSub(Func, TimeUnit):
    +4542    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60680,6 +61476,8 @@ array != array.

    @@ -60767,8 +61565,8 @@ array != array.

    -
    4503class TimeDiff(Func, TimeUnit):
    -4504    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    4545class TimeDiff(Func, TimeUnit):
    +4546    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -60803,6 +61601,8 @@ array != array.

    @@ -60890,8 +61690,8 @@ array != array.

    -
    4507class TimeTrunc(Func, TimeUnit):
    -4508    arg_types = {"this": True, "unit": True, "zone": False}
    +            
    4549class TimeTrunc(Func, TimeUnit):
    +4550    arg_types = {"this": True, "unit": True, "zone": False}
     
    @@ -60926,6 +61726,8 @@ array != array.

    @@ -61013,9 +61815,9 @@ array != array.

    -
    4511class DateFromParts(Func):
    -4512    _sql_names = ["DATEFROMPARTS"]
    -4513    arg_types = {"year": True, "month": True, "day": True}
    +            
    4553class DateFromParts(Func):
    +4554    _sql_names = ["DATEFROMPARTS"]
    +4555    arg_types = {"year": True, "month": True, "day": True}
     
    @@ -61133,8 +61935,8 @@ array != array.

    -
    4516class DateStrToDate(Func):
    -4517    pass
    +            
    4558class DateStrToDate(Func):
    +4559    pass
     
    @@ -61241,8 +62043,8 @@ array != array.

    -
    4520class DateToDateStr(Func):
    -4521    pass
    +            
    4562class DateToDateStr(Func):
    +4563    pass
     
    @@ -61349,8 +62151,8 @@ array != array.

    -
    4524class DateToDi(Func):
    -4525    pass
    +            
    4566class DateToDi(Func):
    +4567    pass
     
    @@ -61457,9 +62259,9 @@ array != array.

    -
    4529class Date(Func):
    -4530    arg_types = {"this": False, "zone": False, "expressions": False}
    -4531    is_var_len_args = True
    +            
    4571class Date(Func):
    +4572    arg_types = {"this": False, "zone": False, "expressions": False}
    +4573    is_var_len_args = True
     
    @@ -61588,8 +62390,8 @@ array != array.

    -
    4534class Day(Func):
    -4535    pass
    +            
    4576class Day(Func):
    +4577    pass
     
    @@ -61696,8 +62498,8 @@ array != array.

    -
    4538class Decode(Func):
    -4539    arg_types = {"this": True, "charset": True, "replace": False}
    +            
    4580class Decode(Func):
    +4581    arg_types = {"this": True, "charset": True, "replace": False}
     
    @@ -61815,8 +62617,8 @@ array != array.

    -
    4542class DiToDate(Func):
    -4543    pass
    +            
    4584class DiToDate(Func):
    +4585    pass
     
    @@ -61923,8 +62725,8 @@ array != array.

    -
    4546class Encode(Func):
    -4547    arg_types = {"this": True, "charset": True}
    +            
    4588class Encode(Func):
    +4589    arg_types = {"this": True, "charset": True}
     
    @@ -62042,8 +62844,8 @@ array != array.

    -
    4550class Exp(Func):
    -4551    pass
    +            
    4592class Exp(Func):
    +4593    pass
     
    @@ -62150,9 +62952,9 @@ array != array.

    -
    4555class Explode(Func):
    -4556    arg_types = {"this": True, "expressions": False}
    -4557    is_var_len_args = True
    +            
    4597class Explode(Func):
    +4598    arg_types = {"this": True, "expressions": False}
    +4599    is_var_len_args = True
     
    @@ -62281,8 +63083,8 @@ array != array.

    -
    4560class ExplodeOuter(Explode):
    -4561    pass
    +            
    4602class ExplodeOuter(Explode):
    +4603    pass
     
    @@ -62392,8 +63194,8 @@ array != array.

    -
    4564class Posexplode(Explode):
    -4565    pass
    +            
    4606class Posexplode(Explode):
    +4607    pass
     
    @@ -62503,8 +63305,8 @@ array != array.

    -
    4568class PosexplodeOuter(Posexplode):
    -4569    pass
    +            
    4610class PosexplodeOuter(Posexplode):
    +4611    pass
     
    @@ -62614,8 +63416,8 @@ array != array.

    -
    4572class Floor(Func):
    -4573    arg_types = {"this": True, "decimals": False}
    +            
    4614class Floor(Func):
    +4615    arg_types = {"this": True, "decimals": False}
     
    @@ -62733,8 +63535,8 @@ array != array.

    -
    4576class FromBase64(Func):
    -4577    pass
    +            
    4618class FromBase64(Func):
    +4619    pass
     
    @@ -62841,8 +63643,8 @@ array != array.

    -
    4580class ToBase64(Func):
    -4581    pass
    +            
    4622class ToBase64(Func):
    +4623    pass
     
    @@ -62949,9 +63751,9 @@ array != array.

    -
    4584class Greatest(Func):
    -4585    arg_types = {"this": True, "expressions": False}
    -4586    is_var_len_args = True
    +            
    4626class Greatest(Func):
    +4627    arg_types = {"this": True, "expressions": False}
    +4628    is_var_len_args = True
     
    @@ -63080,8 +63882,8 @@ array != array.

    -
    4589class GroupConcat(AggFunc):
    -4590    arg_types = {"this": True, "separator": False}
    +            
    4631class GroupConcat(AggFunc):
    +4632    arg_types = {"this": True, "separator": False}
     
    @@ -63199,8 +64001,8 @@ array != array.

    -
    4593class Hex(Func):
    -4594    pass
    +            
    4635class Hex(Func):
    +4636    pass
     
    @@ -63307,8 +64109,8 @@ array != array.

    -
    4597class Xor(Connector, Func):
    -4598    arg_types = {"this": False, "expression": False, "expressions": False}
    +            
    4639class Xor(Connector, Func):
    +4640    arg_types = {"this": False, "expression": False, "expressions": False}
     
    @@ -63431,8 +64233,8 @@ array != array.

    -
    4601class If(Func):
    -4602    arg_types = {"this": True, "true": True, "false": False}
    +            
    4643class If(Func):
    +4644    arg_types = {"this": True, "true": True, "false": False}
     
    @@ -63550,8 +64352,8 @@ array != array.

    -
    4605class Initcap(Func):
    -4606    arg_types = {"this": True, "expression": False}
    +            
    4647class Initcap(Func):
    +4648    arg_types = {"this": True, "expression": False}
     
    @@ -63669,8 +64471,8 @@ array != array.

    -
    4609class IsNan(Func):
    -4610    _sql_names = ["IS_NAN", "ISNAN"]
    +            
    4651class IsNan(Func):
    +4652    _sql_names = ["IS_NAN", "ISNAN"]
     
    @@ -63777,8 +64579,8 @@ array != array.

    -
    4613class FormatJson(Expression):
    -4614    pass
    +            
    4655class FormatJson(Expression):
    +4656    pass
     
    @@ -63877,8 +64679,8 @@ array != array.

    -
    4617class JSONKeyValue(Expression):
    -4618    arg_types = {"this": True, "expression": True}
    +            
    4659class JSONKeyValue(Expression):
    +4660    arg_types = {"this": True, "expression": True}
     
    @@ -63988,14 +64790,14 @@ array != array.

    -
    4621class JSONObject(Func):
    -4622    arg_types = {
    -4623        "expressions": False,
    -4624        "null_handling": False,
    -4625        "unique_keys": False,
    -4626        "return_type": False,
    -4627        "encoding": False,
    -4628    }
    +            
    4663class JSONObject(Func):
    +4664    arg_types = {
    +4665        "expressions": False,
    +4666        "null_handling": False,
    +4667        "unique_keys": False,
    +4668        "return_type": False,
    +4669        "encoding": False,
    +4670    }
     
    @@ -64114,13 +64916,13 @@ array != array.

    -
    4632class JSONArray(Func):
    -4633    arg_types = {
    -4634        "expressions": True,
    -4635        "null_handling": False,
    -4636        "return_type": False,
    -4637        "strict": False,
    -4638    }
    +            
    4674class JSONArray(Func):
    +4675    arg_types = {
    +4676        "expressions": True,
    +4677        "null_handling": False,
    +4678        "return_type": False,
    +4679        "strict": False,
    +4680    }
     
    @@ -64238,14 +65040,14 @@ array != array.

    -
    4642class JSONArrayAgg(Func):
    -4643    arg_types = {
    -4644        "this": True,
    -4645        "order": False,
    -4646        "null_handling": False,
    -4647        "return_type": False,
    -4648        "strict": False,
    -4649    }
    +            
    4684class JSONArrayAgg(Func):
    +4685    arg_types = {
    +4686        "this": True,
    +4687        "order": False,
    +4688        "null_handling": False,
    +4689        "return_type": False,
    +4690        "strict": False,
    +4691    }
     
    @@ -64363,8 +65165,8 @@ array != array.

    -
    4654class JSONColumnDef(Expression):
    -4655    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
    +            
    4696class JSONColumnDef(Expression):
    +4697    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
     
    @@ -64474,8 +65276,8 @@ array != array.

    -
    4658class JSONSchema(Expression):
    -4659    arg_types = {"expressions": True}
    +            
    4700class JSONSchema(Expression):
    +4701    arg_types = {"expressions": True}
     
    @@ -64585,14 +65387,14 @@ array != array.

    -
    4663class JSONTable(Func):
    -4664    arg_types = {
    -4665        "this": True,
    -4666        "schema": True,
    -4667        "path": False,
    -4668        "error_handling": False,
    -4669        "empty_handling": False,
    -4670    }
    +            
    4705class JSONTable(Func):
    +4706    arg_types = {
    +4707        "this": True,
    +4708        "schema": True,
    +4709        "path": False,
    +4710        "error_handling": False,
    +4711        "empty_handling": False,
    +4712    }
     
    @@ -64710,8 +65512,8 @@ array != array.

    -
    4673class OpenJSONColumnDef(Expression):
    -4674    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
    +            
    4715class OpenJSONColumnDef(Expression):
    +4716    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
     
    @@ -64821,8 +65623,8 @@ array != array.

    -
    4677class OpenJSON(Func):
    -4678    arg_types = {"this": True, "path": False, "expressions": False}
    +            
    4719class OpenJSON(Func):
    +4720    arg_types = {"this": True, "path": False, "expressions": False}
     
    @@ -64940,8 +65742,8 @@ array != array.

    -
    4681class JSONBContains(Binary):
    -4682    _sql_names = ["JSONB_CONTAINS"]
    +            
    4723class JSONBContains(Binary):
    +4724    _sql_names = ["JSONB_CONTAINS"]
     
    @@ -65045,8 +65847,8 @@ array != array.

    -
    4685class JSONExtract(Binary, Func):
    -4686    _sql_names = ["JSON_EXTRACT"]
    +            
    4727class JSONExtract(Binary, Func):
    +4728    _sql_names = ["JSON_EXTRACT"]
     
    @@ -65158,8 +65960,8 @@ array != array.

    -
    4689class JSONExtractScalar(JSONExtract):
    -4690    _sql_names = ["JSON_EXTRACT_SCALAR"]
    +            
    4731class JSONExtractScalar(JSONExtract):
    +4732    _sql_names = ["JSON_EXTRACT_SCALAR"]
     
    @@ -65271,8 +66073,8 @@ array != array.

    -
    4693class JSONBExtract(JSONExtract):
    -4694    _sql_names = ["JSONB_EXTRACT"]
    +            
    4735class JSONBExtract(JSONExtract):
    +4736    _sql_names = ["JSONB_EXTRACT"]
     
    @@ -65384,8 +66186,8 @@ array != array.

    -
    4697class JSONBExtractScalar(JSONExtract):
    -4698    _sql_names = ["JSONB_EXTRACT_SCALAR"]
    +            
    4739class JSONBExtractScalar(JSONExtract):
    +4740    _sql_names = ["JSONB_EXTRACT_SCALAR"]
     
    @@ -65497,9 +66299,9 @@ array != array.

    -
    4701class JSONFormat(Func):
    -4702    arg_types = {"this": False, "options": False}
    -4703    _sql_names = ["JSON_FORMAT"]
    +            
    4743class JSONFormat(Func):
    +4744    arg_types = {"this": False, "options": False}
    +4745    _sql_names = ["JSON_FORMAT"]
     
    @@ -65617,8 +66419,8 @@ array != array.

    -
    4707class JSONArrayContains(Binary, Predicate, Func):
    -4708    _sql_names = ["JSON_ARRAY_CONTAINS"]
    +            
    4749class JSONArrayContains(Binary, Predicate, Func):
    +4750    _sql_names = ["JSON_ARRAY_CONTAINS"]
     
    @@ -65730,11 +66532,11 @@ array != array.

    -
    4711class ParseJSON(Func):
    -4712    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
    -4713    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
    -4714    arg_types = {"this": True, "expressions": False}
    -4715    is_var_len_args = True
    +            
    4753class ParseJSON(Func):
    +4754    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
    +4755    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
    +4756    arg_types = {"this": True, "expressions": False}
    +4757    is_var_len_args = True
     
    @@ -65863,9 +66665,9 @@ array != array.

    -
    4718class Least(Func):
    -4719    arg_types = {"this": True, "expressions": False}
    -4720    is_var_len_args = True
    +            
    4760class Least(Func):
    +4761    arg_types = {"this": True, "expressions": False}
    +4762    is_var_len_args = True
     
    @@ -65994,8 +66796,8 @@ array != array.

    -
    4723class Left(Func):
    -4724    arg_types = {"this": True, "expression": True}
    +            
    4765class Left(Func):
    +4766    arg_types = {"this": True, "expression": True}
     
    @@ -66113,8 +66915,8 @@ array != array.

    -
    4727class Right(Func):
    -4728    arg_types = {"this": True, "expression": True}
    +            
    4769class Right(Func):
    +4770    arg_types = {"this": True, "expression": True}
     
    @@ -66232,8 +67034,8 @@ array != array.

    -
    4731class Length(Func):
    -4732    _sql_names = ["LENGTH", "LEN"]
    +            
    4773class Length(Func):
    +4774    _sql_names = ["LENGTH", "LEN"]
     
    @@ -66340,14 +67142,14 @@ array != array.

    -
    4735class Levenshtein(Func):
    -4736    arg_types = {
    -4737        "this": True,
    -4738        "expression": False,
    -4739        "ins_cost": False,
    -4740        "del_cost": False,
    -4741        "sub_cost": False,
    -4742    }
    +            
    4777class Levenshtein(Func):
    +4778    arg_types = {
    +4779        "this": True,
    +4780        "expression": False,
    +4781        "ins_cost": False,
    +4782        "del_cost": False,
    +4783        "sub_cost": False,
    +4784    }
     
    @@ -66465,8 +67267,8 @@ array != array.

    -
    4745class Ln(Func):
    -4746    pass
    +            
    4787class Ln(Func):
    +4788    pass
     
    @@ -66573,8 +67375,8 @@ array != array.

    -
    4749class Log(Func):
    -4750    arg_types = {"this": True, "expression": False}
    +            
    4791class Log(Func):
    +4792    arg_types = {"this": True, "expression": False}
     
    @@ -66692,8 +67494,8 @@ array != array.

    -
    4753class Log2(Func):
    -4754    pass
    +            
    4795class Log2(Func):
    +4796    pass
     
    @@ -66800,8 +67602,8 @@ array != array.

    -
    4757class Log10(Func):
    -4758    pass
    +            
    4799class Log10(Func):
    +4800    pass
     
    @@ -66908,8 +67710,8 @@ array != array.

    -
    4761class LogicalOr(AggFunc):
    -4762    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
    +            
    4803class LogicalOr(AggFunc):
    +4804    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
     
    @@ -67016,8 +67818,8 @@ array != array.

    -
    4765class LogicalAnd(AggFunc):
    -4766    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
    +            
    4807class LogicalAnd(AggFunc):
    +4808    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
     
    @@ -67124,8 +67926,8 @@ array != array.

    -
    4769class Lower(Func):
    -4770    _sql_names = ["LOWER", "LCASE"]
    +            
    4811class Lower(Func):
    +4812    _sql_names = ["LOWER", "LCASE"]
     
    @@ -67232,8 +68034,18 @@ array != array.

    -
    4773class Map(Func):
    -4774    arg_types = {"keys": False, "values": False}
    +            
    4815class Map(Func):
    +4816    arg_types = {"keys": False, "values": False}
    +4817
    +4818    @property
    +4819    def keys(self) -> t.List[Expression]:
    +4820        keys = self.args.get("keys")
    +4821        return keys.expressions if keys else []
    +4822
    +4823    @property
    +4824    def values(self) -> t.List[Expression]:
    +4825        values = self.args.get("values")
    +4826        return values.expressions if values else []
     
    @@ -67250,6 +68062,28 @@ array != array.

    +
    +
    +
    + keys: List[Expression] + + +
    + + + + +
    +
    +
    + values: List[Expression] + + +
    + + + +
    @@ -67351,8 +68185,8 @@ array != array.

    -
    4777class MapFromEntries(Func):
    -4778    pass
    +            
    4829class MapFromEntries(Func):
    +4830    pass
     
    @@ -67459,8 +68293,8 @@ array != array.

    -
    4781class StarMap(Func):
    -4782    pass
    +            
    4833class StarMap(Func):
    +4834    pass
     
    @@ -67567,17 +68401,17 @@ array != array.

    -
    4785class VarMap(Func):
    -4786    arg_types = {"keys": True, "values": True}
    -4787    is_var_len_args = True
    -4788
    -4789    @property
    -4790    def keys(self) -> t.List[Expression]:
    -4791        return self.args["keys"].expressions
    -4792
    -4793    @property
    -4794    def values(self) -> t.List[Expression]:
    -4795        return self.args["values"].expressions
    +            
    4837class VarMap(Func):
    +4838    arg_types = {"keys": True, "values": True}
    +4839    is_var_len_args = True
    +4840
    +4841    @property
    +4842    def keys(self) -> t.List[Expression]:
    +4843        return self.args["keys"].expressions
    +4844
    +4845    @property
    +4846    def values(self) -> t.List[Expression]:
    +4847        return self.args["values"].expressions
     
    @@ -67728,8 +68562,8 @@ array != array.

    -
    4799class MatchAgainst(Func):
    -4800    arg_types = {"this": True, "expressions": True, "modifier": False}
    +            
    4851class MatchAgainst(Func):
    +4852    arg_types = {"this": True, "expressions": True, "modifier": False}
     
    @@ -67847,9 +68681,9 @@ array != array.

    -
    4803class Max(AggFunc):
    -4804    arg_types = {"this": True, "expressions": False}
    -4805    is_var_len_args = True
    +            
    4855class Max(AggFunc):
    +4856    arg_types = {"this": True, "expressions": False}
    +4857    is_var_len_args = True
     
    @@ -67978,8 +68812,8 @@ array != array.

    -
    4808class MD5(Func):
    -4809    _sql_names = ["MD5"]
    +            
    4860class MD5(Func):
    +4861    _sql_names = ["MD5"]
     
    @@ -68086,8 +68920,8 @@ array != array.

    -
    4813class MD5Digest(Func):
    -4814    _sql_names = ["MD5_DIGEST"]
    +            
    4865class MD5Digest(Func):
    +4866    _sql_names = ["MD5_DIGEST"]
     
    @@ -68194,9 +69028,9 @@ array != array.

    -
    4817class Min(AggFunc):
    -4818    arg_types = {"this": True, "expressions": False}
    -4819    is_var_len_args = True
    +            
    4869class Min(AggFunc):
    +4870    arg_types = {"this": True, "expressions": False}
    +4871    is_var_len_args = True
     
    @@ -68325,8 +69159,8 @@ array != array.

    -
    4822class Month(Func):
    -4823    pass
    +            
    4874class Month(Func):
    +4875    pass
     
    @@ -68433,8 +69267,8 @@ array != array.

    -
    4826class Nvl2(Func):
    -4827    arg_types = {"this": True, "true": True, "false": False}
    +            
    4878class Nvl2(Func):
    +4879    arg_types = {"this": True, "true": True, "false": False}
     
    @@ -68552,8 +69386,8 @@ array != array.

    -
    4831class Predict(Func):
    -4832    arg_types = {"this": True, "expression": True, "params_struct": False}
    +            
    4883class Predict(Func):
    +4884    arg_types = {"this": True, "expression": True, "params_struct": False}
     
    @@ -68671,8 +69505,8 @@ array != array.

    -
    4835class Pow(Binary, Func):
    -4836    _sql_names = ["POWER", "POW"]
    +            
    4887class Pow(Binary, Func):
    +4888    _sql_names = ["POWER", "POW"]
     
    @@ -68784,8 +69618,8 @@ array != array.

    -
    4839class PercentileCont(AggFunc):
    -4840    arg_types = {"this": True, "expression": False}
    +            
    4891class PercentileCont(AggFunc):
    +4892    arg_types = {"this": True, "expression": False}
     
    @@ -68903,8 +69737,8 @@ array != array.

    -
    4843class PercentileDisc(AggFunc):
    -4844    arg_types = {"this": True, "expression": False}
    +            
    4895class PercentileDisc(AggFunc):
    +4896    arg_types = {"this": True, "expression": False}
     
    @@ -69022,8 +69856,8 @@ array != array.

    -
    4847class Quantile(AggFunc):
    -4848    arg_types = {"this": True, "quantile": True}
    +            
    4899class Quantile(AggFunc):
    +4900    arg_types = {"this": True, "quantile": True}
     
    @@ -69141,8 +69975,8 @@ array != array.

    -
    4851class ApproxQuantile(Quantile):
    -4852    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
    +            
    4903class ApproxQuantile(Quantile):
    +4904    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
     
    @@ -69260,8 +70094,8 @@ array != array.

    -
    4855class RangeN(Func):
    -4856    arg_types = {"this": True, "expressions": True, "each": False}
    +            
    4907class RangeN(Func):
    +4908    arg_types = {"this": True, "expressions": True, "each": False}
     
    @@ -69379,10 +70213,10 @@ array != array.

    -
    4859class ReadCSV(Func):
    -4860    _sql_names = ["READ_CSV"]
    -4861    is_var_len_args = True
    -4862    arg_types = {"this": True, "expressions": False}
    +            
    4911class ReadCSV(Func):
    +4912    _sql_names = ["READ_CSV"]
    +4913    is_var_len_args = True
    +4914    arg_types = {"this": True, "expressions": False}
     
    @@ -69511,8 +70345,8 @@ array != array.

    -
    4865class Reduce(Func):
    -4866    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
    +            
    4917class Reduce(Func):
    +4918    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
     
    @@ -69630,15 +70464,15 @@ array != array.

    -
    4869class RegexpExtract(Func):
    -4870    arg_types = {
    -4871        "this": True,
    -4872        "expression": True,
    -4873        "position": False,
    -4874        "occurrence": False,
    -4875        "parameters": False,
    -4876        "group": False,
    -4877    }
    +            
    4921class RegexpExtract(Func):
    +4922    arg_types = {
    +4923        "this": True,
    +4924        "expression": True,
    +4925        "position": False,
    +4926        "occurrence": False,
    +4927        "parameters": False,
    +4928        "group": False,
    +4929    }
     
    @@ -69757,16 +70591,16 @@ array != array.

    -
    4880class RegexpReplace(Func):
    -4881    arg_types = {
    -4882        "this": True,
    -4883        "expression": True,
    -4884        "replacement": True,
    -4885        "position": False,
    -4886        "occurrence": False,
    -4887        "parameters": False,
    -4888        "modifiers": False,
    -4889    }
    +            
    4932class RegexpReplace(Func):
    +4933    arg_types = {
    +4934        "this": True,
    +4935        "expression": True,
    +4936        "replacement": True,
    +4937        "position": False,
    +4938        "occurrence": False,
    +4939        "parameters": False,
    +4940        "modifiers": False,
    +4941    }
     
    @@ -69885,8 +70719,8 @@ array != array.

    -
    4892class RegexpLike(Binary, Func):
    -4893    arg_types = {"this": True, "expression": True, "flag": False}
    +            
    4944class RegexpLike(Binary, Func):
    +4945    arg_types = {"this": True, "expression": True, "flag": False}
     
    @@ -70009,8 +70843,8 @@ array != array.

    -
    4896class RegexpILike(Binary, Func):
    -4897    arg_types = {"this": True, "expression": True, "flag": False}
    +            
    4948class RegexpILike(Binary, Func):
    +4949    arg_types = {"this": True, "expression": True, "flag": False}
     
    @@ -70133,8 +70967,8 @@ array != array.

    -
    4902class RegexpSplit(Func):
    -4903    arg_types = {"this": True, "expression": True, "limit": False}
    +            
    4954class RegexpSplit(Func):
    +4955    arg_types = {"this": True, "expression": True, "limit": False}
     
    @@ -70252,8 +71086,8 @@ array != array.

    -
    4906class Repeat(Func):
    -4907    arg_types = {"this": True, "times": True}
    +            
    4958class Repeat(Func):
    +4959    arg_types = {"this": True, "times": True}
     
    @@ -70371,8 +71205,8 @@ array != array.

    -
    4910class Round(Func):
    -4911    arg_types = {"this": True, "decimals": False}
    +            
    4962class Round(Func):
    +4963    arg_types = {"this": True, "decimals": False}
     
    @@ -70490,8 +71324,8 @@ array != array.

    -
    4914class RowNumber(Func):
    -4915    arg_types: t.Dict[str, t.Any] = {}
    +            
    4966class RowNumber(Func):
    +4967    arg_types: t.Dict[str, t.Any] = {}
     
    @@ -70609,8 +71443,8 @@ array != array.

    -
    4918class SafeDivide(Func):
    -4919    arg_types = {"this": True, "expression": True}
    +            
    4970class SafeDivide(Func):
    +4971    arg_types = {"this": True, "expression": True}
     
    @@ -70728,8 +71562,8 @@ array != array.

    -
    4922class SetAgg(AggFunc):
    -4923    pass
    +            
    4974class SetAgg(AggFunc):
    +4975    pass
     
    @@ -70836,8 +71670,8 @@ array != array.

    -
    4926class SHA(Func):
    -4927    _sql_names = ["SHA", "SHA1"]
    +            
    4978class SHA(Func):
    +4979    _sql_names = ["SHA", "SHA1"]
     
    @@ -70944,9 +71778,9 @@ array != array.

    -
    4930class SHA2(Func):
    -4931    _sql_names = ["SHA2"]
    -4932    arg_types = {"this": True, "length": False}
    +            
    4982class SHA2(Func):
    +4983    _sql_names = ["SHA2"]
    +4984    arg_types = {"this": True, "length": False}
     
    @@ -71064,8 +71898,8 @@ array != array.

    -
    4935class SortArray(Func):
    -4936    arg_types = {"this": True, "asc": False}
    +            
    4987class SortArray(Func):
    +4988    arg_types = {"this": True, "asc": False}
     
    @@ -71183,8 +72017,8 @@ array != array.

    -
    4939class Split(Func):
    -4940    arg_types = {"this": True, "expression": True, "limit": False}
    +            
    4991class Split(Func):
    +4992    arg_types = {"this": True, "expression": True, "limit": False}
     
    @@ -71302,8 +72136,8 @@ array != array.

    -
    4945class Substring(Func):
    -4946    arg_types = {"this": True, "start": False, "length": False}
    +            
    4997class Substring(Func):
    +4998    arg_types = {"this": True, "start": False, "length": False}
     
    @@ -71421,8 +72255,8 @@ array != array.

    -
    4949class StandardHash(Func):
    -4950    arg_types = {"this": True, "expression": False}
    +            
    5001class StandardHash(Func):
    +5002    arg_types = {"this": True, "expression": False}
     
    @@ -71540,9 +72374,9 @@ array != array.

    -
    4953class StartsWith(Func):
    -4954    _sql_names = ["STARTS_WITH", "STARTSWITH"]
    -4955    arg_types = {"this": True, "expression": True}
    +            
    5005class StartsWith(Func):
    +5006    _sql_names = ["STARTS_WITH", "STARTSWITH"]
    +5007    arg_types = {"this": True, "expression": True}
     
    @@ -71660,13 +72494,13 @@ array != array.

    -
    4958class StrPosition(Func):
    -4959    arg_types = {
    -4960        "this": True,
    -4961        "substr": True,
    -4962        "position": False,
    -4963        "instance": False,
    -4964    }
    +            
    5010class StrPosition(Func):
    +5011    arg_types = {
    +5012        "this": True,
    +5013        "substr": True,
    +5014        "position": False,
    +5015        "instance": False,
    +5016    }
     
    @@ -71784,8 +72618,8 @@ array != array.

    -
    4967class StrToDate(Func):
    -4968    arg_types = {"this": True, "format": True}
    +            
    5019class StrToDate(Func):
    +5020    arg_types = {"this": True, "format": True}
     
    @@ -71903,8 +72737,8 @@ array != array.

    -
    4971class StrToTime(Func):
    -4972    arg_types = {"this": True, "format": True, "zone": False}
    +            
    5023class StrToTime(Func):
    +5024    arg_types = {"this": True, "format": True, "zone": False}
     
    @@ -72022,8 +72856,8 @@ array != array.

    -
    4977class StrToUnix(Func):
    -4978    arg_types = {"this": False, "format": False}
    +            
    5029class StrToUnix(Func):
    +5030    arg_types = {"this": False, "format": False}
     
    @@ -72141,13 +72975,13 @@ array != array.

    -
    4983class StrToMap(Func):
    -4984    arg_types = {
    -4985        "this": True,
    -4986        "pair_delim": False,
    -4987        "key_value_delim": False,
    -4988        "duplicate_resolution_callback": False,
    -4989    }
    +            
    5035class StrToMap(Func):
    +5036    arg_types = {
    +5037        "this": True,
    +5038        "pair_delim": False,
    +5039        "key_value_delim": False,
    +5040        "duplicate_resolution_callback": False,
    +5041    }
     
    @@ -72266,8 +73100,8 @@ array != array.

    -
    4992class NumberToStr(Func):
    -4993    arg_types = {"this": True, "format": True, "culture": False}
    +            
    5044class NumberToStr(Func):
    +5045    arg_types = {"this": True, "format": True, "culture": False}
     
    @@ -72385,8 +73219,8 @@ array != array.

    -
    4996class FromBase(Func):
    -4997    arg_types = {"this": True, "expression": True}
    +            
    5048class FromBase(Func):
    +5049    arg_types = {"this": True, "expression": True}
     
    @@ -72504,9 +73338,9 @@ array != array.

    -
    5000class Struct(Func):
    -5001    arg_types = {"expressions": True}
    -5002    is_var_len_args = True
    +            
    5052class Struct(Func):
    +5053    arg_types = {"expressions": False}
    +5054    is_var_len_args = True
     
    @@ -72515,7 +73349,7 @@ array != array.

    arg_types = -{'expressions': True} +{'expressions': False}
    @@ -72635,8 +73469,8 @@ array != array.

    -
    5005class StructExtract(Func):
    -5006    arg_types = {"this": True, "expression": True}
    +            
    5057class StructExtract(Func):
    +5058    arg_types = {"this": True, "expression": True}
     
    @@ -72754,9 +73588,9 @@ array != array.

    -
    5011class Stuff(Func):
    -5012    _sql_names = ["STUFF", "INSERT"]
    -5013    arg_types = {"this": True, "start": True, "length": True, "expression": True}
    +            
    5063class Stuff(Func):
    +5064    _sql_names = ["STUFF", "INSERT"]
    +5065    arg_types = {"this": True, "start": True, "length": True, "expression": True}
     
    @@ -72874,8 +73708,8 @@ array != array.

    -
    5016class Sum(AggFunc):
    -5017    pass
    +            
    5068class Sum(AggFunc):
    +5069    pass
     
    @@ -72982,8 +73816,8 @@ array != array.

    -
    5020class Sqrt(Func):
    -5021    pass
    +            
    5072class Sqrt(Func):
    +5073    pass
     
    @@ -73090,8 +73924,8 @@ array != array.

    -
    5024class Stddev(AggFunc):
    -5025    pass
    +            
    5076class Stddev(AggFunc):
    +5077    pass
     
    @@ -73198,8 +74032,8 @@ array != array.

    -
    5028class StddevPop(AggFunc):
    -5029    pass
    +            
    5080class StddevPop(AggFunc):
    +5081    pass
     
    @@ -73306,8 +74140,8 @@ array != array.

    -
    5032class StddevSamp(AggFunc):
    -5033    pass
    +            
    5084class StddevSamp(AggFunc):
    +5085    pass
     
    @@ -73414,8 +74248,8 @@ array != array.

    -
    5036class TimeToStr(Func):
    -5037    arg_types = {"this": True, "format": True, "culture": False}
    +            
    5088class TimeToStr(Func):
    +5089    arg_types = {"this": True, "format": True, "culture": False}
     
    @@ -73533,8 +74367,8 @@ array != array.

    -
    5040class TimeToTimeStr(Func):
    -5041    pass
    +            
    5092class TimeToTimeStr(Func):
    +5093    pass
     
    @@ -73641,8 +74475,8 @@ array != array.

    -
    5044class TimeToUnix(Func):
    -5045    pass
    +            
    5096class TimeToUnix(Func):
    +5097    pass
     
    @@ -73749,8 +74583,8 @@ array != array.

    -
    5048class TimeStrToDate(Func):
    -5049    pass
    +            
    5100class TimeStrToDate(Func):
    +5101    pass
     
    @@ -73857,8 +74691,8 @@ array != array.

    -
    5052class TimeStrToTime(Func):
    -5053    pass
    +            
    5104class TimeStrToTime(Func):
    +5105    pass
     
    @@ -73965,8 +74799,8 @@ array != array.

    -
    5056class TimeStrToUnix(Func):
    -5057    pass
    +            
    5108class TimeStrToUnix(Func):
    +5109    pass
     
    @@ -74073,13 +74907,13 @@ array != array.

    -
    5060class Trim(Func):
    -5061    arg_types = {
    -5062        "this": True,
    -5063        "expression": False,
    -5064        "position": False,
    -5065        "collation": False,
    -5066    }
    +            
    5112class Trim(Func):
    +5113    arg_types = {
    +5114        "this": True,
    +5115        "expression": False,
    +5116        "position": False,
    +5117        "collation": False,
    +5118    }
     
    @@ -74197,8 +75031,8 @@ array != array.

    -
    5069class TsOrDsAdd(Func, TimeUnit):
    -5070    arg_types = {"this": True, "expression": True, "unit": False}
    +            
    5121class TsOrDsAdd(Func, TimeUnit):
    +5122    arg_types = {"this": True, "expression": True, "unit": False}
     
    @@ -74233,6 +75067,8 @@ array != array.

    @@ -74320,8 +75156,8 @@ array != array.

    -
    5073class TsOrDsToDateStr(Func):
    -5074    pass
    +            
    5125class TsOrDsToDateStr(Func):
    +5126    pass
     
    @@ -74428,8 +75264,8 @@ array != array.

    -
    5077class TsOrDsToDate(Func):
    -5078    arg_types = {"this": True, "format": False}
    +            
    5129class TsOrDsToDate(Func):
    +5130    arg_types = {"this": True, "format": False}
     
    @@ -74547,8 +75383,8 @@ array != array.

    -
    5081class TsOrDiToDi(Func):
    -5082    pass
    +            
    5133class TsOrDiToDi(Func):
    +5134    pass
     
    @@ -74655,8 +75491,8 @@ array != array.

    -
    5085class Unhex(Func):
    -5086    pass
    +            
    5137class Unhex(Func):
    +5138    pass
     
    @@ -74763,8 +75599,8 @@ array != array.

    -
    5089class UnixToStr(Func):
    -5090    arg_types = {"this": True, "format": False}
    +            
    5141class UnixToStr(Func):
    +5142    arg_types = {"this": True, "format": False}
     
    @@ -74882,12 +75718,12 @@ array != array.

    -
    5095class UnixToTime(Func):
    -5096    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
    -5097
    -5098    SECONDS = Literal.string("seconds")
    -5099    MILLIS = Literal.string("millis")
    -5100    MICROS = Literal.string("micros")
    +            
    5147class UnixToTime(Func):
    +5148    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
    +5149
    +5150    SECONDS = Literal.string("seconds")
    +5151    MILLIS = Literal.string("millis")
    +5152    MICROS = Literal.string("micros")
     
    @@ -75041,8 +75877,8 @@ array != array.

    -
    5103class UnixToTimeStr(Func):
    -5104    pass
    +            
    5155class UnixToTimeStr(Func):
    +5156    pass
     
    @@ -75149,8 +75985,8 @@ array != array.

    -
    5107class Upper(Func):
    -5108    _sql_names = ["UPPER", "UCASE"]
    +            
    5159class Upper(Func):
    +5160    _sql_names = ["UPPER", "UCASE"]
     
    @@ -75257,8 +76093,8 @@ array != array.

    -
    5111class Variance(AggFunc):
    -5112    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
    +            
    5163class Variance(AggFunc):
    +5164    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
     
    @@ -75365,8 +76201,8 @@ array != array.

    -
    5115class VariancePop(AggFunc):
    -5116    _sql_names = ["VARIANCE_POP", "VAR_POP"]
    +            
    5167class VariancePop(AggFunc):
    +5168    _sql_names = ["VARIANCE_POP", "VAR_POP"]
     
    @@ -75473,8 +76309,8 @@ array != array.

    -
    5119class Week(Func):
    -5120    arg_types = {"this": True, "mode": False}
    +            
    5171class Week(Func):
    +5172    arg_types = {"this": True, "mode": False}
     
    @@ -75592,8 +76428,8 @@ array != array.

    -
    5123class XMLTable(Func):
    -5124    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
    +            
    5175class XMLTable(Func):
    +5176    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
     
    @@ -75711,8 +76547,8 @@ array != array.

    -
    5127class Year(Func):
    -5128    pass
    +            
    5179class Year(Func):
    +5180    pass
     
    @@ -75819,8 +76655,8 @@ array != array.

    -
    5131class Use(Expression):
    -5132    arg_types = {"this": True, "kind": False}
    +            
    5183class Use(Expression):
    +5184    arg_types = {"this": True, "kind": False}
     
    @@ -75930,8 +76766,8 @@ array != array.

    -
    5135class Merge(Expression):
    -5136    arg_types = {"this": True, "using": True, "on": True, "expressions": True}
    +            
    5187class Merge(Expression):
    +5188    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
     
    @@ -75940,7 +76776,7 @@ array != array.

    arg_types = -{'this': True, 'using': True, 'on': True, 'expressions': True} +{'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
    @@ -76041,8 +76877,8 @@ array != array.

    -
    5139class When(Func):
    -5140    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
    +            
    5191class When(Func):
    +5192    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
     
    @@ -76160,8 +76996,8 @@ array != array.

    -
    5145class NextValueFor(Func):
    -5146    arg_types = {"this": True, "order": False}
    +            
    5197class NextValueFor(Func):
    +5198    arg_types = {"this": True, "order": False}
     
    @@ -76272,7 +77108,7 @@ array != array.

    ALL_FUNCTIONS = - [<class 'Abs'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDateOfMonth'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeConcat'>, <class 'SafeDivide'>, <class 'SetAgg'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'Unhex'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>] + [<class 'Abs'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDateOfMonth'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeConcat'>, <class 'SafeDivide'>, <class 'SetAgg'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'Unhex'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
    @@ -76292,52 +77128,52 @@ array != array.

    -
    5183def maybe_parse(
    -5184    sql_or_expression: ExpOrStr,
    -5185    *,
    -5186    into: t.Optional[IntoType] = None,
    -5187    dialect: DialectType = None,
    -5188    prefix: t.Optional[str] = None,
    -5189    copy: bool = False,
    -5190    **opts,
    -5191) -> Expression:
    -5192    """Gracefully handle a possible string or expression.
    -5193
    -5194    Example:
    -5195        >>> maybe_parse("1")
    -5196        (LITERAL this: 1, is_string: False)
    -5197        >>> maybe_parse(to_identifier("x"))
    -5198        (IDENTIFIER this: x, quoted: False)
    -5199
    -5200    Args:
    -5201        sql_or_expression: the SQL code string or an expression
    -5202        into: the SQLGlot Expression to parse into
    -5203        dialect: the dialect used to parse the input expressions (in the case that an
    -5204            input expression is a SQL string).
    -5205        prefix: a string to prefix the sql with before it gets parsed
    -5206            (automatically includes a space)
    -5207        copy: whether or not to copy the expression.
    -5208        **opts: other options to use to parse the input expressions (again, in the case
    -5209            that an input expression is a SQL string).
    -5210
    -5211    Returns:
    -5212        Expression: the parsed or given expression.
    -5213    """
    -5214    if isinstance(sql_or_expression, Expression):
    -5215        if copy:
    -5216            return sql_or_expression.copy()
    -5217        return sql_or_expression
    -5218
    -5219    if sql_or_expression is None:
    -5220        raise ParseError(f"SQL cannot be None")
    -5221
    -5222    import sqlglot
    -5223
    -5224    sql = str(sql_or_expression)
    -5225    if prefix:
    -5226        sql = f"{prefix} {sql}"
    -5227
    -5228    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
    +            
    5235def maybe_parse(
    +5236    sql_or_expression: ExpOrStr,
    +5237    *,
    +5238    into: t.Optional[IntoType] = None,
    +5239    dialect: DialectType = None,
    +5240    prefix: t.Optional[str] = None,
    +5241    copy: bool = False,
    +5242    **opts,
    +5243) -> Expression:
    +5244    """Gracefully handle a possible string or expression.
    +5245
    +5246    Example:
    +5247        >>> maybe_parse("1")
    +5248        (LITERAL this: 1, is_string: False)
    +5249        >>> maybe_parse(to_identifier("x"))
    +5250        (IDENTIFIER this: x, quoted: False)
    +5251
    +5252    Args:
    +5253        sql_or_expression: the SQL code string or an expression
    +5254        into: the SQLGlot Expression to parse into
    +5255        dialect: the dialect used to parse the input expressions (in the case that an
    +5256            input expression is a SQL string).
    +5257        prefix: a string to prefix the sql with before it gets parsed
    +5258            (automatically includes a space)
    +5259        copy: whether or not to copy the expression.
    +5260        **opts: other options to use to parse the input expressions (again, in the case
    +5261            that an input expression is a SQL string).
    +5262
    +5263    Returns:
    +5264        Expression: the parsed or given expression.
    +5265    """
    +5266    if isinstance(sql_or_expression, Expression):
    +5267        if copy:
    +5268            return sql_or_expression.copy()
    +5269        return sql_or_expression
    +5270
    +5271    if sql_or_expression is None:
    +5272        raise ParseError(f"SQL cannot be None")
    +5273
    +5274    import sqlglot
    +5275
    +5276    sql = str(sql_or_expression)
    +5277    if prefix:
    +5278        sql = f"{prefix} {sql}"
    +5279
    +5280    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
     
    @@ -76389,8 +77225,8 @@ that an input expression is a SQL string).
    -
    5241def maybe_copy(instance, copy=True):
    -5242    return instance.copy() if copy and instance else instance
    +            
    5293def maybe_copy(instance, copy=True):
    +5294    return instance.copy() if copy and instance else instance
     
    @@ -76402,38 +77238,44 @@ that an input expression is a SQL string).
    def - union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union: + union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
    -
    5423def union(
    -5424    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
    -5425) -> Union:
    -5426    """
    -5427    Initializes a syntax tree from one UNION expression.
    -5428
    -5429    Example:
    -5430        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
    -5431        'SELECT * FROM foo UNION SELECT * FROM bla'
    -5432
    -5433    Args:
    -5434        left: the SQL code string corresponding to the left-hand side.
    -5435            If an `Expression` instance is passed, it will be used as-is.
    -5436        right: the SQL code string corresponding to the right-hand side.
    -5437            If an `Expression` instance is passed, it will be used as-is.
    -5438        distinct: set the DISTINCT flag if and only if this is true.
    -5439        dialect: the dialect used to parse the input expression.
    -5440        opts: other options to use to parse the input expressions.
    -5441
    -5442    Returns:
    -5443        The new Union instance.
    -5444    """
    -5445    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
    -5446    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
    -5447
    -5448    return Union(this=left, expression=right, distinct=distinct)
    +            
    5475def union(
    +5476    left: ExpOrStr,
    +5477    right: ExpOrStr,
    +5478    distinct: bool = True,
    +5479    dialect: DialectType = None,
    +5480    copy: bool = True,
    +5481    **opts,
    +5482) -> Union:
    +5483    """
    +5484    Initializes a syntax tree from one UNION expression.
    +5485
    +5486    Example:
    +5487        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
    +5488        'SELECT * FROM foo UNION SELECT * FROM bla'
    +5489
    +5490    Args:
    +5491        left: the SQL code string corresponding to the left-hand side.
    +5492            If an `Expression` instance is passed, it will be used as-is.
    +5493        right: the SQL code string corresponding to the right-hand side.
    +5494            If an `Expression` instance is passed, it will be used as-is.
    +5495        distinct: set the DISTINCT flag if and only if this is true.
    +5496        dialect: the dialect used to parse the input expression.
    +5497        copy: whether or not to copy the expression.
    +5498        opts: other options to use to parse the input expressions.
    +5499
    +5500    Returns:
    +5501        The new Union instance.
    +5502    """
    +5503    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
    +5504    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
    +5505
    +5506    return Union(this=left, expression=right, distinct=distinct)
     
    @@ -76458,6 +77300,7 @@ If an Expression instance is passed, it w If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • +
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
  • @@ -76475,38 +77318,44 @@ If an Expression instance is passed, it w
    def - intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect: + intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
    -
    5451def intersect(
    -5452    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
    -5453) -> Intersect:
    -5454    """
    -5455    Initializes a syntax tree from one INTERSECT expression.
    -5456
    -5457    Example:
    -5458        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
    -5459        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
    -5460
    -5461    Args:
    -5462        left: the SQL code string corresponding to the left-hand side.
    -5463            If an `Expression` instance is passed, it will be used as-is.
    -5464        right: the SQL code string corresponding to the right-hand side.
    -5465            If an `Expression` instance is passed, it will be used as-is.
    -5466        distinct: set the DISTINCT flag if and only if this is true.
    -5467        dialect: the dialect used to parse the input expression.
    -5468        opts: other options to use to parse the input expressions.
    -5469
    -5470    Returns:
    -5471        The new Intersect instance.
    -5472    """
    -5473    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
    -5474    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
    -5475
    -5476    return Intersect(this=left, expression=right, distinct=distinct)
    +            
    5509def intersect(
    +5510    left: ExpOrStr,
    +5511    right: ExpOrStr,
    +5512    distinct: bool = True,
    +5513    dialect: DialectType = None,
    +5514    copy: bool = True,
    +5515    **opts,
    +5516) -> Intersect:
    +5517    """
    +5518    Initializes a syntax tree from one INTERSECT expression.
    +5519
    +5520    Example:
    +5521        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
    +5522        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
    +5523
    +5524    Args:
    +5525        left: the SQL code string corresponding to the left-hand side.
    +5526            If an `Expression` instance is passed, it will be used as-is.
    +5527        right: the SQL code string corresponding to the right-hand side.
    +5528            If an `Expression` instance is passed, it will be used as-is.
    +5529        distinct: set the DISTINCT flag if and only if this is true.
    +5530        dialect: the dialect used to parse the input expression.
    +5531        copy: whether or not to copy the expression.
    +5532        opts: other options to use to parse the input expressions.
    +5533
    +5534    Returns:
    +5535        The new Intersect instance.
    +5536    """
    +5537    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
    +5538    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
    +5539
    +5540    return Intersect(this=left, expression=right, distinct=distinct)
     
    @@ -76531,6 +77380,7 @@ If an Expression instance is passed, it w If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • +
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
  • @@ -76548,38 +77398,44 @@ If an Expression instance is passed, it w
    def - except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except: + except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
    -
    5479def except_(
    -5480    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
    -5481) -> Except:
    -5482    """
    -5483    Initializes a syntax tree from one EXCEPT expression.
    -5484
    -5485    Example:
    -5486        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
    -5487        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
    -5488
    -5489    Args:
    -5490        left: the SQL code string corresponding to the left-hand side.
    -5491            If an `Expression` instance is passed, it will be used as-is.
    -5492        right: the SQL code string corresponding to the right-hand side.
    -5493            If an `Expression` instance is passed, it will be used as-is.
    -5494        distinct: set the DISTINCT flag if and only if this is true.
    -5495        dialect: the dialect used to parse the input expression.
    -5496        opts: other options to use to parse the input expressions.
    -5497
    -5498    Returns:
    -5499        The new Except instance.
    -5500    """
    -5501    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
    -5502    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
    -5503
    -5504    return Except(this=left, expression=right, distinct=distinct)
    +            
    5543def except_(
    +5544    left: ExpOrStr,
    +5545    right: ExpOrStr,
    +5546    distinct: bool = True,
    +5547    dialect: DialectType = None,
    +5548    copy: bool = True,
    +5549    **opts,
    +5550) -> Except:
    +5551    """
    +5552    Initializes a syntax tree from one EXCEPT expression.
    +5553
    +5554    Example:
    +5555        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
    +5556        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
    +5557
    +5558    Args:
    +5559        left: the SQL code string corresponding to the left-hand side.
    +5560            If an `Expression` instance is passed, it will be used as-is.
    +5561        right: the SQL code string corresponding to the right-hand side.
    +5562            If an `Expression` instance is passed, it will be used as-is.
    +5563        distinct: set the DISTINCT flag if and only if this is true.
    +5564        dialect: the dialect used to parse the input expression.
    +5565        copy: whether or not to copy the expression.
    +5566        opts: other options to use to parse the input expressions.
    +5567
    +5568    Returns:
    +5569        The new Except instance.
    +5570    """
    +5571    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
    +5572    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
    +5573
    +5574    return Except(this=left, expression=right, distinct=distinct)
     
    @@ -76604,6 +77460,7 @@ If an Expression instance is passed, it w If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • +
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
  • @@ -76627,26 +77484,26 @@ If an Expression instance is passed, it w
    -
    5507def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
    -5508    """
    -5509    Initializes a syntax tree from one or multiple SELECT expressions.
    -5510
    -5511    Example:
    -5512        >>> select("col1", "col2").from_("tbl").sql()
    -5513        'SELECT col1, col2 FROM tbl'
    -5514
    -5515    Args:
    -5516        *expressions: the SQL code string to parse as the expressions of a
    -5517            SELECT statement. If an Expression instance is passed, this is used as-is.
    -5518        dialect: the dialect used to parse the input expressions (in the case that an
    -5519            input expression is a SQL string).
    -5520        **opts: other options to use to parse the input expressions (again, in the case
    -5521            that an input expression is a SQL string).
    -5522
    -5523    Returns:
    -5524        Select: the syntax tree for the SELECT statement.
    -5525    """
    -5526    return Select().select(*expressions, dialect=dialect, **opts)
    +            
    5577def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
    +5578    """
    +5579    Initializes a syntax tree from one or multiple SELECT expressions.
    +5580
    +5581    Example:
    +5582        >>> select("col1", "col2").from_("tbl").sql()
    +5583        'SELECT col1, col2 FROM tbl'
    +5584
    +5585    Args:
    +5586        *expressions: the SQL code string to parse as the expressions of a
    +5587            SELECT statement. If an Expression instance is passed, this is used as-is.
    +5588        dialect: the dialect used to parse the input expressions (in the case that an
    +5589            input expression is a SQL string).
    +5590        **opts: other options to use to parse the input expressions (again, in the case
    +5591            that an input expression is a SQL string).
    +5592
    +5593    Returns:
    +5594        Select: the syntax tree for the SELECT statement.
    +5595    """
    +5596    return Select().select(*expressions, dialect=dialect, **opts)
     
    @@ -76693,26 +77550,26 @@ that an input expression is a SQL string).
    -
    5529def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
    -5530    """
    -5531    Initializes a syntax tree from a FROM expression.
    -5532
    -5533    Example:
    -5534        >>> from_("tbl").select("col1", "col2").sql()
    -5535        'SELECT col1, col2 FROM tbl'
    -5536
    -5537    Args:
    -5538        *expression: the SQL code string to parse as the FROM expressions of a
    -5539            SELECT statement. If an Expression instance is passed, this is used as-is.
    -5540        dialect: the dialect used to parse the input expression (in the case that the
    -5541            input expression is a SQL string).
    -5542        **opts: other options to use to parse the input expressions (again, in the case
    -5543            that the input expression is a SQL string).
    -5544
    -5545    Returns:
    -5546        Select: the syntax tree for the SELECT statement.
    -5547    """
    -5548    return Select().from_(expression, dialect=dialect, **opts)
    +            
    5599def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
    +5600    """
    +5601    Initializes a syntax tree from a FROM expression.
    +5602
    +5603    Example:
    +5604        >>> from_("tbl").select("col1", "col2").sql()
    +5605        'SELECT col1, col2 FROM tbl'
    +5606
    +5607    Args:
    +5608        *expression: the SQL code string to parse as the FROM expressions of a
    +5609            SELECT statement. If an Expression instance is passed, this is used as-is.
    +5610        dialect: the dialect used to parse the input expression (in the case that the
    +5611            input expression is a SQL string).
    +5612        **opts: other options to use to parse the input expressions (again, in the case
    +5613            that the input expression is a SQL string).
    +5614
    +5615    Returns:
    +5616        Select: the syntax tree for the SELECT statement.
    +5617    """
    +5618    return Select().from_(expression, dialect=dialect, **opts)
     
    @@ -76759,53 +77616,53 @@ that the input expression is a SQL string).
    -
    5551def update(
    -5552    table: str | Table,
    -5553    properties: dict,
    -5554    where: t.Optional[ExpOrStr] = None,
    -5555    from_: t.Optional[ExpOrStr] = None,
    -5556    dialect: DialectType = None,
    -5557    **opts,
    -5558) -> Update:
    -5559    """
    -5560    Creates an update statement.
    -5561
    -5562    Example:
    -5563        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
    -5564        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
    -5565
    -5566    Args:
    -5567        *properties: dictionary of properties to set which are
    -5568            auto converted to sql objects eg None -> NULL
    -5569        where: sql conditional parsed into a WHERE statement
    -5570        from_: sql statement parsed into a FROM statement
    -5571        dialect: the dialect used to parse the input expressions.
    -5572        **opts: other options to use to parse the input expressions.
    -5573
    -5574    Returns:
    -5575        Update: the syntax tree for the UPDATE statement.
    -5576    """
    -5577    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
    -5578    update_expr.set(
    -5579        "expressions",
    -5580        [
    -5581            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
    -5582            for k, v in properties.items()
    -5583        ],
    -5584    )
    -5585    if from_:
    -5586        update_expr.set(
    -5587            "from",
    -5588            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
    -5589        )
    -5590    if isinstance(where, Condition):
    -5591        where = Where(this=where)
    -5592    if where:
    -5593        update_expr.set(
    -5594            "where",
    -5595            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
    -5596        )
    -5597    return update_expr
    +            
    5621def update(
    +5622    table: str | Table,
    +5623    properties: dict,
    +5624    where: t.Optional[ExpOrStr] = None,
    +5625    from_: t.Optional[ExpOrStr] = None,
    +5626    dialect: DialectType = None,
    +5627    **opts,
    +5628) -> Update:
    +5629    """
    +5630    Creates an update statement.
    +5631
    +5632    Example:
    +5633        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
    +5634        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
    +5635
    +5636    Args:
    +5637        *properties: dictionary of properties to set which are
    +5638            auto converted to sql objects eg None -> NULL
    +5639        where: sql conditional parsed into a WHERE statement
    +5640        from_: sql statement parsed into a FROM statement
    +5641        dialect: the dialect used to parse the input expressions.
    +5642        **opts: other options to use to parse the input expressions.
    +5643
    +5644    Returns:
    +5645        Update: the syntax tree for the UPDATE statement.
    +5646    """
    +5647    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
    +5648    update_expr.set(
    +5649        "expressions",
    +5650        [
    +5651            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
    +5652            for k, v in properties.items()
    +5653        ],
    +5654    )
    +5655    if from_:
    +5656        update_expr.set(
    +5657            "from",
    +5658            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
    +5659        )
    +5660    if isinstance(where, Condition):
    +5661        where = Where(this=where)
    +5662    if where:
    +5663        update_expr.set(
    +5664            "where",
    +5665            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
    +5666        )
    +5667    return update_expr
     
    @@ -76852,35 +77709,35 @@ auto converted to sql objects eg None -> NULL
    -
    5600def delete(
    -5601    table: ExpOrStr,
    -5602    where: t.Optional[ExpOrStr] = None,
    -5603    returning: t.Optional[ExpOrStr] = None,
    -5604    dialect: DialectType = None,
    -5605    **opts,
    -5606) -> Delete:
    -5607    """
    -5608    Builds a delete statement.
    -5609
    -5610    Example:
    -5611        >>> delete("my_table", where="id > 1").sql()
    -5612        'DELETE FROM my_table WHERE id > 1'
    -5613
    -5614    Args:
    -5615        where: sql conditional parsed into a WHERE statement
    -5616        returning: sql conditional parsed into a RETURNING statement
    -5617        dialect: the dialect used to parse the input expressions.
    -5618        **opts: other options to use to parse the input expressions.
    -5619
    -5620    Returns:
    -5621        Delete: the syntax tree for the DELETE statement.
    -5622    """
    -5623    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
    -5624    if where:
    -5625        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
    -5626    if returning:
    -5627        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
    -5628    return delete_expr
    +            
    5670def delete(
    +5671    table: ExpOrStr,
    +5672    where: t.Optional[ExpOrStr] = None,
    +5673    returning: t.Optional[ExpOrStr] = None,
    +5674    dialect: DialectType = None,
    +5675    **opts,
    +5676) -> Delete:
    +5677    """
    +5678    Builds a delete statement.
    +5679
    +5680    Example:
    +5681        >>> delete("my_table", where="id > 1").sql()
    +5682        'DELETE FROM my_table WHERE id > 1'
    +5683
    +5684    Args:
    +5685        where: sql conditional parsed into a WHERE statement
    +5686        returning: sql conditional parsed into a RETURNING statement
    +5687        dialect: the dialect used to parse the input expressions.
    +5688        **opts: other options to use to parse the input expressions.
    +5689
    +5690    Returns:
    +5691        Delete: the syntax tree for the DELETE statement.
    +5692    """
    +5693    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
    +5694    if where:
    +5695        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
    +5696    if returning:
    +5697        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
    +5698    return delete_expr
     
    @@ -76925,49 +77782,49 @@ auto converted to sql objects eg None -> NULL
    -
    5631def insert(
    -5632    expression: ExpOrStr,
    -5633    into: ExpOrStr,
    -5634    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
    -5635    overwrite: t.Optional[bool] = None,
    -5636    dialect: DialectType = None,
    -5637    copy: bool = True,
    -5638    **opts,
    -5639) -> Insert:
    -5640    """
    -5641    Builds an INSERT statement.
    -5642
    -5643    Example:
    -5644        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
    -5645        'INSERT INTO tbl VALUES (1, 2, 3)'
    -5646
    -5647    Args:
    -5648        expression: the sql string or expression of the INSERT statement
    -5649        into: the tbl to insert data to.
    -5650        columns: optionally the table's column names.
    -5651        overwrite: whether to INSERT OVERWRITE or not.
    -5652        dialect: the dialect used to parse the input expressions.
    -5653        copy: whether or not to copy the expression.
    -5654        **opts: other options to use to parse the input expressions.
    -5655
    -5656    Returns:
    -5657        Insert: the syntax tree for the INSERT statement.
    -5658    """
    -5659    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
    -5660    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
    -5661
    -5662    if columns:
    -5663        this = _apply_list_builder(
    -5664            *columns,
    -5665            instance=Schema(this=this),
    -5666            arg="expressions",
    -5667            into=Identifier,
    -5668            copy=False,
    -5669            dialect=dialect,
    -5670            **opts,
    -5671        )
    -5672
    -5673    return Insert(this=this, expression=expr, overwrite=overwrite)
    +            
    5701def insert(
    +5702    expression: ExpOrStr,
    +5703    into: ExpOrStr,
    +5704    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
    +5705    overwrite: t.Optional[bool] = None,
    +5706    dialect: DialectType = None,
    +5707    copy: bool = True,
    +5708    **opts,
    +5709) -> Insert:
    +5710    """
    +5711    Builds an INSERT statement.
    +5712
    +5713    Example:
    +5714        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
    +5715        'INSERT INTO tbl VALUES (1, 2, 3)'
    +5716
    +5717    Args:
    +5718        expression: the sql string or expression of the INSERT statement
    +5719        into: the tbl to insert data to.
    +5720        columns: optionally the table's column names.
    +5721        overwrite: whether to INSERT OVERWRITE or not.
    +5722        dialect: the dialect used to parse the input expressions.
    +5723        copy: whether or not to copy the expression.
    +5724        **opts: other options to use to parse the input expressions.
    +5725
    +5726    Returns:
    +5727        Insert: the syntax tree for the INSERT statement.
    +5728    """
    +5729    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
    +5730    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
    +5731
    +5732    if columns:
    +5733        this = _apply_list_builder(
    +5734            *columns,
    +5735            instance=Schema(this=this),
    +5736            arg="expressions",
    +5737            into=Identifier,
    +5738            copy=False,
    +5739            dialect=dialect,
    +5740            **opts,
    +5741        )
    +5742
    +5743    return Insert(this=this, expression=expr, overwrite=overwrite)
     
    @@ -77015,41 +77872,41 @@ auto converted to sql objects eg None -> NULL
    -
    5676def condition(
    -5677    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    -5678) -> Condition:
    -5679    """
    -5680    Initialize a logical condition expression.
    -5681
    -5682    Example:
    -5683        >>> condition("x=1").sql()
    -5684        'x = 1'
    -5685
    -5686        This is helpful for composing larger logical syntax trees:
    -5687        >>> where = condition("x=1")
    -5688        >>> where = where.and_("y=1")
    -5689        >>> Select().from_("tbl").select("*").where(where).sql()
    -5690        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
    -5691
    -5692    Args:
    -5693        *expression: the SQL code string to parse.
    -5694            If an Expression instance is passed, this is used as-is.
    -5695        dialect: the dialect used to parse the input expression (in the case that the
    -5696            input expression is a SQL string).
    -5697        copy: Whether or not to copy `expression` (only applies to expressions).
    -5698        **opts: other options to use to parse the input expressions (again, in the case
    -5699            that the input expression is a SQL string).
    -5700
    -5701    Returns:
    -5702        The new Condition instance
    -5703    """
    -5704    return maybe_parse(
    -5705        expression,
    -5706        into=Condition,
    -5707        dialect=dialect,
    -5708        copy=copy,
    -5709        **opts,
    -5710    )
    +            
    5746def condition(
    +5747    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
    +5748) -> Condition:
    +5749    """
    +5750    Initialize a logical condition expression.
    +5751
    +5752    Example:
    +5753        >>> condition("x=1").sql()
    +5754        'x = 1'
    +5755
    +5756        This is helpful for composing larger logical syntax trees:
    +5757        >>> where = condition("x=1")
    +5758        >>> where = where.and_("y=1")
    +5759        >>> Select().from_("tbl").select("*").where(where).sql()
    +5760        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
    +5761
    +5762    Args:
    +5763        *expression: the SQL code string to parse.
    +5764            If an Expression instance is passed, this is used as-is.
    +5765        dialect: the dialect used to parse the input expression (in the case that the
    +5766            input expression is a SQL string).
    +5767        copy: Whether or not to copy `expression` (only applies to expressions).
    +5768        **opts: other options to use to parse the input expressions (again, in the case
    +5769            that the input expression is a SQL string).
    +5770
    +5771    Returns:
    +5772        The new Condition instance
    +5773    """
    +5774    return maybe_parse(
    +5775        expression,
    +5776        into=Condition,
    +5777        dialect=dialect,
    +5778        copy=copy,
    +5779        **opts,
    +5780    )
     
    @@ -77107,27 +77964,27 @@ that the input expression is a SQL string).
    -
    5713def and_(
    -5714    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
    -5715) -> Condition:
    -5716    """
    -5717    Combine multiple conditions with an AND logical operator.
    -5718
    -5719    Example:
    -5720        >>> and_("x=1", and_("y=1", "z=1")).sql()
    -5721        'x = 1 AND (y = 1 AND z = 1)'
    -5722
    -5723    Args:
    -5724        *expressions: the SQL code strings to parse.
    -5725            If an Expression instance is passed, this is used as-is.
    -5726        dialect: the dialect used to parse the input expression.
    -5727        copy: whether or not to copy `expressions` (only applies to Expressions).
    -5728        **opts: other options to use to parse the input expressions.
    -5729
    -5730    Returns:
    -5731        And: the new condition
    -5732    """
    -5733    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
    +            
    5783def and_(
    +5784    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
    +5785) -> Condition:
    +5786    """
    +5787    Combine multiple conditions with an AND logical operator.
    +5788
    +5789    Example:
    +5790        >>> and_("x=1", and_("y=1", "z=1")).sql()
    +5791        'x = 1 AND (y = 1 AND z = 1)'
    +5792
    +5793    Args:
    +5794        *expressions: the SQL code strings to parse.
    +5795            If an Expression instance is passed, this is used as-is.
    +5796        dialect: the dialect used to parse the input expression.
    +5797        copy: whether or not to copy `expressions` (only applies to Expressions).
    +5798        **opts: other options to use to parse the input expressions.
    +5799
    +5800    Returns:
    +5801        And: the new condition
    +5802    """
    +5803    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
     
    @@ -77173,27 +78030,27 @@ If an Expression instance is passed, this is used as-is.
    -
    5736def or_(
    -5737    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
    -5738) -> Condition:
    -5739    """
    -5740    Combine multiple conditions with an OR logical operator.
    -5741
    -5742    Example:
    -5743        >>> or_("x=1", or_("y=1", "z=1")).sql()
    -5744        'x = 1 OR (y = 1 OR z = 1)'
    -5745
    -5746    Args:
    -5747        *expressions: the SQL code strings to parse.
    -5748            If an Expression instance is passed, this is used as-is.
    -5749        dialect: the dialect used to parse the input expression.
    -5750        copy: whether or not to copy `expressions` (only applies to Expressions).
    -5751        **opts: other options to use to parse the input expressions.
    -5752
    -5753    Returns:
    -5754        Or: the new condition
    -5755    """
    -5756    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
    +            
    5806def or_(
    +5807    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
    +5808) -> Condition:
    +5809    """
    +5810    Combine multiple conditions with an OR logical operator.
    +5811
    +5812    Example:
    +5813        >>> or_("x=1", or_("y=1", "z=1")).sql()
    +5814        'x = 1 OR (y = 1 OR z = 1)'
    +5815
    +5816    Args:
    +5817        *expressions: the SQL code strings to parse.
    +5818            If an Expression instance is passed, this is used as-is.
    +5819        dialect: the dialect used to parse the input expression.
    +5820        copy: whether or not to copy `expressions` (only applies to Expressions).
    +5821        **opts: other options to use to parse the input expressions.
    +5822
    +5823    Returns:
    +5824        Or: the new condition
    +5825    """
    +5826    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
     
    @@ -77239,31 +78096,31 @@ If an Expression instance is passed, this is used as-is.
    -
    5759def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
    -5760    """
    -5761    Wrap a condition with a NOT operator.
    -5762
    -5763    Example:
    -5764        >>> not_("this_suit='black'").sql()
    -5765        "NOT this_suit = 'black'"
    -5766
    -5767    Args:
    -5768        expression: the SQL code string to parse.
    -5769            If an Expression instance is passed, this is used as-is.
    -5770        dialect: the dialect used to parse the input expression.
    -5771        copy: whether to copy the expression or not.
    -5772        **opts: other options to use to parse the input expressions.
    -5773
    -5774    Returns:
    -5775        The new condition.
    -5776    """
    -5777    this = condition(
    -5778        expression,
    -5779        dialect=dialect,
    -5780        copy=copy,
    -5781        **opts,
    -5782    )
    -5783    return Not(this=_wrap(this, Connector))
    +            
    5829def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
    +5830    """
    +5831    Wrap a condition with a NOT operator.
    +5832
    +5833    Example:
    +5834        >>> not_("this_suit='black'").sql()
    +5835        "NOT this_suit = 'black'"
    +5836
    +5837    Args:
    +5838        expression: the SQL code string to parse.
    +5839            If an Expression instance is passed, this is used as-is.
    +5840        dialect: the dialect used to parse the input expression.
    +5841        copy: whether to copy the expression or not.
    +5842        **opts: other options to use to parse the input expressions.
    +5843
    +5844    Returns:
    +5845        The new condition.
    +5846    """
    +5847    this = condition(
    +5848        expression,
    +5849        dialect=dialect,
    +5850        copy=copy,
    +5851        **opts,
    +5852    )
    +5853    return Not(this=_wrap(this, Connector))
     
    @@ -77309,23 +78166,23 @@ If an Expression instance is passed, this is used as-is.
    -
    5786def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
    -5787    """
    -5788    Wrap an expression in parentheses.
    -5789
    -5790    Example:
    -5791        >>> paren("5 + 3").sql()
    -5792        '(5 + 3)'
    -5793
    -5794    Args:
    -5795        expression: the SQL code string to parse.
    -5796            If an Expression instance is passed, this is used as-is.
    -5797        copy: whether to copy the expression or not.
    -5798
    -5799    Returns:
    -5800        The wrapped expression.
    -5801    """
    -5802    return Paren(this=maybe_parse(expression, copy=copy))
    +            
    5856def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
    +5857    """
    +5858    Wrap an expression in parentheses.
    +5859
    +5860    Example:
    +5861        >>> paren("5 + 3").sql()
    +5862        '(5 + 3)'
    +5863
    +5864    Args:
    +5865        expression: the SQL code string to parse.
    +5866            If an Expression instance is passed, this is used as-is.
    +5867        copy: whether to copy the expression or not.
    +5868
    +5869    Returns:
    +5870        The wrapped expression.
    +5871    """
    +5872    return Paren(this=maybe_parse(expression, copy=copy))
     
    @@ -77381,31 +78238,31 @@ If an Expression instance is passed, this is used as-is.
    -
    5820def to_identifier(name, quoted=None, copy=True):
    -5821    """Builds an identifier.
    -5822
    -5823    Args:
    -5824        name: The name to turn into an identifier.
    -5825        quoted: Whether or not force quote the identifier.
    -5826        copy: Whether or not to copy a passed in Identefier node.
    -5827
    -5828    Returns:
    -5829        The identifier ast node.
    -5830    """
    -5831
    -5832    if name is None:
    -5833        return None
    -5834
    -5835    if isinstance(name, Identifier):
    -5836        identifier = maybe_copy(name, copy)
    -5837    elif isinstance(name, str):
    -5838        identifier = Identifier(
    -5839            this=name,
    -5840            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
    -5841        )
    -5842    else:
    -5843        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
    -5844    return identifier
    +            
    5890def to_identifier(name, quoted=None, copy=True):
    +5891    """Builds an identifier.
    +5892
    +5893    Args:
    +5894        name: The name to turn into an identifier.
    +5895        quoted: Whether or not force quote the identifier.
    +5896        copy: Whether or not to copy a passed in Identefier node.
    +5897
    +5898    Returns:
    +5899        The identifier ast node.
    +5900    """
    +5901
    +5902    if name is None:
    +5903        return None
    +5904
    +5905    if isinstance(name, Identifier):
    +5906        identifier = maybe_copy(name, copy)
    +5907    elif isinstance(name, str):
    +5908        identifier = Identifier(
    +5909            this=name,
    +5910            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
    +5911        )
    +5912    else:
    +5913        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
    +5914    return identifier
     
    @@ -77451,23 +78308,23 @@ If an Expression instance is passed, this is used as-is.
    -
    5850def to_interval(interval: str | Literal) -> Interval:
    -5851    """Builds an interval expression from a string like '1 day' or '5 months'."""
    -5852    if isinstance(interval, Literal):
    -5853        if not interval.is_string:
    -5854            raise ValueError("Invalid interval string.")
    -5855
    -5856        interval = interval.this
    -5857
    -5858    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
    -5859
    -5860    if not interval_parts:
    -5861        raise ValueError("Invalid interval string.")
    -5862
    -5863    return Interval(
    -5864        this=Literal.string(interval_parts.group(1)),
    -5865        unit=Var(this=interval_parts.group(2)),
    -5866    )
    +            
    5920def to_interval(interval: str | Literal) -> Interval:
    +5921    """Builds an interval expression from a string like '1 day' or '5 months'."""
    +5922    if isinstance(interval, Literal):
    +5923        if not interval.is_string:
    +5924            raise ValueError("Invalid interval string.")
    +5925
    +5926        interval = interval.this
    +5927
    +5928    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
    +5929
    +5930    if not interval_parts:
    +5931        raise ValueError("Invalid interval string.")
    +5932
    +5933    return Interval(
    +5934        this=Literal.string(interval_parts.group(1)),
    +5935        unit=Var(this=interval_parts.group(2)),
    +5936    )
     
    @@ -77487,32 +78344,32 @@ If an Expression instance is passed, this is used as-is.
    -
    5879def to_table(
    -5880    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
    -5881) -> t.Optional[Table]:
    -5882    """
    -5883    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
    -5884    If a table is passed in then that table is returned.
    -5885
    -5886    Args:
    -5887        sql_path: a `[catalog].[schema].[table]` string.
    -5888        dialect: the source dialect according to which the table name will be parsed.
    -5889        kwargs: the kwargs to instantiate the resulting `Table` expression with.
    -5890
    -5891    Returns:
    -5892        A table expression.
    -5893    """
    -5894    if sql_path is None or isinstance(sql_path, Table):
    -5895        return sql_path
    -5896    if not isinstance(sql_path, str):
    -5897        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
    -5898
    -5899    table = maybe_parse(sql_path, into=Table, dialect=dialect)
    -5900    if table:
    -5901        for k, v in kwargs.items():
    -5902            table.set(k, v)
    -5903
    -5904    return table
    +            
    5949def to_table(
    +5950    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
    +5951) -> t.Optional[Table]:
    +5952    """
    +5953    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
    +5954    If a table is passed in then that table is returned.
    +5955
    +5956    Args:
    +5957        sql_path: a `[catalog].[schema].[table]` string.
    +5958        dialect: the source dialect according to which the table name will be parsed.
    +5959        kwargs: the kwargs to instantiate the resulting `Table` expression with.
    +5960
    +5961    Returns:
    +5962        A table expression.
    +5963    """
    +5964    if sql_path is None or isinstance(sql_path, Table):
    +5965        return sql_path
    +5966    if not isinstance(sql_path, str):
    +5967        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
    +5968
    +5969    table = maybe_parse(sql_path, into=Table, dialect=dialect)
    +5970    if table:
    +5971        for k, v in kwargs.items():
    +5972            table.set(k, v)
    +5973
    +5974    return table
     
    @@ -77547,22 +78404,22 @@ If a table is passed in then that table is returned.

    -
    5907def to_column(sql_path: str | Column, **kwargs) -> Column:
    -5908    """
    -5909    Create a column from a `[table].[column]` sql path. Schema is optional.
    -5910
    -5911    If a column is passed in then that column is returned.
    -5912
    -5913    Args:
    -5914        sql_path: `[table].[column]` string
    -5915    Returns:
    -5916        Table: A column expression
    -5917    """
    -5918    if sql_path is None or isinstance(sql_path, Column):
    -5919        return sql_path
    -5920    if not isinstance(sql_path, str):
    -5921        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
    -5922    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
    +            
    5977def to_column(sql_path: str | Column, **kwargs) -> Column:
    +5978    """
    +5979    Create a column from a `[table].[column]` sql path. Schema is optional.
    +5980
    +5981    If a column is passed in then that column is returned.
    +5982
    +5983    Args:
    +5984        sql_path: `[table].[column]` string
    +5985    Returns:
    +5986        Table: A column expression
    +5987    """
    +5988    if sql_path is None or isinstance(sql_path, Column):
    +5989        return sql_path
    +5990    if not isinstance(sql_path, str):
    +5991        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
    +5992    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
     
    @@ -77596,61 +78453,61 @@ If a table is passed in then that table is returned.

    -
    5925def alias_(
    -5926    expression: ExpOrStr,
    -5927    alias: str | Identifier,
    -5928    table: bool | t.Sequence[str | Identifier] = False,
    -5929    quoted: t.Optional[bool] = None,
    -5930    dialect: DialectType = None,
    -5931    copy: bool = True,
    -5932    **opts,
    -5933):
    -5934    """Create an Alias expression.
    -5935
    -5936    Example:
    -5937        >>> alias_('foo', 'bar').sql()
    -5938        'foo AS bar'
    -5939
    -5940        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
    -5941        '(SELECT 1, 2) AS bar(a, b)'
    -5942
    -5943    Args:
    -5944        expression: the SQL code strings to parse.
    -5945            If an Expression instance is passed, this is used as-is.
    -5946        alias: the alias name to use. If the name has
    -5947            special characters it is quoted.
    -5948        table: Whether or not to create a table alias, can also be a list of columns.
    -5949        quoted: whether or not to quote the alias
    -5950        dialect: the dialect used to parse the input expression.
    -5951        copy: Whether or not to copy the expression.
    -5952        **opts: other options to use to parse the input expressions.
    -5953
    -5954    Returns:
    -5955        Alias: the aliased expression
    -5956    """
    -5957    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
    -5958    alias = to_identifier(alias, quoted=quoted)
    -5959
    -5960    if table:
    -5961        table_alias = TableAlias(this=alias)
    -5962        exp.set("alias", table_alias)
    -5963
    -5964        if not isinstance(table, bool):
    -5965            for column in table:
    -5966                table_alias.append("columns", to_identifier(column, quoted=quoted))
    -5967
    -5968        return exp
    -5969
    -5970    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
    -5971    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
    -5972    # for the complete Window expression.
    -5973    #
    -5974    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
    -5975
    -5976    if "alias" in exp.arg_types and not isinstance(exp, Window):
    -5977        exp.set("alias", alias)
    -5978        return exp
    -5979    return Alias(this=exp, alias=alias)
    +            
    5995def alias_(
    +5996    expression: ExpOrStr,
    +5997    alias: str | Identifier,
    +5998    table: bool | t.Sequence[str | Identifier] = False,
    +5999    quoted: t.Optional[bool] = None,
    +6000    dialect: DialectType = None,
    +6001    copy: bool = True,
    +6002    **opts,
    +6003):
    +6004    """Create an Alias expression.
    +6005
    +6006    Example:
    +6007        >>> alias_('foo', 'bar').sql()
    +6008        'foo AS bar'
    +6009
    +6010        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
    +6011        '(SELECT 1, 2) AS bar(a, b)'
    +6012
    +6013    Args:
    +6014        expression: the SQL code strings to parse.
    +6015            If an Expression instance is passed, this is used as-is.
    +6016        alias: the alias name to use. If the name has
    +6017            special characters it is quoted.
    +6018        table: Whether or not to create a table alias, can also be a list of columns.
    +6019        quoted: whether or not to quote the alias
    +6020        dialect: the dialect used to parse the input expression.
    +6021        copy: Whether or not to copy the expression.
    +6022        **opts: other options to use to parse the input expressions.
    +6023
    +6024    Returns:
    +6025        Alias: the aliased expression
    +6026    """
    +6027    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
    +6028    alias = to_identifier(alias, quoted=quoted)
    +6029
    +6030    if table:
    +6031        table_alias = TableAlias(this=alias)
    +6032        exp.set("alias", table_alias)
    +6033
    +6034        if not isinstance(table, bool):
    +6035            for column in table:
    +6036                table_alias.append("columns", to_identifier(column, quoted=quoted))
    +6037
    +6038        return exp
    +6039
    +6040    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
    +6041    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
    +6042    # for the complete Window expression.
    +6043    #
    +6044    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
    +6045
    +6046    if "alias" in exp.arg_types and not isinstance(exp, Window):
    +6047        exp.set("alias", alias)
    +6048        return exp
    +6049    return Alias(this=exp, alias=alias)
     
    @@ -77706,32 +78563,32 @@ special characters it is quoted.
    -
    5982def subquery(
    -5983    expression: ExpOrStr,
    -5984    alias: t.Optional[Identifier | str] = None,
    -5985    dialect: DialectType = None,
    -5986    **opts,
    -5987) -> Select:
    -5988    """
    -5989    Build a subquery expression.
    -5990
    -5991    Example:
    -5992        >>> subquery('select x from tbl', 'bar').select('x').sql()
    -5993        'SELECT x FROM (SELECT x FROM tbl) AS bar'
    -5994
    -5995    Args:
    -5996        expression: the SQL code strings to parse.
    -5997            If an Expression instance is passed, this is used as-is.
    -5998        alias: the alias name to use.
    -5999        dialect: the dialect used to parse the input expression.
    -6000        **opts: other options to use to parse the input expressions.
    -6001
    -6002    Returns:
    -6003        A new Select instance with the subquery expression included.
    -6004    """
    -6005
    -6006    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
    -6007    return Select().from_(expression, dialect=dialect, **opts)
    +            
    6052def subquery(
    +6053    expression: ExpOrStr,
    +6054    alias: t.Optional[Identifier | str] = None,
    +6055    dialect: DialectType = None,
    +6056    **opts,
    +6057) -> Select:
    +6058    """
    +6059    Build a subquery expression.
    +6060
    +6061    Example:
    +6062        >>> subquery('select x from tbl', 'bar').select('x').sql()
    +6063        'SELECT x FROM (SELECT x FROM tbl) AS bar'
    +6064
    +6065    Args:
    +6066        expression: the SQL code strings to parse.
    +6067            If an Expression instance is passed, this is used as-is.
    +6068        alias: the alias name to use.
    +6069        dialect: the dialect used to parse the input expression.
    +6070        **opts: other options to use to parse the input expressions.
    +6071
    +6072    Returns:
    +6073        A new Select instance with the subquery expression included.
    +6074    """
    +6075
    +6076    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
    +6077    return Select().from_(expression, dialect=dialect, **opts)
     
    @@ -77777,32 +78634,32 @@ If an Expression instance is passed, this is used as-is.
    -
    6010def column(
    -6011    col: str | Identifier,
    -6012    table: t.Optional[str | Identifier] = None,
    -6013    db: t.Optional[str | Identifier] = None,
    -6014    catalog: t.Optional[str | Identifier] = None,
    -6015    quoted: t.Optional[bool] = None,
    -6016) -> Column:
    -6017    """
    -6018    Build a Column.
    -6019
    -6020    Args:
    -6021        col: Column name.
    -6022        table: Table name.
    -6023        db: Database name.
    -6024        catalog: Catalog name.
    -6025        quoted: Whether to force quotes on the column's identifiers.
    -6026
    -6027    Returns:
    -6028        The new Column instance.
    -6029    """
    -6030    return Column(
    -6031        this=to_identifier(col, quoted=quoted),
    -6032        table=to_identifier(table, quoted=quoted),
    -6033        db=to_identifier(db, quoted=quoted),
    -6034        catalog=to_identifier(catalog, quoted=quoted),
    -6035    )
    +            
    6080def column(
    +6081    col: str | Identifier,
    +6082    table: t.Optional[str | Identifier] = None,
    +6083    db: t.Optional[str | Identifier] = None,
    +6084    catalog: t.Optional[str | Identifier] = None,
    +6085    quoted: t.Optional[bool] = None,
    +6086) -> Column:
    +6087    """
    +6088    Build a Column.
    +6089
    +6090    Args:
    +6091        col: Column name.
    +6092        table: Table name.
    +6093        db: Database name.
    +6094        catalog: Catalog name.
    +6095        quoted: Whether to force quotes on the column's identifiers.
    +6096
    +6097    Returns:
    +6098        The new Column instance.
    +6099    """
    +6100    return Column(
    +6101        this=to_identifier(col, quoted=quoted),
    +6102        table=to_identifier(table, quoted=quoted),
    +6103        db=to_identifier(db, quoted=quoted),
    +6104        catalog=to_identifier(catalog, quoted=quoted),
    +6105    )
     
    @@ -77838,25 +78695,25 @@ If an Expression instance is passed, this is used as-is.
    -
    6038def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
    -6039    """Cast an expression to a data type.
    -6040
    -6041    Example:
    -6042        >>> cast('x + 1', 'int').sql()
    -6043        'CAST(x + 1 AS INT)'
    -6044
    -6045    Args:
    -6046        expression: The expression to cast.
    -6047        to: The datatype to cast to.
    -6048
    -6049    Returns:
    -6050        The new Cast instance.
    -6051    """
    -6052    expression = maybe_parse(expression, **opts)
    -6053    data_type = DataType.build(to, **opts)
    -6054    expression = Cast(this=expression, to=data_type)
    -6055    expression.type = data_type
    -6056    return expression
    +            
    6108def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
    +6109    """Cast an expression to a data type.
    +6110
    +6111    Example:
    +6112        >>> cast('x + 1', 'int').sql()
    +6113        'CAST(x + 1 AS INT)'
    +6114
    +6115    Args:
    +6116        expression: The expression to cast.
    +6117        to: The datatype to cast to.
    +6118
    +6119    Returns:
    +6120        The new Cast instance.
    +6121    """
    +6122    expression = maybe_parse(expression, **opts)
    +6123    data_type = DataType.build(to, **opts)
    +6124    expression = Cast(this=expression, to=data_type)
    +6125    expression.type = data_type
    +6126    return expression
     
    @@ -77899,31 +78756,31 @@ If an Expression instance is passed, this is used as-is.
    -
    6059def table_(
    -6060    table: Identifier | str,
    -6061    db: t.Optional[Identifier | str] = None,
    -6062    catalog: t.Optional[Identifier | str] = None,
    -6063    quoted: t.Optional[bool] = None,
    -6064    alias: t.Optional[Identifier | str] = None,
    -6065) -> Table:
    -6066    """Build a Table.
    -6067
    -6068    Args:
    -6069        table: Table name.
    -6070        db: Database name.
    -6071        catalog: Catalog name.
    -6072        quote: Whether to force quotes on the table's identifiers.
    -6073        alias: Table's alias.
    -6074
    -6075    Returns:
    -6076        The new Table instance.
    -6077    """
    -6078    return Table(
    -6079        this=to_identifier(table, quoted=quoted) if table else None,
    -6080        db=to_identifier(db, quoted=quoted) if db else None,
    -6081        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
    -6082        alias=TableAlias(this=to_identifier(alias)) if alias else None,
    -6083    )
    +            
    6129def table_(
    +6130    table: Identifier | str,
    +6131    db: t.Optional[Identifier | str] = None,
    +6132    catalog: t.Optional[Identifier | str] = None,
    +6133    quoted: t.Optional[bool] = None,
    +6134    alias: t.Optional[Identifier | str] = None,
    +6135) -> Table:
    +6136    """Build a Table.
    +6137
    +6138    Args:
    +6139        table: Table name.
    +6140        db: Database name.
    +6141        catalog: Catalog name.
    +6142        quote: Whether to force quotes on the table's identifiers.
    +6143        alias: Table's alias.
    +6144
    +6145    Returns:
    +6146        The new Table instance.
    +6147    """
    +6148    return Table(
    +6149        this=to_identifier(table, quoted=quoted) if table else None,
    +6150        db=to_identifier(db, quoted=quoted) if db else None,
    +6151        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
    +6152        alias=TableAlias(this=to_identifier(alias)) if alias else None,
    +6153    )
     
    @@ -77959,37 +78816,37 @@ If an Expression instance is passed, this is used as-is.
    -
    6086def values(
    -6087    values: t.Iterable[t.Tuple[t.Any, ...]],
    -6088    alias: t.Optional[str] = None,
    -6089    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
    -6090) -> Values:
    -6091    """Build VALUES statement.
    -6092
    -6093    Example:
    -6094        >>> values([(1, '2')]).sql()
    -6095        "VALUES (1, '2')"
    -6096
    -6097    Args:
    -6098        values: values statements that will be converted to SQL
    -6099        alias: optional alias
    -6100        columns: Optional list of ordered column names or ordered dictionary of column names to types.
    -6101         If either are provided then an alias is also required.
    -6102
    -6103    Returns:
    -6104        Values: the Values expression object
    -6105    """
    -6106    if columns and not alias:
    -6107        raise ValueError("Alias is required when providing columns")
    -6108
    -6109    return Values(
    -6110        expressions=[convert(tup) for tup in values],
    -6111        alias=(
    -6112            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
    -6113            if columns
    -6114            else (TableAlias(this=to_identifier(alias)) if alias else None)
    -6115        ),
    -6116    )
    +            
    6156def values(
    +6157    values: t.Iterable[t.Tuple[t.Any, ...]],
    +6158    alias: t.Optional[str] = None,
    +6159    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
    +6160) -> Values:
    +6161    """Build VALUES statement.
    +6162
    +6163    Example:
    +6164        >>> values([(1, '2')]).sql()
    +6165        "VALUES (1, '2')"
    +6166
    +6167    Args:
    +6168        values: values statements that will be converted to SQL
    +6169        alias: optional alias
    +6170        columns: Optional list of ordered column names or ordered dictionary of column names to types.
    +6171         If either are provided then an alias is also required.
    +6172
    +6173    Returns:
    +6174        Values: the Values expression object
    +6175    """
    +6176    if columns and not alias:
    +6177        raise ValueError("Alias is required when providing columns")
    +6178
    +6179    return Values(
    +6180        expressions=[convert(tup) for tup in values],
    +6181        alias=(
    +6182            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
    +6183            if columns
    +6184            else (TableAlias(this=to_identifier(alias)) if alias else None)
    +6185        ),
    +6186    )
     
    @@ -78034,28 +78891,28 @@ If either are provided then an alias is also required.
    -
    6119def var(name: t.Optional[ExpOrStr]) -> Var:
    -6120    """Build a SQL variable.
    -6121
    -6122    Example:
    -6123        >>> repr(var('x'))
    -6124        '(VAR this: x)'
    -6125
    -6126        >>> repr(var(column('x', table='y')))
    -6127        '(VAR this: x)'
    -6128
    -6129    Args:
    -6130        name: The name of the var or an expression who's name will become the var.
    -6131
    -6132    Returns:
    -6133        The new variable node.
    -6134    """
    -6135    if not name:
    -6136        raise ValueError("Cannot convert empty name into var.")
    -6137
    -6138    if isinstance(name, Expression):
    -6139        name = name.name
    -6140    return Var(this=name)
    +            
    6189def var(name: t.Optional[ExpOrStr]) -> Var:
    +6190    """Build a SQL variable.
    +6191
    +6192    Example:
    +6193        >>> repr(var('x'))
    +6194        '(VAR this: x)'
    +6195
    +6196        >>> repr(var(column('x', table='y')))
    +6197        '(VAR this: x)'
    +6198
    +6199    Args:
    +6200        name: The name of the var or an expression who's name will become the var.
    +6201
    +6202    Returns:
    +6203        The new variable node.
    +6204    """
    +6205    if not name:
    +6206        raise ValueError("Cannot convert empty name into var.")
    +6207
    +6208    if isinstance(name, Expression):
    +6209        name = name.name
    +6210    return Var(this=name)
     
    @@ -78103,24 +78960,24 @@ If either are provided then an alias is also required.
    -
    6143def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
    -6144    """Build ALTER TABLE... RENAME... expression
    -6145
    -6146    Args:
    -6147        old_name: The old name of the table
    -6148        new_name: The new name of the table
    -6149
    -6150    Returns:
    -6151        Alter table expression
    -6152    """
    -6153    old_table = to_table(old_name)
    -6154    new_table = to_table(new_name)
    -6155    return AlterTable(
    -6156        this=old_table,
    -6157        actions=[
    -6158            RenameTable(this=new_table),
    -6159        ],
    -6160    )
    +            
    6213def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
    +6214    """Build ALTER TABLE... RENAME... expression
    +6215
    +6216    Args:
    +6217        old_name: The old name of the table
    +6218        new_name: The new name of the table
    +6219
    +6220    Returns:
    +6221        Alter table expression
    +6222    """
    +6223    old_table = to_table(old_name)
    +6224    new_table = to_table(new_name)
    +6225    return AlterTable(
    +6226        this=old_table,
    +6227        actions=[
    +6228            RenameTable(this=new_table),
    +6229        ],
    +6230    )
     
    @@ -78153,46 +79010,46 @@ If either are provided then an alias is also required.
    -
    6163def convert(value: t.Any, copy: bool = False) -> Expression:
    -6164    """Convert a python value into an expression object.
    -6165
    -6166    Raises an error if a conversion is not possible.
    -6167
    -6168    Args:
    -6169        value: A python object.
    -6170        copy: Whether or not to copy `value` (only applies to Expressions and collections).
    -6171
    -6172    Returns:
    -6173        Expression: the equivalent expression object.
    -6174    """
    -6175    if isinstance(value, Expression):
    -6176        return maybe_copy(value, copy)
    -6177    if isinstance(value, str):
    -6178        return Literal.string(value)
    -6179    if isinstance(value, bool):
    -6180        return Boolean(this=value)
    -6181    if value is None or (isinstance(value, float) and math.isnan(value)):
    -6182        return NULL
    -6183    if isinstance(value, numbers.Number):
    -6184        return Literal.number(value)
    -6185    if isinstance(value, datetime.datetime):
    -6186        datetime_literal = Literal.string(
    -6187            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
    -6188        )
    -6189        return TimeStrToTime(this=datetime_literal)
    -6190    if isinstance(value, datetime.date):
    -6191        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
    -6192        return DateStrToDate(this=date_literal)
    -6193    if isinstance(value, tuple):
    -6194        return Tuple(expressions=[convert(v, copy=copy) for v in value])
    -6195    if isinstance(value, list):
    -6196        return Array(expressions=[convert(v, copy=copy) for v in value])
    -6197    if isinstance(value, dict):
    -6198        return Map(
    -6199            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
    -6200            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
    -6201        )
    -6202    raise ValueError(f"Cannot convert {value}")
    +            
    6233def convert(value: t.Any, copy: bool = False) -> Expression:
    +6234    """Convert a python value into an expression object.
    +6235
    +6236    Raises an error if a conversion is not possible.
    +6237
    +6238    Args:
    +6239        value: A python object.
    +6240        copy: Whether or not to copy `value` (only applies to Expressions and collections).
    +6241
    +6242    Returns:
    +6243        Expression: the equivalent expression object.
    +6244    """
    +6245    if isinstance(value, Expression):
    +6246        return maybe_copy(value, copy)
    +6247    if isinstance(value, str):
    +6248        return Literal.string(value)
    +6249    if isinstance(value, bool):
    +6250        return Boolean(this=value)
    +6251    if value is None or (isinstance(value, float) and math.isnan(value)):
    +6252        return NULL
    +6253    if isinstance(value, numbers.Number):
    +6254        return Literal.number(value)
    +6255    if isinstance(value, datetime.datetime):
    +6256        datetime_literal = Literal.string(
    +6257            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
    +6258        )
    +6259        return TimeStrToTime(this=datetime_literal)
    +6260    if isinstance(value, datetime.date):
    +6261        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
    +6262        return DateStrToDate(this=date_literal)
    +6263    if isinstance(value, tuple):
    +6264        return Tuple(expressions=[convert(v, copy=copy) for v in value])
    +6265    if isinstance(value, list):
    +6266        return Array(expressions=[convert(v, copy=copy) for v in value])
    +6267    if isinstance(value, dict):
    +6268        return Map(
    +6269            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
    +6270            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
    +6271        )
    +6272    raise ValueError(f"Cannot convert {value}")
     
    @@ -78227,26 +79084,26 @@ If either are provided then an alias is also required.
    -
    6205def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
    -6206    """
    -6207    Replace children of an expression with the result of a lambda fun(child) -> exp.
    -6208    """
    -6209    for k, v in expression.args.items():
    -6210        is_list_arg = type(v) is list
    -6211
    -6212        child_nodes = v if is_list_arg else [v]
    -6213        new_child_nodes = []
    -6214
    -6215        for cn in child_nodes:
    -6216            if isinstance(cn, Expression):
    -6217                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
    -6218                    new_child_nodes.append(child_node)
    -6219                    child_node.parent = expression
    -6220                    child_node.arg_key = k
    -6221            else:
    -6222                new_child_nodes.append(cn)
    -6223
    -6224        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
    +            
    6275def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
    +6276    """
    +6277    Replace children of an expression with the result of a lambda fun(child) -> exp.
    +6278    """
    +6279    for k, v in expression.args.items():
    +6280        is_list_arg = type(v) is list
    +6281
    +6282        child_nodes = v if is_list_arg else [v]
    +6283        new_child_nodes = []
    +6284
    +6285        for cn in child_nodes:
    +6286            if isinstance(cn, Expression):
    +6287                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
    +6288                    new_child_nodes.append(child_node)
    +6289                    child_node.parent = expression
    +6290                    child_node.arg_key = k
    +6291            else:
    +6292                new_child_nodes.append(cn)
    +6293
    +6294        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
     
    @@ -78266,27 +79123,27 @@ If either are provided then an alias is also required.
    -
    6227def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
    -6228    """
    -6229    Return all table names referenced through columns in an expression.
    -6230
    -6231    Example:
    -6232        >>> import sqlglot
    -6233        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
    -6234        ['a', 'c']
    -6235
    -6236    Args:
    -6237        expression: expression to find table names.
    -6238        exclude: a table name to exclude
    -6239
    -6240    Returns:
    -6241        A list of unique names.
    -6242    """
    -6243    return {
    -6244        table
    -6245        for table in (column.table for column in expression.find_all(Column))
    -6246        if table and table != exclude
    -6247    }
    +            
    6297def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
    +6298    """
    +6299    Return all table names referenced through columns in an expression.
    +6300
    +6301    Example:
    +6302        >>> import sqlglot
    +6303        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
    +6304        ['a', 'c']
    +6305
    +6306    Args:
    +6307        expression: expression to find table names.
    +6308        exclude: a table name to exclude
    +6309
    +6310    Returns:
    +6311        A list of unique names.
    +6312    """
    +6313    return {
    +6314        table
    +6315        for table in (column.table for column in expression.find_all(Column))
    +6316        if table and table != exclude
    +6317    }
     
    @@ -78330,33 +79187,33 @@ If either are provided then an alias is also required.
    -
    6250def table_name(table: Table | str, dialect: DialectType = None) -> str:
    -6251    """Get the full name of a table as a string.
    -6252
    -6253    Args:
    -6254        table: Table expression node or string.
    -6255        dialect: The dialect to generate the table name for.
    -6256
    -6257    Examples:
    -6258        >>> from sqlglot import exp, parse_one
    -6259        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
    -6260        'a.b.c'
    -6261
    -6262    Returns:
    -6263        The table name.
    -6264    """
    -6265
    -6266    table = maybe_parse(table, into=Table, dialect=dialect)
    -6267
    -6268    if not table:
    -6269        raise ValueError(f"Cannot parse {table}")
    -6270
    -6271    return ".".join(
    -6272        part.sql(dialect=dialect, identify=True)
    -6273        if not SAFE_IDENTIFIER_RE.match(part.name)
    -6274        else part.name
    -6275        for part in table.parts
    -6276    )
    +            
    6320def table_name(table: Table | str, dialect: DialectType = None) -> str:
    +6321    """Get the full name of a table as a string.
    +6322
    +6323    Args:
    +6324        table: Table expression node or string.
    +6325        dialect: The dialect to generate the table name for.
    +6326
    +6327    Examples:
    +6328        >>> from sqlglot import exp, parse_one
    +6329        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
    +6330        'a.b.c'
    +6331
    +6332    Returns:
    +6333        The table name.
    +6334    """
    +6335
    +6336    table = maybe_parse(table, into=Table, dialect=dialect)
    +6337
    +6338    if not table:
    +6339        raise ValueError(f"Cannot parse {table}")
    +6340
    +6341    return ".".join(
    +6342        part.sql(dialect=dialect, identify=True)
    +6343        if not SAFE_IDENTIFIER_RE.match(part.name)
    +6344        else part.name
    +6345        for part in table.parts
    +6346    )
     
    @@ -78400,34 +79257,34 @@ If either are provided then an alias is also required.
    -
    6279def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
    -6280    """Replace all tables in expression according to the mapping.
    -6281
    -6282    Args:
    -6283        expression: expression node to be transformed and replaced.
    -6284        mapping: mapping of table names.
    -6285        copy: whether or not to copy the expression.
    -6286
    -6287    Examples:
    -6288        >>> from sqlglot import exp, parse_one
    -6289        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
    -6290        'SELECT * FROM c'
    -6291
    -6292    Returns:
    -6293        The mapped expression.
    -6294    """
    -6295
    -6296    def _replace_tables(node: Expression) -> Expression:
    -6297        if isinstance(node, Table):
    -6298            new_name = mapping.get(table_name(node))
    -6299            if new_name:
    -6300                return to_table(
    -6301                    new_name,
    -6302                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
    -6303                )
    -6304        return node
    -6305
    -6306    return expression.transform(_replace_tables, copy=copy)
    +            
    6349def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
    +6350    """Replace all tables in expression according to the mapping.
    +6351
    +6352    Args:
    +6353        expression: expression node to be transformed and replaced.
    +6354        mapping: mapping of table names.
    +6355        copy: whether or not to copy the expression.
    +6356
    +6357    Examples:
    +6358        >>> from sqlglot import exp, parse_one
    +6359        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
    +6360        'SELECT * FROM c'
    +6361
    +6362    Returns:
    +6363        The mapped expression.
    +6364    """
    +6365
    +6366    def _replace_tables(node: Expression) -> Expression:
    +6367        if isinstance(node, Table):
    +6368            new_name = mapping.get(table_name(node))
    +6369            if new_name:
    +6370                return to_table(
    +6371                    new_name,
    +6372                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
    +6373                )
    +6374        return node
    +6375
    +6376    return expression.transform(_replace_tables, copy=copy)
     
    @@ -78472,40 +79329,40 @@ If either are provided then an alias is also required.
    -
    6309def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
    -6310    """Replace placeholders in an expression.
    -6311
    -6312    Args:
    -6313        expression: expression node to be transformed and replaced.
    -6314        args: positional names that will substitute unnamed placeholders in the given order.
    -6315        kwargs: keyword arguments that will substitute named placeholders.
    -6316
    -6317    Examples:
    -6318        >>> from sqlglot import exp, parse_one
    -6319        >>> replace_placeholders(
    -6320        ...     parse_one("select * from :tbl where ? = ?"),
    -6321        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
    -6322        ... ).sql()
    -6323        "SELECT * FROM foo WHERE str_col = 'b'"
    -6324
    -6325    Returns:
    -6326        The mapped expression.
    -6327    """
    -6328
    -6329    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
    -6330        if isinstance(node, Placeholder):
    -6331            if node.name:
    -6332                new_name = kwargs.get(node.name)
    -6333                if new_name:
    -6334                    return convert(new_name)
    -6335            else:
    -6336                try:
    -6337                    return convert(next(args))
    -6338                except StopIteration:
    -6339                    pass
    -6340        return node
    -6341
    -6342    return expression.transform(_replace_placeholders, iter(args), **kwargs)
    +            
    6379def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
    +6380    """Replace placeholders in an expression.
    +6381
    +6382    Args:
    +6383        expression: expression node to be transformed and replaced.
    +6384        args: positional names that will substitute unnamed placeholders in the given order.
    +6385        kwargs: keyword arguments that will substitute named placeholders.
    +6386
    +6387    Examples:
    +6388        >>> from sqlglot import exp, parse_one
    +6389        >>> replace_placeholders(
    +6390        ...     parse_one("select * from :tbl where ? = ?"),
    +6391        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
    +6392        ... ).sql()
    +6393        "SELECT * FROM foo WHERE str_col = 'b'"
    +6394
    +6395    Returns:
    +6396        The mapped expression.
    +6397    """
    +6398
    +6399    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
    +6400        if isinstance(node, Placeholder):
    +6401            if node.name:
    +6402                new_name = kwargs.get(node.name)
    +6403                if new_name:
    +6404                    return convert(new_name)
    +6405            else:
    +6406                try:
    +6407                    return convert(next(args))
    +6408                except StopIteration:
    +6409                    pass
    +6410        return node
    +6411
    +6412    return expression.transform(_replace_placeholders, iter(args), **kwargs)
     
    @@ -78553,39 +79410,39 @@ If either are provided then an alias is also required.
    -
    6345def expand(
    -6346    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
    -6347) -> Expression:
    -6348    """Transforms an expression by expanding all referenced sources into subqueries.
    -6349
    -6350    Examples:
    -6351        >>> from sqlglot import parse_one
    -6352        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
    -6353        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
    -6354
    -6355        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
    -6356        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
    -6357
    -6358    Args:
    -6359        expression: The expression to expand.
    -6360        sources: A dictionary of name to Subqueryables.
    -6361        copy: Whether or not to copy the expression during transformation. Defaults to True.
    -6362
    -6363    Returns:
    -6364        The transformed expression.
    -6365    """
    -6366
    -6367    def _expand(node: Expression):
    -6368        if isinstance(node, Table):
    -6369            name = table_name(node)
    -6370            source = sources.get(name)
    -6371            if source:
    -6372                subquery = source.subquery(node.alias or name)
    -6373                subquery.comments = [f"source: {name}"]
    -6374                return subquery.transform(_expand, copy=False)
    -6375        return node
    -6376
    -6377    return expression.transform(_expand, copy=copy)
    +            
    6415def expand(
    +6416    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
    +6417) -> Expression:
    +6418    """Transforms an expression by expanding all referenced sources into subqueries.
    +6419
    +6420    Examples:
    +6421        >>> from sqlglot import parse_one
    +6422        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
    +6423        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
    +6424
    +6425        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
    +6426        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
    +6427
    +6428    Args:
    +6429        expression: The expression to expand.
    +6430        sources: A dictionary of name to Subqueryables.
    +6431        copy: Whether or not to copy the expression during transformation. Defaults to True.
    +6432
    +6433    Returns:
    +6434        The transformed expression.
    +6435    """
    +6436
    +6437    def _expand(node: Expression):
    +6438        if isinstance(node, Table):
    +6439            name = table_name(node)
    +6440            source = sources.get(name)
    +6441            if source:
    +6442                subquery = source.subquery(node.alias or name)
    +6443                subquery.comments = [f"source: {name}"]
    +6444                return subquery.transform(_expand, copy=False)
    +6445        return node
    +6446
    +6447    return expression.transform(_expand, copy=copy)
     
    @@ -78636,51 +79493,51 @@ If either are provided then an alias is also required.
    -
    6380def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
    -6381    """
    -6382    Returns a Func expression.
    -6383
    -6384    Examples:
    -6385        >>> func("abs", 5).sql()
    -6386        'ABS(5)'
    -6387
    -6388        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
    -6389        'CAST(5 AS DOUBLE)'
    -6390
    -6391    Args:
    -6392        name: the name of the function to build.
    -6393        args: the args used to instantiate the function of interest.
    -6394        dialect: the source dialect.
    -6395        kwargs: the kwargs used to instantiate the function of interest.
    -6396
    -6397    Note:
    -6398        The arguments `args` and `kwargs` are mutually exclusive.
    -6399
    -6400    Returns:
    -6401        An instance of the function of interest, or an anonymous function, if `name` doesn't
    -6402        correspond to an existing `sqlglot.expressions.Func` class.
    -6403    """
    -6404    if args and kwargs:
    -6405        raise ValueError("Can't use both args and kwargs to instantiate a function.")
    -6406
    -6407    from sqlglot.dialects.dialect import Dialect
    -6408
    -6409    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
    -6410    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
    -6411
    -6412    parser = Dialect.get_or_raise(dialect)().parser()
    -6413    from_args_list = parser.FUNCTIONS.get(name.upper())
    -6414
    -6415    if from_args_list:
    -6416        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
    -6417    else:
    -6418        kwargs = kwargs or {"expressions": converted}
    -6419        function = Anonymous(this=name, **kwargs)
    -6420
    -6421    for error_message in function.error_messages(converted):
    -6422        raise ValueError(error_message)
    -6423
    -6424    return function
    +            
    6450def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
    +6451    """
    +6452    Returns a Func expression.
    +6453
    +6454    Examples:
    +6455        >>> func("abs", 5).sql()
    +6456        'ABS(5)'
    +6457
    +6458        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
    +6459        'CAST(5 AS DOUBLE)'
    +6460
    +6461    Args:
    +6462        name: the name of the function to build.
    +6463        args: the args used to instantiate the function of interest.
    +6464        dialect: the source dialect.
    +6465        kwargs: the kwargs used to instantiate the function of interest.
    +6466
    +6467    Note:
    +6468        The arguments `args` and `kwargs` are mutually exclusive.
    +6469
    +6470    Returns:
    +6471        An instance of the function of interest, or an anonymous function, if `name` doesn't
    +6472        correspond to an existing `sqlglot.expressions.Func` class.
    +6473    """
    +6474    if args and kwargs:
    +6475        raise ValueError("Can't use both args and kwargs to instantiate a function.")
    +6476
    +6477    from sqlglot.dialects.dialect import Dialect
    +6478
    +6479    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
    +6480    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
    +6481
    +6482    parser = Dialect.get_or_raise(dialect)().parser()
    +6483    from_args_list = parser.FUNCTIONS.get(name.upper())
    +6484
    +6485    if from_args_list:
    +6486        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
    +6487    else:
    +6488        kwargs = kwargs or {"expressions": converted}
    +6489        function = Anonymous(this=name, **kwargs)
    +6490
    +6491    for error_message in function.error_messages(converted):
    +6492        raise ValueError(error_message)
    +6493
    +6494    return function
     
    @@ -78738,11 +79595,11 @@ If either are provided then an alias is also required.
    -
    6427def true() -> Boolean:
    -6428    """
    -6429    Returns a true Boolean expression.
    -6430    """
    -6431    return Boolean(this=True)
    +            
    6497def true() -> Boolean:
    +6498    """
    +6499    Returns a true Boolean expression.
    +6500    """
    +6501    return Boolean(this=True)
     
    @@ -78762,11 +79619,11 @@ If either are provided then an alias is also required.
    -
    6434def false() -> Boolean:
    -6435    """
    -6436    Returns a false Boolean expression.
    -6437    """
    -6438    return Boolean(this=False)
    +            
    6504def false() -> Boolean:
    +6505    """
    +6506    Returns a false Boolean expression.
    +6507    """
    +6508    return Boolean(this=False)
     
    @@ -78786,11 +79643,11 @@ If either are provided then an alias is also required.
    -
    6441def null() -> Null:
    -6442    """
    -6443    Returns a Null expression.
    -6444    """
    -6445    return Null()
    +            
    6511def null() -> Null:
    +6512    """
    +6513    Returns a Null expression.
    +6514    """
    +6515    return Null()
     
    -- cgit v1.2.3