diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-01-23 08:42:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-01-23 08:42:55 +0000 |
commit | ade4a78e8fabcaa7270b6d4be2187457a3fa115f (patch) | |
tree | 018225e76010479b3a568bb6d9ef5df457802885 /sqlglot/parser.py | |
parent | Adding upstream version 10.5.2. (diff) | |
download | sqlglot-ade4a78e8fabcaa7270b6d4be2187457a3fa115f.tar.xz sqlglot-ade4a78e8fabcaa7270b6d4be2187457a3fa115f.zip |
Adding upstream version 10.5.6.upstream/10.5.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/parser.py')
-rw-r--r-- | sqlglot/parser.py | 80 |
1 files changed, 58 insertions, 22 deletions
diff --git a/sqlglot/parser.py b/sqlglot/parser.py index bd95db8..c97b19a 100644 --- a/sqlglot/parser.py +++ b/sqlglot/parser.py @@ -107,6 +107,8 @@ class Parser(metaclass=_Parser): TokenType.VARCHAR, TokenType.NVARCHAR, TokenType.TEXT, + TokenType.MEDIUMTEXT, + TokenType.LONGTEXT, TokenType.BINARY, TokenType.VARBINARY, TokenType.JSON, @@ -233,6 +235,7 @@ class Parser(metaclass=_Parser): TokenType.UNPIVOT, TokenType.PROPERTIES, TokenType.PROCEDURE, + TokenType.VIEW, TokenType.VOLATILE, TokenType.WINDOW, *SUBQUERY_PREDICATES, @@ -252,6 +255,7 @@ class Parser(metaclass=_Parser): TRIM_TYPES = {TokenType.LEADING, TokenType.TRAILING, TokenType.BOTH} FUNC_TOKENS = { + TokenType.COMMAND, TokenType.CURRENT_DATE, TokenType.CURRENT_DATETIME, TokenType.CURRENT_TIMESTAMP, @@ -552,7 +556,7 @@ class Parser(metaclass=_Parser): TokenType.IF: lambda self: self._parse_if(), } - FUNCTION_PARSERS = { + FUNCTION_PARSERS: t.Dict[str, t.Callable] = { "CONVERT": lambda self: self._parse_convert(self.STRICT_CAST), "TRY_CONVERT": lambda self: self._parse_convert(False), "EXTRACT": lambda self: self._parse_extract(), @@ -937,6 +941,7 @@ class Parser(metaclass=_Parser): statistics = None no_primary_index = None indexes = None + no_schema_binding = None if create_token.token_type in (TokenType.FUNCTION, TokenType.PROCEDURE): this = self._parse_user_defined_function() @@ -975,6 +980,9 @@ class Parser(metaclass=_Parser): break else: indexes.append(index) + elif create_token.token_type == TokenType.VIEW: + if self._match_text_seq("WITH", "NO", "SCHEMA", "BINDING"): + no_schema_binding = True return self.expression( exp.Create, @@ -993,6 +1001,7 @@ class Parser(metaclass=_Parser): statistics=statistics, no_primary_index=no_primary_index, indexes=indexes, + no_schema_binding=no_schema_binding, ) def _parse_property(self) -> t.Optional[exp.Expression]: @@ -1246,8 +1255,14 @@ class Parser(metaclass=_Parser): return self.expression(exp.Partition, this=self._parse_wrapped_csv(parse_values)) def _parse_value(self) -> exp.Expression: - expressions = self._parse_wrapped_csv(self._parse_conjunction) - return self.expression(exp.Tuple, expressions=expressions) + if self._match(TokenType.L_PAREN): + expressions = self._parse_csv(self._parse_conjunction) + self._match_r_paren() + return self.expression(exp.Tuple, expressions=expressions) + + # In presto we can have VALUES 1, 2 which results in 1 column & 2 rows. + # Source: https://prestodb.io/docs/current/sql/values.html + return self.expression(exp.Tuple, expressions=[self._parse_conjunction()]) def _parse_select( self, nested: bool = False, table: bool = False, parse_subquery_alias: bool = True @@ -1313,19 +1328,9 @@ class Parser(metaclass=_Parser): # Union ALL should be a property of the top select node, not the subquery return self._parse_subquery(this, parse_alias=parse_subquery_alias) elif self._match(TokenType.VALUES): - if self._curr.token_type == TokenType.L_PAREN: - # We don't consume the left paren because it's consumed in _parse_value - expressions = self._parse_csv(self._parse_value) - else: - # In presto we can have VALUES 1, 2 which results in 1 column & 2 rows. - # Source: https://prestodb.io/docs/current/sql/values.html - expressions = self._parse_csv( - lambda: self.expression(exp.Tuple, expressions=[self._parse_conjunction()]) - ) - this = self.expression( exp.Values, - expressions=expressions, + expressions=self._parse_csv(self._parse_value), alias=self._parse_table_alias(), ) else: @@ -1612,13 +1617,12 @@ class Parser(metaclass=_Parser): if alias: this.set("alias", alias) - if self._match(TokenType.WITH): + if self._match_pair(TokenType.WITH, TokenType.L_PAREN): this.set( "hints", - self._parse_wrapped_csv( - lambda: self._parse_function() or self._parse_var(any_token=True) - ), + self._parse_csv(lambda: self._parse_function() or self._parse_var(any_token=True)), ) + self._match_r_paren() if not self.alias_post_tablesample: table_sample = self._parse_table_sample() @@ -1643,8 +1647,17 @@ class Parser(metaclass=_Parser): alias.set("columns", [alias.this]) alias.set("this", None) + offset = None + if self._match_pair(TokenType.WITH, TokenType.OFFSET): + self._match(TokenType.ALIAS) + offset = self._parse_conjunction() + return self.expression( - exp.Unnest, expressions=expressions, ordinality=ordinality, alias=alias + exp.Unnest, + expressions=expressions, + ordinality=ordinality, + alias=alias, + offset=offset, ) def _parse_derived_table_values(self) -> t.Optional[exp.Expression]: @@ -1999,7 +2012,7 @@ class Parser(metaclass=_Parser): this = self._parse_column() if type_token: - if this: + if this and not isinstance(this, exp.Star): return self.expression(exp.Cast, this=this, to=type_token) if not type_token.args.get("expressions"): self._retreat(index) @@ -2050,6 +2063,7 @@ class Parser(metaclass=_Parser): self._retreat(index) return None + 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) @@ -2059,6 +2073,10 @@ class Parser(metaclass=_Parser): if not self._match(TokenType.GT): self.raise_error("Expecting >") + if self._match_set((TokenType.L_BRACKET, TokenType.L_PAREN)): + values = self._parse_csv(self._parse_conjunction) + self._match_set((TokenType.R_BRACKET, TokenType.R_PAREN)) + value: t.Optional[exp.Expression] = None if type_token in self.TIMESTAMPS: if self._match(TokenType.WITH_TIME_ZONE) or type_token == TokenType.TIMESTAMPTZ: @@ -2097,9 +2115,13 @@ class Parser(metaclass=_Parser): this=exp.DataType.Type[type_token.value.upper()], expressions=expressions, nested=nested, + values=values, ) def _parse_struct_kwargs(self) -> t.Optional[exp.Expression]: + if self._curr and self._curr.token_type in self.TYPE_TOKENS: + return self._parse_types() + this = self._parse_id_var() self._match(TokenType.COLON) data_type = self._parse_types() @@ -2412,6 +2434,14 @@ class Parser(metaclass=_Parser): self._match(TokenType.ALWAYS) kind = self.expression(exp.GeneratedAsIdentityColumnConstraint, this=True) self._match_pair(TokenType.ALIAS, TokenType.IDENTITY) + + if self._match(TokenType.L_PAREN): + if self._match_text_seq("START", "WITH"): + kind.set("start", self._parse_bitwise()) + if self._match_text_seq("INCREMENT", "BY"): + kind.set("increment", self._parse_bitwise()) + + self._match_r_paren() else: return this @@ -2619,8 +2649,12 @@ class Parser(metaclass=_Parser): if self._match(TokenType.IN): args.append(self._parse_bitwise()) - # Note: we're parsing in order needle, haystack, position - this = exp.StrPosition.from_arg_list(args) + this = exp.StrPosition( + this=seq_get(args, 1), + substr=seq_get(args, 0), + position=seq_get(args, 2), + ) + self.validate_expression(this, args) return this @@ -2999,6 +3033,8 @@ class Parser(metaclass=_Parser): actions = self._parse_csv(self._parse_add_column) elif self._match_text_seq("DROP", advance=False): actions = self._parse_csv(self._parse_drop_column) + elif self._match_text_seq("RENAME", "TO"): + actions = self.expression(exp.RenameTable, this=self._parse_table(schema=True)) elif self._match_text_seq("ALTER"): self._match(TokenType.COLUMN) column = self._parse_field(any_token=True) |