Skip to content

Commit

Permalink
Merge pull request #286 from mindsdb/feature/if-not-exist-token
Browse files Browse the repository at this point in the history
Add IF_EXISTS and IF_NOT_EXISTS tokens to common creation and drop statement
  • Loading branch information
yuhuishi-convect authored Aug 21, 2023
2 parents af998dc + a694172 commit aed0799
Show file tree
Hide file tree
Showing 21 changed files with 202 additions and 49 deletions.
5 changes: 4 additions & 1 deletion mindsdb_sql/parser/ast/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ def __init__(self,
from_select=None,
columns: List[TableColumn] = None,
is_replace=False,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.is_replace = is_replace
self.from_select = from_select
self.columns = columns
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand All @@ -45,6 +47,7 @@ def to_tree(self, *args, level=0, **kwargs):
columns_str = f'{ind1}columns=\n' + '\n'.join(columns)

out_str = f'{ind}CreateTable(\n' \
f'{ind1}if_not_exists={self.if_not_exists},\n' \
f'{ind1}name={self.name}\n' \
f'{replace_str}' \
f'{from_select_str}' \
Expand Down Expand Up @@ -72,4 +75,4 @@ def get_string(self, *args, **kwargs):
from_select_str = self.from_select.to_string()

name_str = str(self.name)
return f'CREATE{replace_str} TABLE {name_str} {columns_str} {from_select_str}'
return f'CREATE{replace_str} TABLE {"IF NOT EXISTS " if self.if_not_exists else ""}{name_str} {columns_str} {from_select_str}'
5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/create_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ def __init__(self,
engine,
parameters,
is_replace=False,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.engine = engine
self.parameters = parameters
self.is_replace = is_replace
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand All @@ -28,6 +30,7 @@ def to_tree(self, *args, level=0, **kwargs):
replace_str = f'\n{ind1}is_replace=True'

out_str = f'{ind}CreateDatabase(' \
f'\n{ind1}if_not_exists={self.if_not_exists},' \
f'{name_str}' \
f'{engine_str}' \
f'{parameters_str}' \
Expand All @@ -43,5 +46,5 @@ def get_string(self, *args, **kwargs):
parameters_str = ''
if self.parameters:
parameters_str = f', PARAMETERS = {json.dumps(self.parameters)}'
out_str = f'CREATE{replace_str} DATABASE {self.name.to_string()} WITH ENGINE = {repr(self.engine)}{parameters_str}'
out_str = f'CREATE{replace_str} DATABASE {"IF NOT EXISTS " if self.if_not_exists else ""}{self.name.to_string()} WITH ENGINE = {repr(self.engine)}{parameters_str}'
return out_str
9 changes: 8 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/create_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def __init__(self,
start_str=None,
end_str=None,
repeat_str=None,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
Expand All @@ -20,6 +21,7 @@ def __init__(self,
self.end_str = end_str
self.repeat_str = repeat_str
self.date_format = '%Y-%m-%d %H:%M:%S'
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand All @@ -40,7 +42,12 @@ def to_tree(self, *args, level=0, **kwargs):
if self.repeat_str is not None:
repeat_str = f'\n{ind1}repeat_str={self.repeat_str},'

if_not_exists_str = ''
if self.if_not_exists:
if_not_exists_str = f'\n{ind1}if_not_exists=True,'

out_str = f'{ind}CreateJob(' \
f'{if_not_exists_str}' \
f'{name_str}' \
f'{query_str}' \
f'{start_str}' \
Expand All @@ -63,5 +70,5 @@ def get_string(self, *args, **kwargs):
if self.repeat_str is not None:
repeat_str = f" EVERY '{self.repeat_str}'"

out_str = f'CREATE JOB {self.name.to_string()} ({self.query_str}){start_str}{end_str}{repeat_str}'
out_str = f'CREATE JOB {"IF NOT EXISTS" if self.if_not_exists else ""} {self.name.to_string()} ({self.query_str}){start_str}{end_str}{repeat_str}'
return out_str
5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/create_ml_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ def __init__(self,
name,
handler,
params=None,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.handler = handler
self.params = params
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand All @@ -20,6 +22,7 @@ def to_tree(self, *args, level=0, **kwargs):
param_str = f'{repr(self.params)},'

out_str = f'{ind}CreateMLEngine(' \
f'\n{ind1}if_not_exists={self.if_not_exists}' \
f'\n{ind1}name={self.name.to_tree()}' \
f'\n{ind1}handler={self.handler}' \
f'\n{ind1}using={param_str}' \
Expand All @@ -33,7 +36,7 @@ def get_string(self, *args, **kwargs):

using_str = 'USING ' + ', '.join(using_ar)

out_str = f'CREATE ML_ENGINE {self.name.to_string()} FROM {self.handler} {using_str}'
out_str = f'CREATE ML_ENGINE {"IF NOT EXISTS" if self.if_not_exists else ""} {self.name.to_string()} FROM {self.handler} {using_str}'

return out_str.strip()

9 changes: 8 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/create_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def __init__(self,
horizon=None,
using=None,
is_replace=False,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
Expand All @@ -31,6 +32,7 @@ def __init__(self,
self.horizon = horizon
self.using = using
self.is_replace = is_replace
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand Down Expand Up @@ -69,7 +71,10 @@ def to_tree(self, *args, level=0, **kwargs):
horizon_str = f'\n{ind1}horizon={repr(self.horizon)},'
using_str = f'\n{ind1}using={repr(self.using)},'

if_not_exists_str = f'\n{ind1}if_not_exists={self.if_not_exists},' if self.if_not_exists else ''

out_str = f'{ind}{self.__class__.__name__}(' \
f'{if_not_exists_str}' \
f'{name_str}' \
f'{integration_name_str}' \
f'{query_str}' \
Expand Down Expand Up @@ -119,7 +124,9 @@ def get_string(self, *args, **kwargs):
if self.integration_name is not None:
integration_name_str = f'FROM {self.integration_name.to_string()} '

out_str = f'{self._command} {self.name.to_string()} {integration_name_str}{query_str}' \
if_not_exists_str = 'IF NOT EXISTS ' if self.if_not_exists else ''

out_str = f'{self._command} {if_not_exists_str}{self.name.to_string()} {integration_name_str}{query_str}' \
f'{datasource_name_str}' \
f'{targets_str} ' \
f'{order_by_str}' \
Expand Down
6 changes: 5 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/create_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def __init__(self,
name,
query_str,
from_table=None,
if_not_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
# todo remove it
Expand All @@ -15,6 +16,7 @@ def __init__(self,
self.name = name
self.query_str = query_str
self.from_table = from_table
self.if_not_exists = if_not_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
Expand All @@ -23,8 +25,10 @@ def to_tree(self, *args, level=0, **kwargs):
# name_str = f'\n{ind1}name={self.name.to_string()},'
from_table_str = f'\n{ind1}from_table=\n{self.from_table.to_tree(level=level+2)},' if self.from_table else ''
query_str = f'\n{ind1}query="{self.query_str}"'
if_not_exists_str = f'\n{ind1}if_not_exists=True,' if self.if_not_exists else ''

out_str = f'{ind}CreateView(' \
f'{if_not_exists_str}' \
f'{name_str}' \
f'{query_str}' \
f'{from_table_str}' \
Expand All @@ -34,7 +38,7 @@ def to_tree(self, *args, level=0, **kwargs):
def get_string(self, *args, **kwargs):
from_str = f'FROM {str(self.from_table)} ' if self.from_table else ''
# out_str = f'CREATE VIEW {self.name.to_string()} {from_str}AS ( {self.query_str} )'
out_str = f'CREATE VIEW {str(self.name)} {from_str}AS ( {self.query_str} )'
out_str = f'CREATE VIEW {"IF NOT EXISTS " if self.if_not_exists else ""}{str(self.name)} {from_str}AS ( {self.query_str} )'

return out_str

5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
class DropDataset(Drop):
def __init__(self,
name,
if_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.if_exists = if_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
ind1 = indent(level+1)
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropDataset(' \
f'{ind1}if_exists={self.if_exists},' \
f'{name_str}' \
f'\n{ind})'
return out_str

def get_string(self, *args, **kwargs):
out_str = f'DROP DATASET {str(self.name)}'
out_str = f'DROP DATASET {"IF EXISTS " if self.if_exists else ""}{str(self.name)}'
return out_str

5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
class DropDatasource(Drop):
def __init__(self,
name,
if_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.if_exists = if_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
ind1 = indent(level+1)
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropDatasource(' \
f'{ind1}if_exists={self.if_exists},' \
f'{name_str}' \
f'\n{ind})'
return out_str

def get_string(self, *args, **kwargs):
out_str = f'DROP DATASOURCE {str(self.name)}'
out_str = f'DROP DATASOURCE {"IF EXISTS " if self.if_exists else ""}{str(self.name)}'
return out_str

5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@
class DropIntegration(Drop):
def __init__(self,
name,
if_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.if_exists = if_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
ind1 = indent(level+1)
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropIntegration(' \
f'{ind1}if_exists={self.if_exists},' \
f'{name_str}' \
f'\n{ind})'
return out_str

def get_string(self, *args, **kwargs):
out_str = f'DROP INTEGRATION {str(self.name)}'
out_str = f'DROP INTEGRATION {"IF EXISTS " if self.if_exists else ""}{str(self.name)}'
return out_str
5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
class DropJob(Drop):
def __init__(self,
name,
if_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.if_exists = if_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
ind1 = indent(level+1)
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropJob(' \
f'{ind1}if_exists={self.if_exists},' \
f'{name_str}' \
f'\n{ind})'
return out_str

def get_string(self, *args, **kwargs):
out_str = f'DROP JOB {str(self.name)}'
out_str = f'DROP JOB {"IF EXISTS " if self.if_exists else ""}{str(self.name)}'
return out_str

5 changes: 4 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_ml_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
class DropMLEngine(Drop):
def __init__(self,
name,
if_exists=False,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.if_exists = if_exists

def to_tree(self, *args, level=0, **kwargs):
ind = indent(level)
ind1 = indent(level+1)
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropMLEngine(' \
f'{ind1}if_exists={self.if_exists},' \
f'{name_str}' \
f'\n{ind})'
return out_str

def get_string(self, *args, **kwargs):
out_str = f'DROP ML_ENGINE {str(self.name)}'
out_str = f'DROP ML_ENGINE {"IF EXISTS " if self.if_exists else ""}{str(self.name)}'
return out_str

2 changes: 1 addition & 1 deletion mindsdb_sql/parser/dialects/mindsdb/drop_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def to_tree(self, *args, level=0, **kwargs):
name_str = f'\n{ind1}name={self.name.to_tree()},'

out_str = f'{ind}DropPredictor(' \
f'{name_str}' \
f'if_exists={self.if_exists}' \
f'{name_str}' \
f'\n{ind})'
return out_str

Expand Down
3 changes: 2 additions & 1 deletion mindsdb_sql/parser/dialects/mindsdb/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MindsDBLexer(Lexer):
GLOBAL, PROCEDURE, FUNCTION, INDEX, WARNINGS,
ENGINES, CHARSET, COLLATION, PLUGINS, CHARACTER,
PERSIST, PERSIST_ONLY, DEFAULT,
IF_EXISTS, COLUMNS, FIELDS, COLLATE, SEARCH_PATH,
IF_EXISTS, IF_NOT_EXISTS, COLUMNS, FIELDS, COLLATE, SEARCH_PATH,
# SELECT Keywords
WITH, SELECT, DISTINCT, FROM, WHERE, AS,
LIMIT, OFFSET, ASC, DESC, NULLS_FIRST, NULLS_LAST,
Expand Down Expand Up @@ -158,6 +158,7 @@ class MindsDBLexer(Lexer):
PERSIST_ONLY = r'\bPERSIST_ONLY\b'
DEFAULT = r'\bDEFAULT\b'
IF_EXISTS = r'\bIF[\s]+EXISTS\b'
IF_NOT_EXISTS = r'\bIF[\s]+NOT[\s]+EXISTS\b'
COLUMNS = r'\bCOLUMNS\b'
FIELDS = r'\bFIELDS\b'
EXTENDED = r'\bEXTENDED\b'
Expand Down
Loading

0 comments on commit aed0799

Please sign in to comment.