Skip to content

Commit f6c1d11

Browse files
Parsed ALTER VIEW query (#47)
* Parsed ALTER VIEW query
1 parent 5deeed8 commit f6c1d11

File tree

3 files changed

+145
-2
lines changed

3 files changed

+145
-2
lines changed

sqlglot/dialects/singlestore.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from sqlglot.dialects.mysql import _str_to_date
2222
from sqlglot.expressions import DataType
2323
from sqlglot.generator import ESCAPED_UNICODE_RE, unsupported_args
24-
from sqlglot.helper import csv, seq_get, is_int
24+
from sqlglot.helper import csv, seq_get, is_int, ensure_list
2525
from sqlglot.parser import build_coalesce
2626
from sqlglot.time import format_time
2727
from sqlglot.trie import new_trie
@@ -457,6 +457,56 @@ def _parse_match_against(self) -> exp.MatchAgainst:
457457

458458
return self.expression(exp.MatchAgainst, this=this, expressions=expressions)
459459

460+
def _parse_alter(self) -> t.Union[exp.Alter, exp.Command]:
461+
start = self._prev
462+
463+
if self._match_text_seq("DEFINER", advance=False):
464+
definer = self._parse_assignment()
465+
else:
466+
definer = None
467+
468+
if self._match_text_seq("SCHEMA_BINDING", "=", "ON"):
469+
schema_binding = True
470+
elif self._match_text_seq("SCHEMA_BINDING", "=", "OFF"):
471+
schema_binding = False
472+
else:
473+
schema_binding = None
474+
475+
alter_token = self._match_set(self.ALTERABLES) and self._prev
476+
if not alter_token:
477+
return self._parse_as_command(start)
478+
479+
exists = self._parse_exists()
480+
only = self._match_text_seq("ONLY")
481+
this = self._parse_table(schema=True)
482+
cluster = self._parse_on_property() if self._match(TokenType.ON) else None
483+
484+
if self._next:
485+
self._advance()
486+
487+
parser = self.ALTER_PARSERS.get(self._prev.text.upper()) if self._prev else None
488+
if parser:
489+
actions = ensure_list(parser(self))
490+
not_valid = self._match_text_seq("NOT", "VALID")
491+
options = self._parse_csv(self._parse_property)
492+
493+
if not self._curr and actions:
494+
return self.expression(
495+
exp.Alter,
496+
this=this,
497+
kind=alter_token.text.upper(),
498+
exists=exists,
499+
actions=actions,
500+
only=only,
501+
options=options,
502+
cluster=cluster,
503+
not_valid=not_valid,
504+
definer=definer,
505+
schema_binding=schema_binding,
506+
)
507+
508+
return self._parse_as_command(start)
509+
460510
def _parse_alter_table_set(self) -> exp.AlterSet:
461511
alter_set = self.expression(exp.AlterSet)
462512

@@ -3596,8 +3646,17 @@ def alter_sql(self, expression: exp.Alter) -> str:
35963646
actions_sql = self.format_args(*actions_list).lstrip("\n")
35973647

35983648
kind = self.sql(expression, "kind")
3649+
definer = self.sql(expression, "definer")
3650+
definer = f" {definer}" if definer else ""
3651+
schema_binding = expression.args.get("schema_binding")
3652+
if schema_binding is True:
3653+
schema_binding = " SCHEMA_BINDING = ON"
3654+
elif schema_binding is False:
3655+
schema_binding = " SCHEMA_BINDING = OFF"
3656+
else:
3657+
schema_binding = ""
35993658

3600-
return f"ALTER {kind} {self.sql(expression, 'this')} {actions_sql}"
3659+
return f"ALTER{definer}{schema_binding} {kind} {self.sql(expression, 'this')} {actions_sql}"
36013660

36023661
def add_column_sql(self, expression: exp.Expression) -> str:
36033662
sql = self.sql(expression)

sqlglot/expressions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4856,6 +4856,8 @@ class Alter(Expression):
48564856
"options": False,
48574857
"cluster": False,
48584858
"not_valid": False,
4859+
"definer": False,
4860+
"schema_binding": False,
48594861
}
48604862

48614863
@property

tests/dialects/test_singlestore.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ def setUp(self):
114114
execute_query(
115115
"""CREATE OR REPLACE PROCEDURE proc() RETURNS void AS BEGIN ECHO SELECT 1; END"""
116116
)
117+
execute_query("""DROP VIEW IF EXISTS users_view""")
118+
execute_query("""CREATE VIEW users_view AS SELECT * FROM users""")
117119

118120
def validate_generation(
119121
self,
@@ -5894,3 +5896,83 @@ def test_alter_database_parsing(self):
58945896
actions=[exp.AlterSet(expressions=[exp.Var(this="ASYNC REPLICATION")])],
58955897
),
58965898
)
5899+
5900+
def test_alter_view_parsing(self):
5901+
self.validate_parsing(
5902+
"ALTER VIEW users_view AS SELECT * FROM users",
5903+
exp.Alter(
5904+
this=exp.Table(this=exp.Identifier(this="users_view", quoted=False)),
5905+
kind="VIEW",
5906+
actions=[
5907+
exp.Select(
5908+
**{
5909+
"expressions": [exp.Star()],
5910+
"from": exp.From(
5911+
this=exp.Table(this=exp.Identifier(this="users", quoted=False))
5912+
),
5913+
}
5914+
)
5915+
],
5916+
),
5917+
)
5918+
self.validate_parsing(
5919+
"ALTER DEFINER = CURRENT_USER() VIEW users_view AS SELECT * FROM users",
5920+
exp.Alter(
5921+
this=exp.Table(this=exp.Identifier(this="users_view", quoted=False)),
5922+
kind="VIEW",
5923+
actions=[
5924+
exp.Select(
5925+
**{
5926+
"expressions": [exp.Star()],
5927+
"from": exp.From(
5928+
this=exp.Table(this=exp.Identifier(this="users", quoted=False))
5929+
),
5930+
}
5931+
)
5932+
],
5933+
definer=exp.EQ(
5934+
this=exp.Column(this=exp.Identifier(this="DEFINER", quoted=False)),
5935+
expression=exp.CurrentUser(),
5936+
),
5937+
),
5938+
)
5939+
self.validate_parsing(
5940+
"ALTER SCHEMA_BINDING = ON VIEW users_view AS SELECT * FROM users",
5941+
exp.Alter(
5942+
this=exp.Table(this=exp.Identifier(this="users_view", quoted=False)),
5943+
kind="VIEW",
5944+
actions=[
5945+
exp.Select(
5946+
**{
5947+
"expressions": [exp.Star()],
5948+
"from": exp.From(
5949+
this=exp.Table(this=exp.Identifier(this="users", quoted=False))
5950+
),
5951+
}
5952+
)
5953+
],
5954+
schema_binding=True,
5955+
),
5956+
)
5957+
self.validate_parsing(
5958+
"ALTER DEFINER = CURRENT_USER() SCHEMA_BINDING = ON VIEW users_view AS SELECT * FROM users",
5959+
exp.Alter(
5960+
this=exp.Table(this=exp.Identifier(this="users_view", quoted=False)),
5961+
kind="VIEW",
5962+
actions=[
5963+
exp.Select(
5964+
**{
5965+
"expressions": [exp.Star()],
5966+
"from": exp.From(
5967+
this=exp.Table(this=exp.Identifier(this="users", quoted=False))
5968+
),
5969+
}
5970+
)
5971+
],
5972+
definer=exp.EQ(
5973+
this=exp.Column(this=exp.Identifier(this="DEFINER", quoted=False)),
5974+
expression=exp.CurrentUser(),
5975+
),
5976+
schema_binding=True,
5977+
),
5978+
)

0 commit comments

Comments
 (0)