summaryrefslogtreecommitdiffstats
path: root/sqlglot/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'sqlglot/parser.py')
-rw-r--r--sqlglot/parser.py58
1 files changed, 38 insertions, 20 deletions
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index f714c8d..35a1744 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -248,7 +248,6 @@ class Parser(metaclass=_Parser):
TokenType.FILTER,
TokenType.FORMAT,
TokenType.FULL,
- TokenType.IF,
TokenType.IS,
TokenType.ISNULL,
TokenType.INTERVAL,
@@ -708,14 +707,10 @@ class Parser(metaclass=_Parser):
SCHEMA_UNNAMED_CONSTRAINTS = {"CHECK", "FOREIGN KEY", "LIKE", "PRIMARY KEY", "UNIQUE"}
NO_PAREN_FUNCTION_PARSERS = {
- TokenType.ANY: lambda self: self.expression(exp.Any, this=self._parse_bitwise()),
- TokenType.CASE: lambda self: self._parse_case(),
- TokenType.IF: lambda self: self._parse_if(),
- TokenType.NEXT_VALUE_FOR: lambda self: self.expression(
- exp.NextValueFor,
- this=self._parse_column(),
- order=self._match(TokenType.OVER) and self._parse_wrapped(self._parse_order),
- ),
+ "ANY": lambda self: self.expression(exp.Any, this=self._parse_bitwise()),
+ "CASE": lambda self: self._parse_case(),
+ "IF": lambda self: self._parse_if(),
+ "NEXT": lambda self: self._parse_next_value_for(),
}
FUNCTIONS_WITH_ALIASED_ARGS = {"STRUCT"}
@@ -1162,7 +1157,7 @@ class Parser(metaclass=_Parser):
def _parse_exists(self, not_: bool = False) -> t.Optional[bool]:
return (
- self._match(TokenType.IF)
+ self._match_text_seq("IF")
and (not not_ or self._match(TokenType.NOT))
and self._match(TokenType.EXISTS)
)
@@ -1935,6 +1930,9 @@ class Parser(metaclass=_Parser):
# https://prestodb.io/docs/current/sql/values.html
return self.expression(exp.Tuple, expressions=[self._parse_conjunction()])
+ def _parse_projections(self) -> t.List[t.Optional[exp.Expression]]:
+ return self._parse_expressions()
+
def _parse_select(
self, nested: bool = False, table: bool = False, parse_subquery_alias: bool = True
) -> t.Optional[exp.Expression]:
@@ -1974,14 +1972,14 @@ class Parser(metaclass=_Parser):
self.raise_error("Cannot specify both ALL and DISTINCT after SELECT")
limit = self._parse_limit(top=True)
- expressions = self._parse_expressions()
+ projections = self._parse_projections()
this = self.expression(
exp.Select,
kind=kind,
hint=hint,
distinct=distinct,
- expressions=expressions,
+ expressions=projections,
limit=limit,
)
this.comments = comments
@@ -3021,8 +3019,12 @@ class Parser(metaclass=_Parser):
while True:
if self._match_set(self.BITWISE):
this = self.expression(
- self.BITWISE[self._prev.token_type], this=this, expression=self._parse_term()
+ self.BITWISE[self._prev.token_type],
+ this=this,
+ expression=self._parse_term(),
)
+ elif self._match(TokenType.DQMARK):
+ this = self.expression(exp.Coalesce, this=this, expressions=self._parse_term())
elif self._match_pair(TokenType.LT, TokenType.LT):
this = self.expression(
exp.BitwiseLeftShift, this=this, expression=self._parse_term()
@@ -3322,9 +3324,13 @@ class Parser(metaclass=_Parser):
return None
token_type = self._curr.token_type
+ this = self._curr.text
+ upper = this.upper()
- if optional_parens and self._match_set(self.NO_PAREN_FUNCTION_PARSERS):
- return self.NO_PAREN_FUNCTION_PARSERS[token_type](self)
+ parser = self.NO_PAREN_FUNCTION_PARSERS.get(upper)
+ if optional_parens and parser:
+ self._advance()
+ return parser(self)
if not self._next or self._next.token_type != TokenType.L_PAREN:
if optional_parens and token_type in self.NO_PAREN_FUNCTIONS:
@@ -3336,12 +3342,9 @@ class Parser(metaclass=_Parser):
if token_type not in self.FUNC_TOKENS:
return None
- this = self._curr.text
- upper = this.upper()
self._advance(2)
parser = self.FUNCTION_PARSERS.get(upper)
-
if parser and not anonymous:
this = parser(self)
else:
@@ -3368,7 +3371,7 @@ class Parser(metaclass=_Parser):
else:
this = self.expression(exp.Anonymous, this=this, expressions=args)
- self._match(TokenType.R_PAREN, expression=this)
+ self._match_r_paren(this)
return self._parse_window(this)
def _parse_function_parameter(self) -> t.Optional[exp.Expression]:
@@ -3703,7 +3706,11 @@ class Parser(metaclass=_Parser):
self.expression(exp.Slice, expression=self._parse_conjunction())
]
else:
- expressions = self._parse_csv(lambda: self._parse_slice(self._parse_conjunction()))
+ expressions = self._parse_csv(
+ lambda: self._parse_slice(
+ self._parse_alias(self._parse_conjunction(), explicit=True)
+ )
+ )
# https://duckdb.org/docs/sql/data_types/struct.html#creating-structs
if bracket_kind == TokenType.L_BRACE:
@@ -3770,6 +3777,17 @@ class Parser(metaclass=_Parser):
return self._parse_window(this)
+ def _parse_next_value_for(self) -> t.Optional[exp.Expression]:
+ if not self._match_text_seq("VALUE", "FOR"):
+ self._retreat(self._index - 1)
+ return None
+
+ return self.expression(
+ exp.NextValueFor,
+ this=self._parse_column(),
+ order=self._match(TokenType.OVER) and self._parse_wrapped(self._parse_order),
+ )
+
def _parse_extract(self) -> exp.Extract:
this = self._parse_function() or self._parse_var() or self._parse_type()