-
Notifications
You must be signed in to change notification settings - Fork 970
Fix: parsing quoted built-in data types #5810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
from collections import defaultdict | ||
|
||
from sqlglot import exp | ||
from sqlglot.errors import ErrorLevel, ParseError, concat_messages, merge_errors | ||
from sqlglot.errors import ErrorLevel, ParseError, TokenError, concat_messages, merge_errors | ||
from sqlglot.helper import apply_index_offset, ensure_list, seq_get | ||
from sqlglot.time import format_time | ||
from sqlglot.tokens import Token, Tokenizer, TokenType | ||
|
@@ -5298,28 +5298,30 @@ def _parse_types( | |
this: t.Optional[exp.Expression] = None | ||
prefix = self._match_text_seq("SYSUDTLIB", ".") | ||
|
||
if not self._match_set(self.TYPE_TOKENS): | ||
if self._match_set(self.TYPE_TOKENS): | ||
type_token = self._prev.token_type | ||
else: | ||
type_token = None | ||
identifier = allow_identifiers and self._parse_id_var( | ||
any_token=False, tokens=(TokenType.VAR,) | ||
) | ||
if isinstance(identifier, exp.Identifier): | ||
tokens = self.dialect.tokenize(identifier.sql(dialect=self.dialect)) | ||
|
||
if len(tokens) != 1: | ||
self.raise_error("Unexpected identifier", self._prev) | ||
try: | ||
tokens = self.dialect.tokenize(identifier.name) | ||
except TokenError: | ||
tokens = None | ||
|
||
if tokens[0].token_type in self.TYPE_TOKENS: | ||
self._prev = tokens[0] | ||
elif self.dialect.SUPPORTS_USER_DEFINED_TYPES: | ||
this = self._parse_user_defined_type(identifier) | ||
if tokens and len(tokens) == 1 and tokens[0].token_type in self.TYPE_TOKENS: | ||
type_token = tokens[0].token_type | ||
else: | ||
self._retreat(self._index - 1) | ||
return None | ||
if self.dialect.SUPPORTS_USER_DEFINED_TYPES: | ||
this = self._parse_user_defined_type(identifier) | ||
else: | ||
self._retreat(self._index - 1) | ||
return None | ||
Comment on lines
+5317
to
+5321
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Nit] Could we revert the if/elif/else chain to reduce some of the indentation? |
||
else: | ||
return None | ||
|
||
type_token = self._prev.token_type | ||
|
||
if type_token == TokenType.PSEUDO_TYPE: | ||
return self.expression(exp.PseudoType, this=self._prev.text.upper()) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from sqlglot import ParseError, UnsupportedError, exp, transpile | ||
from sqlglot import ParseError, UnsupportedError, exp, transpile, parse_one | ||
from sqlglot.helper import logger as helper_logger | ||
from tests.dialects.test_dialect import Validator | ||
|
||
|
@@ -805,6 +805,12 @@ def test_postgres(self): | |
) | ||
self.assertIsInstance(self.parse_one("id::UUID"), exp.Cast) | ||
|
||
self.validate_identity('1::"int"', "CAST(1 AS INT)") | ||
assert parse_one('1::"int"', read="postgres").to.is_type(exp.DataType.Type.INT) | ||
Comment on lines
+808
to
+809
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need the generic We can grab the AST as |
||
|
||
self.validate_identity('1::"udt"', 'CAST(1 AS "udt")') | ||
assert parse_one('1::"udt"', read="postgres").to.this == exp.DataType.Type.USERDEFINED | ||
|
||
self.validate_identity( | ||
"COPY tbl (col1, col2) FROM 'file' WITH (FORMAT format, HEADER MATCH, FREEZE TRUE)" | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from sqlglot import exp, parse_one, transpile | ||
from sqlglot import exp, ParseError, parse_one, transpile | ||
from tests.dialects.test_dialect import Validator | ||
|
||
|
||
|
@@ -698,3 +698,10 @@ def test_analyze(self): | |
self.validate_identity("ANALYZE VERBOSE TBL") | ||
self.validate_identity("ANALYZE TBL PREDICATE COLUMNS") | ||
self.validate_identity("ANALYZE TBL ALL COLUMNS") | ||
|
||
def test_cast(self): | ||
self.validate_identity('1::"int"', "CAST(1 AS INTEGER)") | ||
assert parse_one('1::"int"', read="redshift").to.is_type(exp.DataType.Type.INT) | ||
Comment on lines
+703
to
+704
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
|
||
with self.assertRaises(ParseError): | ||
parse_one('1::"udt"', read="redshift") |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we
self.raise_error(...)
here? Otherwise, we'll now silently continue onThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is intentional. See previous threads & Slack.