This commit is contained in:
2022-04-16 03:35:20 +08:00
parent ae51d8c622
commit d1a6b1d83f
11 changed files with 142 additions and 74 deletions
+4 -1
View File
@@ -110,7 +110,10 @@ class TableInfo:
self.cxt.ccols_byname[cname] = col_object
self.columns_byname[c['name']] = col_object
self.columns.append(col_object)
def get_size(self):
size_tmp = 'tmp_sz_'+base62uuid(6)
self.cxt.emit(f'const auto& {size_tmp} = {self.columns[0].reference()}.size;')
return size_tmp
@property
def n_cols(self):
return len(self.columns)
+10 -3
View File
@@ -1,6 +1,7 @@
# code-gen for data decl languages
from engine.ast import ColRef, TableInfo, ast_node, Context, include
from engine.scan import scan
from engine.utils import base62uuid
class create_table(ast_node):
@@ -26,9 +27,15 @@ class create_table(ast_node):
for c in tbl.columns:
self.emit(f"{c.cxt_name}.init();")
else:
for i, c in enumerate(tbl.columns):
self.emit(f"{c.cxt_name}.init();")
self.emit(f"{c.cxt_name} = {self.cexpr[i]()};")
if len(self.context.scans) == 0:
for i, c in enumerate(tbl.columns):
self.emit(f"{c.cxt_name}.init();")
self.emit(f"{c.cxt_name} = {self.cexpr[i]()};")
else:
scanner:scan = self.context.scans[-1]
for i, c in enumerate(tbl.columns):
scanner.add(f"{c.cxt_name}.init();", "init")
scanner.add(f"{c.cxt_name} = {self.cexpr[i](scanner.it_ver)};")
class insert(ast_node):
name = 'insert'
+3 -3
View File
@@ -23,8 +23,8 @@ class expr(ast_node):
'mul':'*',
'div':'/',
'mod':'%',
'and':'&',
'or':'|',
'and':'&&',
'or':'||',
'xor' : '^',
'gt':'>',
'lt':'<',
@@ -92,7 +92,7 @@ class expr(ast_node):
x.append(expr(self, v)._expr)
self._expr = self.compound_ops[key][1](x)
elif key in self.unary_ops:
self._expr += f'({expr(self, val)._expr}{self.unary_ops[key]})'
self._expr += f'{self.unary_ops[key]}({expr(self, val)._expr})'
else:
print(f'Undefined expr: {key}{val}')
+1 -1
View File
@@ -40,7 +40,7 @@ class groupby(ast_node):
self.emit(f'unordered_map<{self.group_type}, vector_type<uint32_t>, '
f'transTypes<{self.group_type}, hasher>> {self.group};')
self.n_grps = len(node)
self.scanner = scan(self, None, expr.toCExpr(first_col)()+'.size')
self.scanner = scan(self, self.datasource, expr.toCExpr(first_col)()+'.size')
self.scanner.add(f'{self.group}[forward_as_tuple({g_contents(self.scanner.it_ver)})].emplace_back({self.scanner.it_ver});')
+8 -3
View File
@@ -14,6 +14,7 @@ class projection(ast_node):
self.disp = disp
self.outname = outname
self.group_node = None
self.where = None
ast_node.__init__(self, parent, node, context)
def init(self, _):
if self.outname is None:
@@ -58,8 +59,9 @@ class projection(ast_node):
self.prev_datasource = self.context.datasource
self.context.datasource = self.datasource
if 'where' in node:
self.datasource = filter(self, node['where'], True).output
self.context.datasource = self.datasource
self.where = filter(self, node['where'], True)
# self.datasource = filter(self, node['where'], True).output
#self.context.datasource = self.datasource
if 'groupby' in node:
self.group_node = groupby(self, node['groupby'])
@@ -107,7 +109,10 @@ class projection(ast_node):
else:
create_table(self, self.out_table, cexpr = cexprs)
self.datasource.group_node = None
if self.where is not None:
self.where.finalize()
has_orderby = 'orderby' in node
if has_orderby:
+30 -8
View File
@@ -11,10 +11,12 @@ class scan(ast_node):
super().__init__(parent, node, context)
def init(self, _):
self.datasource = self.context.datasource
self.initializers = ''
self.start = ''
self.body = ''
self.end = '}'
self.filter = None
self.mode = None
self.filters = []
scan_vars = set(s.it_var for s in self.context.scans)
self.it_ver = 'i' + base62uuid(2)
while(self.it_ver in scan_vars):
@@ -22,19 +24,30 @@ class scan(ast_node):
self.parent.context.scans.append(self)
def produce(self, node):
if type(node) is ColRef:
self.colref = node
if self.size is None:
self.mode = ["col", node.table]
self.start += f'for (auto& {self.it_ver} : {node.reference()}) {{\n'
else:
self.mode = ["idx", node.table]
self.start += f"for (uint32_t {self.it_ver} = 0; {self.it_ver} < {node.reference()}.size; ++{self.it_ver}){{\\n"
elif type(node) is str:
self.mode = ["idx", None]
self.start+= f'for(auto& {self.it_ver} : {node}) {{\n'
else:
self.mode = ["idx", node] # Node is the TableInfo
self.start += f"for (uint32_t {self.it_ver} = 0; {self.it_ver} < {self.size}; ++{self.it_ver}){{\n"
def add(self, stmt):
self.body+=stmt + '\n'
def add(self, stmt, position = "body"):
if position == "body":
self.body += stmt + '\n'
else:
self.initializers += stmt + '\n'
def finalize(self):
self.context.remove_scan(self, self.start + self.body + self.end)
for f in self.filters:
self.start += f
self.end += '}'
self.context.remove_scan(self, self.initializers + self.start + self.body + self.end)
class filter(ast_node):
name = 'filter'
@@ -45,7 +58,7 @@ class filter(ast_node):
self.datasource = self.context.datasource
self.view = View(self.context, self.datasource)
self.value = None
def spawn(self, node):
# TODO: deal with subqueries
self.modified_node = node
@@ -64,9 +77,18 @@ class filter(ast_node):
self.emit(f'{tmpVar}:{self.value}')
for o, c in zip(self.output.columns, self.datasource.columns):
self.emit(f'{o.cname}:$[{tmpVar};{c.cname};()]')
def consume(self, node):
def finalize(self):
self.scanner.finalize()
def consume(self, _):
# TODO: optimizations after converting expr to cnf
self.scanner = None
for s in self.context.scans:
if self.datasource == s.mode[1]:
self.scanner = s
break
if self.scanner is None:
self.scanner = scan(self, self.datasource, self.datasource.get_size())
self.expr = expr(self, self.modified_node)
print(node)
self.scanner.filters.append(f'if ({self.expr.cexpr(self.scanner.it_ver)}) {{\n')