parent
49a3fc0a78
commit
ee2dc88f06
@ -0,0 +1,46 @@
|
|||||||
|
from engine.ast import ast_node
|
||||||
|
|
||||||
|
|
||||||
|
class expr(ast_node):
|
||||||
|
name='expr'
|
||||||
|
builtin_func_maps = {
|
||||||
|
'max': 'max',
|
||||||
|
'min': 'min',
|
||||||
|
|
||||||
|
}
|
||||||
|
binary_ops = {'sub':'-', 'plus':'+'}
|
||||||
|
unary_ops = []
|
||||||
|
def __init__(self, parent, node):
|
||||||
|
from engine.projection import projection
|
||||||
|
if type(parent) in [projection, expr]:
|
||||||
|
self.datasource = parent.datasource
|
||||||
|
else:
|
||||||
|
self.datasource = None
|
||||||
|
self.udf_map = parent.context.udf_map
|
||||||
|
self.k9expr = ''
|
||||||
|
self.func_maps = {**self.udf_map, **self.builtin_func_maps}
|
||||||
|
ast_node.__init__(self, parent, node, None)
|
||||||
|
|
||||||
|
def produce(self, node):
|
||||||
|
if type(node) is dict:
|
||||||
|
for key, val in node.items():
|
||||||
|
if key in self.func_maps:
|
||||||
|
self.k9expr += f"{self.func_maps[key]}("
|
||||||
|
# if type(val) in [dict, str]:
|
||||||
|
self.k9expr += expr(self, val).k9expr
|
||||||
|
|
||||||
|
self.k9expr+=')'
|
||||||
|
elif key in self.binary_ops:
|
||||||
|
l = expr(self, val[0]).k9expr
|
||||||
|
r = expr(self, val[1]).k9expr
|
||||||
|
self.k9expr += f'({l}{self.binary_ops[key]}{r})'
|
||||||
|
|
||||||
|
print(f'binary{key}')
|
||||||
|
elif key in self.unary_ops:
|
||||||
|
print(f'unary{key}')
|
||||||
|
else:
|
||||||
|
print(key)
|
||||||
|
elif type(node) is str:
|
||||||
|
self.k9expr = self.datasource.parse_tablenames(node)
|
||||||
|
def __str__(self):
|
||||||
|
return self.k9expr
|
@ -0,0 +1,6 @@
|
|||||||
|
from engine.ast import ast_node
|
||||||
|
|
||||||
|
|
||||||
|
class join(ast_node):
|
||||||
|
name='join'
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
from engine.ast import TableInfo, ast_node, Context, include
|
||||||
|
from engine.join import join
|
||||||
|
from engine.expr import expr
|
||||||
|
from engine.utils import base62uuid
|
||||||
|
|
||||||
|
class projection(ast_node):
|
||||||
|
name='select'
|
||||||
|
def __init__(self, parent:ast_node, node, context:Context = None, outname = None, disp = True):
|
||||||
|
self.disp = disp
|
||||||
|
self.outname = outname
|
||||||
|
ast_node.__init__(self, parent, node, context)
|
||||||
|
def init(self, _):
|
||||||
|
if self.outname is None:
|
||||||
|
self.outname = self.context.gen_tmptable()
|
||||||
|
|
||||||
|
def produce(self, node):
|
||||||
|
p = node['select']
|
||||||
|
self.projections = p if type(projection) == list else [p]
|
||||||
|
print(node)
|
||||||
|
|
||||||
|
def spawn(self, node):
|
||||||
|
self.datasource = None
|
||||||
|
if 'from' in node:
|
||||||
|
from_clause = node['from']
|
||||||
|
if type(from_clause) is list:
|
||||||
|
# from joins
|
||||||
|
join(self, from_clause)
|
||||||
|
elif type(from_clause) is dict:
|
||||||
|
if 'value' in from_clause:
|
||||||
|
value = from_clause['value']
|
||||||
|
if type(value) is dict:
|
||||||
|
if 'select' in value:
|
||||||
|
# from subquery
|
||||||
|
projection(self, from_clause, disp = False)
|
||||||
|
else:
|
||||||
|
# TODO: from func over table
|
||||||
|
print(f"from func over table{node}")
|
||||||
|
elif type(value) is str:
|
||||||
|
self.datasource = self.context.tables_byname[value]
|
||||||
|
if 'assumptions' in from_clause:
|
||||||
|
ord = from_clause['assumptions']['ord'] == 'asc'
|
||||||
|
ord = '^' if ord else '|^'
|
||||||
|
# TODO: generate view of table by order
|
||||||
|
|
||||||
|
elif type(from_clause) is str:
|
||||||
|
self.datasource = self.context.tables_byname[from_clause]
|
||||||
|
|
||||||
|
if self.datasource is None:
|
||||||
|
raise ValueError('spawn error: from clause')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def consume(self, node):
|
||||||
|
disp_varname = 'disptmp' + base62uuid()
|
||||||
|
self.emit_no_ln(f'{disp_varname}:(')
|
||||||
|
for proj in self.projections:
|
||||||
|
if type(proj) is dict:
|
||||||
|
if 'value' in proj:
|
||||||
|
e = proj['value']
|
||||||
|
|
||||||
|
if type(e) is str:
|
||||||
|
self.emit_no_ln(f"{self.datasource.parse_tablenames(proj['value'])};")
|
||||||
|
elif type(e) is dict:
|
||||||
|
self.emit_no_ln(f"{expr(self, e).k9expr};")
|
||||||
|
|
||||||
|
self.emit(')')
|
||||||
|
if self.disp:
|
||||||
|
self.emit(disp_varname)
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
include(sys.modules[__name__])
|
@ -0,0 +1,12 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
def base62uuid(crop=8):
|
||||||
|
alp = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
id = uuid.uuid4().int
|
||||||
|
ret = ''
|
||||||
|
|
||||||
|
while id:
|
||||||
|
ret = alp[id % 62] + ret
|
||||||
|
id //= 62
|
||||||
|
|
||||||
|
return ret[:crop] if len(ret) else '0'
|
Loading…
Reference in new issue