This commit is contained in:
2022-04-24 02:56:19 +08:00
parent d1a6b1d83f
commit 2462bc6711
15 changed files with 259 additions and 147 deletions
+4
View File
@@ -15,6 +15,9 @@ class ColRef:
self.order_pending = None # order_pending
self.compound = compound # compound field (list as a field)
self.views = []
self.aux_columns = [] # columns for temperary calculations
# e.g. order by, group by, filter by expressions
self.__arr__ = (cname, _ty, cobj, cnt, table, name, id)
def reference(self):
@@ -90,6 +93,7 @@ class TableInfo:
type_tags += '>'
self.cxt.emit(f'auto& {base_name} = *(TableInfo{type_tags} *)(cxt->tables[{self.table_name}]);')
return self.cxt_name
def refer_all(self):
self.reference()
for c in self.columns:
+14 -1
View File
@@ -88,6 +88,15 @@ class outfile(ast_node):
def produce(self, node):
out_table:TableInfo = self.parent.out_table
filename = node['loc']['literal'] if 'loc' in node else node['literal']
sep = ',' if 'term' not in node else node['term']['literal']
self.context.headers.add('fstream')
cout_backup_buffer = 'stdout_' + base62uuid(4)
ofstream = 'ofstream_' + base62uuid(6)
self.emit(f'auto {cout_backup_buffer} = cout.rdbuf();')
self.emit(f'auto {ofstream} = ofstream("{filename}");')
self.emit(f'cout.rdbuf({ofstream}.rdbuf());')
self.emit_no_ln(f"\"{filename}\"1:`csv@(+(")
l_compound = False
l_cols = ''
@@ -114,6 +123,10 @@ class outfile(ast_node):
else:
self.emit_no_ln(f'{l_keys}!+,/({ending(l_cols)})')
self.emit('))')
self.emit(f'cout.rdbuf({cout_backup_buffer});')
self.emit(f'{ofstream}.close();')
import sys
include(sys.modules[__name__])
+1 -1
View File
@@ -40,7 +40,7 @@ class expr(ast_node):
'not' : '!'
}
coumpound_generating_ops = ['mod', 'mins', 'maxs', 'sums'] + \
coumpound_generating_ops = ['avgs', 'mins', 'maxs', 'sums'] + \
list( binary_ops.keys()) + list(compound_ops.keys()) + list(unary_ops.keys() )
def __init__(self, parent, node, materialize_cols = True, abs_col = False):
+9 -26
View File
@@ -16,43 +16,26 @@ class order_item:
return ('' if self.order else '-') + f'({self.name})'
def __str__(self):
return self.materialize()
return self.name
def __repr__(self):
return self.__str__()
class orders:
def __init__(self, node, datasource):
self.order_items = []
self.materialized = False
self.view = None
self.node = node
self.datasource = datasource
self.n_attrs = -1
def materialize(self):
if not self.materialized:
self.view = View(self.node.context, self.datasource, False)
keys = ';'.join([f'{o}' for o in self.order_items])
self.n_attrs = len(self.order_items)
self.node.emit(f"{self.view.name}: > +`j (({',' if self.n_attrs == 1 else ''}{keys}))")
self.materialized = True
def append(self, o):
self.order_items.append(o)
class orderby(ast_node):
name = '_orderby'
def __init__(self, parent: "ast_node", node, context: Context = None):
self.col_list = []
super().__init__(parent, node, context)
def init(self, _):
self.datasource = self.parent.datasource
self.order = orders(self, self.datasource)
self.order = []
self.view = ''
def produce(self, node):
if type(node) is not list:
node = [node]
for n in node:
order = not ('sort' in n and n['sort'] == 'desc')
col_id = self.datasource.columns_byname[n['value']].id
self.col_list.append(col_id if order else -col_id-1)
self.order.append(order_item(n['value'], self, order))
def consume(self, _):
self.datasource.order.append(self.order)
def finialize(self, references):
self.order = [ o for o in self.order if o.name in references ]
+17 -18
View File
@@ -14,6 +14,7 @@ class projection(ast_node):
self.disp = disp
self.outname = outname
self.group_node = None
self.assumption = None
self.where = None
ast_node.__init__(self, parent, node, context)
def init(self, _):
@@ -45,9 +46,8 @@ class projection(ast_node):
elif type(value) is str:
self.datasource = self.context.tables_byname[value]
if 'assumptions' in from_clause:
for assumption in enlist(from_clause['assumptions']):
orderby(self, assumption)
self.assumption = orderby(self, enlist(from_clause['assumptions']))
elif type(from_clause) is str:
self.datasource = self.context.tables_byname[from_clause]
@@ -83,7 +83,8 @@ class projection(ast_node):
self.out_table = TableInfo('out_'+base62uuid(4), [], self.context)
if 'outfile' in node:
flatten = True
new_names = []
for i, proj in enumerate(self.projections):
cname = ''
compound = False
@@ -92,12 +93,14 @@ class projection(ast_node):
if 'value' in proj:
e = proj['value']
sname = expr(self, e)._expr
fname = expr.toCExpr(sname)
absname = expr(self, e, abs_col=True)._expr
fname = expr.toCExpr(sname) # fastest access method at innermost context
absname = expr(self, e, abs_col=True)._expr # absolute name at function scope
compound = True
cexprs.append(fname)
cname = ''.join([a if a in base62alp else '' for a in fname()])
cname = e if type(e) is str else ''.join([a if a in base62alp else '' for a in expr.toCExpr(absname)()])
if 'name' in proj: # renaming column by AS keyword
cname = proj['name']
new_names.append(cname)
compound = compound and has_groupby and self.datasource.rec not in self.group_node.referenced
cols.append(ColRef(cname, expr.toCExpr(f'decays<decltype({absname})>')(0), self.out_table, 0, None, cname, i, compound=compound))
@@ -114,21 +117,17 @@ class projection(ast_node):
self.where.finalize()
has_orderby = 'orderby' in node
if has_orderby:
self.datasource = self.out_table
self.context.datasource = self.out_table # discard current ds
orderby_node = orderby(self, node['orderby'])
self.context.datasource.materialize_orderbys()
self.emit_no_ln(f"{f'{disp_varname}:+' if flatten else ''}(")
if self.disp or has_orderby:
self.emit(f'print(*{self.out_table.cxt_name});')
if has_orderby:
self.emit(f')[{orderby_node.view}]')
self.emit(f'auto {disp_varname} ={self.out_table.reference()}->order_by_view<{",".join([f"{c}" for c in orderby_node.col_list])}>();')
else:
self.context.emit_flush()
disp_varname = f'*{self.out_table.cxt_name}'
if self.disp:
self.emit(f'print({disp_varname});')
if flatten:
if len(self.projections) > 1 and not self.inv:
self.emit(f"{disp_varname}:+{disp_varname}")