Skip to content

Commit

Permalink
refactor including/excluding
Browse files Browse the repository at this point in the history
  • Loading branch information
tobymao committed Nov 25, 2022
1 parent fd2ea96 commit 7a94d39
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 38 deletions.
1 change: 1 addition & 0 deletions sqlglot/dialects/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class Generator(generator.Generator):
exp.CharacterSetProperty,
exp.CollateProperty,
exp.SchemaCommentProperty,
exp.LikeProperty,
}

WITH_PROPERTIES: t.Set[t.Type[exp.Property]] = set()
Expand Down
11 changes: 2 additions & 9 deletions sqlglot/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ class Create(Expression):
"this": True,
"kind": True,
"expression": False,
"like_properties": False,
"exists": False,
"properties": False,
"temporary": False,
Expand Down Expand Up @@ -1076,12 +1075,8 @@ class DistStyleProperty(Property):
arg_types = {"this": True}


class IncludingProperty(Property):
arg_types = {"this": True}


class ExcludingProperty(Property):
arg_types = {"this": True}
class LikeProperty(Property):
arg_types = {"this": True, "expressions": False}


class LocationProperty(Property):
Expand Down Expand Up @@ -1137,8 +1132,6 @@ class Properties(Expression):
"ENGINE": EngineProperty,
"EXECUTE AS": ExecuteAsProperty,
"FORMAT": FileFormatProperty,
"INCLUDING": IncludingProperty,
"EXCLUDING": ExcludingProperty,
"LANGUAGE": LanguageProperty,
"LOCATION": LocationProperty,
"PARTITIONED_BY": PartitionedByProperty,
Expand Down
6 changes: 6 additions & 0 deletions sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class Generator:
exp.DistStyleProperty,
exp.DistKeyProperty,
exp.SortKeyProperty,
exp.LikeProperty,
}

WITH_PROPERTIES = {
Expand Down Expand Up @@ -568,6 +569,11 @@ def property_sql(self, expression):

return f"{property_name}={self.sql(expression, 'this')}"

def likeproperty_sql(self, expression):
options = " ".join(f"{e.name} {self.sql(e, 'value')}" for e in expression.expressions)
options = f" {options}" if options else ""
return f"LIKE {self.sql(expression, 'this')}{options}"

def insert_sql(self, expression):
overwrite = expression.args.get("overwrite")

Expand Down
45 changes: 20 additions & 25 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ class Parser(metaclass=_Parser):
TokenType.GENERATED,
TokenType.IDENTITY,
TokenType.IF,
TokenType.INCLUDING,
TokenType.INDEX,
TokenType.ISNULL,
TokenType.IMMUTABLE,
Expand Down Expand Up @@ -471,8 +470,7 @@ class Parser(metaclass=_Parser):
TokenType.DISTKEY: lambda self: self._parse_distkey(),
TokenType.DISTSTYLE: lambda self: self._parse_property_assignment(exp.DistStyleProperty),
TokenType.SORTKEY: lambda self: self._parse_sortkey(),
TokenType.INCLUDING: lambda self: self._parse_property_assignment(exp.IncludingProperty),
TokenType.EXCLUDING: lambda self: self._parse_property_assignment(exp.ExcludingProperty),
TokenType.LIKE: lambda self: self._parse_create_like(),
TokenType.RETURNS: lambda self: self._parse_returns(),
TokenType.COLLATE: lambda self: self._parse_property_assignment(exp.CollateProperty),
TokenType.COMMENT: lambda self: self._parse_property_assignment(exp.SchemaCommentProperty),
Expand Down Expand Up @@ -503,6 +501,7 @@ class Parser(metaclass=_Parser):
),
TokenType.FOREIGN_KEY: lambda self: self._parse_foreign_key(),
TokenType.UNIQUE: lambda self: self._parse_unique(),
TokenType.LIKE: lambda self: self._parse_create_like(),
}

NO_PAREN_FUNCTION_PARSERS = {
Expand Down Expand Up @@ -815,7 +814,6 @@ def _parse_create(self):
this = None
expression = None
properties = None
like_properties = None

if create_token.token_type in (TokenType.FUNCTION, TokenType.PROCEDURE):
this = self._parse_user_defined_function()
Expand All @@ -833,27 +831,12 @@ def _parse_create(self):
properties = self._parse_properties()
if self._match(TokenType.ALIAS):
expression = self._parse_select(nested=True)
elif self._match(TokenType.LIKE):
# create table a like b
expression = self.expression(
exp.Like, this=this, expression=self._parse_table(schema=True)
)
elif self._match_pair(TokenType.L_PAREN, TokenType.LIKE):
# create table a (like b including constraints excluding statistics)
expression = self.expression(
exp.Like, this=this, expression=self._parse_table(schema=True)
)

like_properties = self._parse_properties()

self._match_r_paren()

return self.expression(
exp.Create,
this=this,
kind=create_token.text,
expression=expression,
like_properties=like_properties,
exists=exists,
properties=properties,
temporary=temporary,
Expand Down Expand Up @@ -899,6 +882,23 @@ def _parse_stored(self):
def _parse_distkey(self):
return self.expression(exp.DistKeyProperty, this=self._parse_wrapped(self._parse_var))

def _parse_create_like(self):
table = self._parse_table(schema=True)
options = []
while True:
if self._match_texts(("INCLUDING", "EXCLUDING")):
options.append(
self.expression(
exp.Property,
this=self._prev.text.upper(),
value=exp.Var(this=self._parse_id_var().this.upper()),
)
)
else:
break

return self.expression(exp.LikeProperty, this=table, expressions=options)

def _parse_sortkey(self, compound=False):
return self.expression(
exp.SortKeyProperty, this=self._parse_wrapped_csv(self._parse_var), compound=compound
Expand Down Expand Up @@ -2036,13 +2036,8 @@ def _parse_lambda(self):
return self._parse_alias(self._parse_limit(self._parse_order(this)))

def _parse_schema(self, this=None):

index = self._index
if (
self._match_pair(TokenType.L_PAREN, TokenType.LIKE)
or not self._match(TokenType.L_PAREN)
or self._match(TokenType.SELECT)
):
if not self._match(TokenType.L_PAREN) or self._match(TokenType.SELECT):
self._retreat(index)
return this

Expand Down
4 changes: 0 additions & 4 deletions sqlglot/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ class TokenType(AutoName):
ENGINE = auto()
ESCAPE = auto()
EXCEPT = auto()
EXCLUDING = auto()
EXECUTE = auto()
EXISTS = auto()
FALSE = auto()
Expand All @@ -185,7 +184,6 @@ class TokenType(AutoName):
ILIKE = auto()
IMMUTABLE = auto()
IN = auto()
INCLUDING = auto()
INDEX = auto()
INNER = auto()
INSERT = auto()
Expand Down Expand Up @@ -482,7 +480,6 @@ class Tokenizer(metaclass=_Tokenizer):
"ENGINE": TokenType.ENGINE,
"ESCAPE": TokenType.ESCAPE,
"EXCEPT": TokenType.EXCEPT,
"EXCLUDING": TokenType.EXCLUDING,
"EXECUTE": TokenType.EXECUTE,
"EXISTS": TokenType.EXISTS,
"FALSE": TokenType.FALSE,
Expand All @@ -504,7 +501,6 @@ class Tokenizer(metaclass=_Tokenizer):
"IMMUTABLE": TokenType.IMMUTABLE,
"IGNORE NULLS": TokenType.IGNORE_NULLS,
"IN": TokenType.IN,
"INCLUDING": TokenType.INCLUDING,
"INDEX": TokenType.INDEX,
"INNER": TokenType.INNER,
"INSERT": TokenType.INSERT,
Expand Down
2 changes: 2 additions & 0 deletions tests/dialects/test_mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def test_identity(self):
self.validate_identity("SELECT TRIM('bla' FROM ' XXX ')")
self.validate_identity("@@GLOBAL.max_connections")

self.validate_identity("CREATE TABLE A LIKE B")

# SET Commands
self.validate_identity("SET @var_name = expr")
self.validate_identity("SET @name = 43")
Expand Down
4 changes: 4 additions & 0 deletions tests/dialects/test_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def test_postgres(self):
"spark": "CREATE TABLE x (a UUID, b BINARY)",
},
)

self.validate_identity(
"CREATE TABLE A (LIKE B INCLUDING CONSTRAINT INCLUDING COMPRESSION EXCLUDING COMMENTS)"
)
self.validate_all(
"SELECT SUM(x) OVER (PARTITION BY a ORDER BY d ROWS 1 PRECEDING)",
write={
Expand Down

0 comments on commit 7a94d39

Please sign in to comment.