1
0
Fork 0

Merging upstream version 12.2.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 15:53:39 +01:00
parent fffa0d5761
commit 62b2b24d3b
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
100 changed files with 35022 additions and 30936 deletions

View file

@ -126,9 +126,17 @@ class Parser(metaclass=_Parser):
TokenType.BIT,
TokenType.BOOLEAN,
TokenType.TINYINT,
TokenType.UTINYINT,
TokenType.SMALLINT,
TokenType.USMALLINT,
TokenType.INT,
TokenType.UINT,
TokenType.BIGINT,
TokenType.UBIGINT,
TokenType.INT128,
TokenType.UINT128,
TokenType.INT256,
TokenType.UINT256,
TokenType.FLOAT,
TokenType.DOUBLE,
TokenType.CHAR,
@ -961,14 +969,15 @@ class Parser(metaclass=_Parser):
The target expression.
"""
instance = exp_class(**kwargs)
if self._prev_comments:
instance.comments = self._prev_comments
self._prev_comments = None
if comments:
instance.comments = comments
instance.add_comments(comments) if comments else self._add_comments(instance)
self.validate_expression(instance)
return instance
def _add_comments(self, expression: t.Optional[exp.Expression]) -> None:
if expression and self._prev_comments:
expression.add_comments(self._prev_comments)
self._prev_comments = None
def validate_expression(
self, expression: exp.Expression, args: t.Optional[t.List] = None
) -> None:
@ -1567,7 +1576,7 @@ class Parser(metaclass=_Parser):
value = self.expression(
exp.Schema,
this="TABLE",
expressions=self._parse_csv(self._parse_struct_kwargs),
expressions=self._parse_csv(self._parse_struct_types),
)
if not self._match(TokenType.GT):
self.raise_error("Expecting >")
@ -1802,14 +1811,15 @@ class Parser(metaclass=_Parser):
elif self._match(TokenType.SELECT):
comments = self._prev_comments
hint = self._parse_hint()
all_ = self._match(TokenType.ALL)
distinct = self._match(TokenType.DISTINCT)
kind = (
self._match(TokenType.ALIAS)
and self._match_texts(("STRUCT", "VALUE"))
and self._prev.text
)
hint = self._parse_hint()
all_ = self._match(TokenType.ALL)
distinct = self._match(TokenType.DISTINCT)
if distinct:
distinct = self.expression(
@ -2284,7 +2294,7 @@ class Parser(metaclass=_Parser):
if not self._match(TokenType.UNNEST):
return None
expressions = self._parse_wrapped_csv(self._parse_column)
expressions = self._parse_wrapped_csv(self._parse_type)
ordinality = self._match_pair(TokenType.WITH, TokenType.ORDINALITY)
alias = self._parse_table_alias()
@ -2333,7 +2343,9 @@ class Parser(metaclass=_Parser):
size = None
seed = None
kind = "TABLESAMPLE" if self._prev.token_type == TokenType.TABLE_SAMPLE else "USING SAMPLE"
kind = (
self._prev.text if self._prev.token_type == TokenType.TABLE_SAMPLE else "USING SAMPLE"
)
method = self._parse_var(tokens=(TokenType.ROW,))
self._match(TokenType.L_PAREN)
@ -2684,7 +2696,7 @@ class Parser(metaclass=_Parser):
else:
this = self.expression(exp.In, this=this, expressions=expressions)
self._match_r_paren()
self._match_r_paren(this)
else:
this = self.expression(exp.In, this=this, field=self._parse_field())
@ -2798,7 +2810,7 @@ class Parser(metaclass=_Parser):
if self._match(TokenType.L_PAREN):
if is_struct:
expressions = self._parse_csv(self._parse_struct_kwargs)
expressions = self._parse_csv(self._parse_struct_types)
elif nested:
expressions = self._parse_csv(self._parse_types)
else:
@ -2833,7 +2845,7 @@ class Parser(metaclass=_Parser):
values: t.Optional[t.List[t.Optional[exp.Expression]]] = None
if nested and self._match(TokenType.LT):
if is_struct:
expressions = self._parse_csv(self._parse_struct_kwargs)
expressions = self._parse_csv(self._parse_struct_types)
else:
expressions = self._parse_csv(self._parse_types)
@ -2891,16 +2903,10 @@ class Parser(metaclass=_Parser):
prefix=prefix,
)
def _parse_struct_kwargs(self) -> t.Optional[exp.Expression]:
index = self._index
this = self._parse_id_var()
def _parse_struct_types(self) -> t.Optional[exp.Expression]:
this = self._parse_type() or self._parse_id_var()
self._match(TokenType.COLON)
data_type = self._parse_types()
if not data_type:
self._retreat(index)
return self._parse_types()
return self.expression(exp.StructKwarg, this=this, expression=data_type)
return self._parse_column_def(this)
def _parse_at_time_zone(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
if not self._match(TokenType.AT_TIME_ZONE):
@ -2932,7 +2938,11 @@ class Parser(metaclass=_Parser):
else exp.Literal.string(value)
)
else:
field = self._parse_star() or self._parse_function() or self._parse_id_var()
field = (
self._parse_star()
or self._parse_function(anonymous=True)
or self._parse_id_var()
)
if isinstance(field, exp.Func):
# bigquery allows function calls like x.y.count(...)
@ -2995,11 +3005,9 @@ class Parser(metaclass=_Parser):
else:
this = self.expression(exp.Paren, this=self._parse_set_operations(this))
self._match_r_paren()
comments.extend(self._prev_comments)
if this and comments:
this.comments = comments
if this:
this.add_comments(comments)
self._match_r_paren(expression=this)
return this
@ -3017,7 +3025,7 @@ class Parser(metaclass=_Parser):
)
def _parse_function(
self, functions: t.Optional[t.Dict[str, t.Callable]] = None
self, functions: t.Optional[t.Dict[str, t.Callable]] = None, anonymous: bool = False
) -> t.Optional[exp.Expression]:
if not self._curr:
return None
@ -3043,7 +3051,7 @@ class Parser(metaclass=_Parser):
parser = self.FUNCTION_PARSERS.get(upper)
if parser:
if parser and not anonymous:
this = parser(self)
else:
subquery_predicate = self.SUBQUERY_PREDICATES.get(token_type)
@ -3059,7 +3067,7 @@ class Parser(metaclass=_Parser):
function = functions.get(upper)
args = self._parse_csv(self._parse_lambda)
if function:
if function and not anonymous:
# Clickhouse supports function calls like foo(x, y)(z), so for these we need to also parse the
# second parameter list (i.e. "(z)") and the corresponding function will receive both arg lists.
if count_params(function) == 2:
@ -3148,12 +3156,7 @@ class Parser(metaclass=_Parser):
if isinstance(left, exp.Column):
left.replace(exp.Var(this=left.text("this")))
if self._match(TokenType.IGNORE_NULLS):
this = self.expression(exp.IgnoreNulls, this=this)
else:
self._match(TokenType.RESPECT_NULLS)
return self._parse_limit(self._parse_order(this))
return self._parse_limit(self._parse_order(self._parse_respect_or_ignore_nulls(this)))
def _parse_schema(self, this: t.Optional[exp.Expression] = None) -> t.Optional[exp.Expression]:
index = self._index
@ -3177,6 +3180,9 @@ class Parser(metaclass=_Parser):
return self.expression(exp.Schema, this=this, expressions=args)
def _parse_column_def(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
# column defs are not really columns, they're identifiers
if isinstance(this, exp.Column):
this = this.this
kind = self._parse_types()
if self._match_text_seq("FOR", "ORDINALITY"):
@ -3420,7 +3426,7 @@ class Parser(metaclass=_Parser):
elif not self._match(TokenType.R_BRACE) and bracket_kind == TokenType.L_BRACE:
self.raise_error("Expected }")
this.comments = self._prev_comments
self._add_comments(this)
return self._parse_bracket(this)
def _parse_slice(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
@ -3584,7 +3590,9 @@ class Parser(metaclass=_Parser):
exp.and_(
exp.Is(this=expression.copy(), expression=exp.Null()),
exp.Is(this=search.copy(), expression=exp.Null()),
copy=False,
),
copy=False,
)
ifs.append(exp.If(this=cond, true=result))
@ -3717,15 +3725,15 @@ class Parser(metaclass=_Parser):
if self._match_set(self.TRIM_TYPES):
position = self._prev.text.upper()
expression = self._parse_term()
expression = self._parse_bitwise()
if self._match_set((TokenType.FROM, TokenType.COMMA)):
this = self._parse_term()
this = self._parse_bitwise()
else:
this = expression
expression = None
if self._match(TokenType.COLLATE):
collation = self._parse_term()
collation = self._parse_bitwise()
return self.expression(
exp.Trim,
@ -3741,6 +3749,15 @@ class Parser(metaclass=_Parser):
def _parse_named_window(self) -> t.Optional[exp.Expression]:
return self._parse_window(self._parse_id_var(), alias=True)
def _parse_respect_or_ignore_nulls(
self, this: t.Optional[exp.Expression]
) -> t.Optional[exp.Expression]:
if self._match(TokenType.IGNORE_NULLS):
return self.expression(exp.IgnoreNulls, this=this)
if self._match(TokenType.RESPECT_NULLS):
return self.expression(exp.RespectNulls, this=this)
return this
def _parse_window(
self, this: t.Optional[exp.Expression], alias: bool = False
) -> t.Optional[exp.Expression]:
@ -3768,10 +3785,7 @@ class Parser(metaclass=_Parser):
# (https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/img_text/first_value.html)
# and Snowflake chose to do the same for familiarity
# https://docs.snowflake.com/en/sql-reference/functions/first_value.html#usage-notes
if self._match(TokenType.IGNORE_NULLS):
this = self.expression(exp.IgnoreNulls, this=this)
elif self._match(TokenType.RESPECT_NULLS):
this = self.expression(exp.RespectNulls, this=this)
this = self._parse_respect_or_ignore_nulls(this)
# bigquery select from window x AS (partition by ...)
if alias:
@ -3975,9 +3989,7 @@ class Parser(metaclass=_Parser):
items = [parse_result] if parse_result is not None else []
while self._match(sep):
if parse_result and self._prev_comments:
parse_result.comments = self._prev_comments
self._add_comments(parse_result)
parse_result = parse_method()
if parse_result is not None:
items.append(parse_result)
@ -4345,13 +4357,14 @@ class Parser(metaclass=_Parser):
self._retreat(index)
return None
def _match(self, token_type, advance=True):
def _match(self, token_type, advance=True, expression=None):
if not self._curr:
return None
if self._curr.token_type == token_type:
if advance:
self._advance()
self._add_comments(expression)
return True
return None
@ -4379,16 +4392,12 @@ class Parser(metaclass=_Parser):
return None
def _match_l_paren(self, expression=None):
if not self._match(TokenType.L_PAREN):
if not self._match(TokenType.L_PAREN, expression=expression):
self.raise_error("Expecting (")
if expression and self._prev_comments:
expression.comments = self._prev_comments
def _match_r_paren(self, expression=None):
if not self._match(TokenType.R_PAREN):
if not self._match(TokenType.R_PAREN, expression=expression):
self.raise_error("Expecting )")
if expression and self._prev_comments:
expression.comments = self._prev_comments
def _match_texts(self, texts, advance=True):
if self._curr and self._curr.text.upper() in texts: