|
|
|
# code-gen for data decl languages
|
|
|
|
|
|
|
|
from engine.ast import ColRef, TableInfo, ast_node, include
|
|
|
|
from engine.utils import base62uuid
|
|
|
|
class create_table(ast_node):
|
|
|
|
name = 'create_table'
|
|
|
|
def produce(self, node):
|
|
|
|
ct = node[self.name]
|
|
|
|
tbl = self.context.add_table(ct['name'], ct['columns'])
|
|
|
|
# create tables in c
|
|
|
|
self.emit(f"auto {tbl.table_name} = new TableInfo(\"{tbl.table_name}\", {tbl.n_cols});")
|
|
|
|
self.emit("cxt->tables.insert({\"" + tbl.table_name + f"\", {tbl.table_name}"+"});")
|
|
|
|
self.context.tables_in_context[tbl] = tbl.table_name
|
|
|
|
tbl.cxt_name = tbl.table_name
|
|
|
|
for i, c in enumerate(ct['columns']):
|
|
|
|
# TODO: more self awareness
|
|
|
|
self.emit(f"{tbl.table_name}->colrefs[{i}].ty = types::AINT;")
|
|
|
|
|
|
|
|
class insert(ast_node):
|
|
|
|
name = 'insert'
|
|
|
|
def produce(self, node):
|
|
|
|
ct = node[self.name]
|
|
|
|
table:TableInfo = self.context.tables_byname[ct]
|
|
|
|
|
|
|
|
values = node['query']['select']
|
|
|
|
if len(values) != table.n_cols:
|
|
|
|
raise ValueError("Column Mismatch")
|
|
|
|
table.refer_all()
|
|
|
|
for i, s in enumerate(values):
|
|
|
|
if 'value' in s:
|
|
|
|
cname = table.columns[i].cxt_name
|
|
|
|
self.emit(f"{cname}.emplace_back({s['value']});")
|
|
|
|
else:
|
|
|
|
# subquery, dispatch to select astnode
|
|
|
|
pass
|
|
|
|
|
|
|
|
class c(ast_node):
|
|
|
|
name='c'
|
|
|
|
def produce(self, node):
|
|
|
|
self.emit(node[self.name])
|
|
|
|
|
|
|
|
class load(ast_node):
|
|
|
|
name="load"
|
|
|
|
def produce(self, node):
|
|
|
|
node = node[self.name]
|
|
|
|
table:TableInfo = self.context.tables_byname[node['table']]
|
|
|
|
n_keys = len(table.columns)
|
|
|
|
keys = ''
|
|
|
|
for _ in range(n_keys):
|
|
|
|
keys+='`tk'+base62uuid(6)
|
|
|
|
tablename = 'l'+base62uuid(7)
|
|
|
|
|
|
|
|
self.emit(f"{tablename}:({keys}!(+(`csv ? 1:\"{node['file']['literal']}\")))[{keys}]")
|
|
|
|
|
|
|
|
for i, c in enumerate(table.columns):
|
|
|
|
self.emit(f'{c.cname}:{tablename}[{i}]')
|
|
|
|
|
|
|
|
class outfile(ast_node):
|
|
|
|
name="_outfile"
|
|
|
|
def produce(self, node):
|
|
|
|
out_table:TableInfo = self.parent.out_table
|
|
|
|
filename = node['loc']['literal'] if 'loc' in node else node['literal']
|
|
|
|
self.emit_no_ln(f"\"{filename}\"1:`csv@(+(")
|
|
|
|
l_compound = False
|
|
|
|
l_cols = ''
|
|
|
|
l_keys = ''
|
|
|
|
ending = lambda x: x[:-1] if len(x) > 0 and x[-1]==';' else x
|
|
|
|
for i, c in enumerate(out_table.columns):
|
|
|
|
c:ColRef
|
|
|
|
l_keys += '`' + c.name
|
|
|
|
if c.compound:
|
|
|
|
if l_compound:
|
|
|
|
l_cols=f'flatBOTH\'+(({ending(l_cols)});{c.cname})'
|
|
|
|
else:
|
|
|
|
l_compound = True
|
|
|
|
if i >= 1:
|
|
|
|
l_cols = f'flatRO\'+(({ending(l_cols)});{c.cname})'
|
|
|
|
else:
|
|
|
|
l_cols = c.cname + ';'
|
|
|
|
elif l_compound:
|
|
|
|
l_cols = f'flatLO\'+(({ending(l_cols)});{c.cname})'
|
|
|
|
else:
|
|
|
|
l_cols += f"{c.cname};"
|
|
|
|
if not l_compound:
|
|
|
|
self.emit_no_ln(l_keys + '!(' + ending(l_cols) + ')')
|
|
|
|
else:
|
|
|
|
self.emit_no_ln(f'{l_keys}!+,/({ending(l_cols)})')
|
|
|
|
self.emit('))')
|
|
|
|
|
|
|
|
import sys
|
|
|
|
include(sys.modules[__name__])
|