Bug fixes on assumptions.

Other improvements.
dev
bill sun 3 years ago committed by Bill Sun
parent ae51d8c622
commit f3762595a8

@ -1,8 +0,0 @@
all:
g++ mmw.cpp --std=c++1z -shared -fPIC -Ofast -march=native -g0 -s -o mmw.so
avx512:
g++ mmw.cpp --std=c++1z -shared -fPIC -Ofast -mavx512f -g0 -s -o mmw.so
debug:
g++ mmw.cpp --std=c++1z -shared -fPIC -O0 -march=native -g3 -o mmw.so
clean:
rm mmw.so -rf

@ -1,20 +1,44 @@
# AQuery++ # AQuery++ DB
## Introduction
AQuery++ Compiler that compiles AQuery into C++11. AQuery++ Database is a cross-platform, In-Memory Column-Store Database that incorporates compiled query execution.
Frontend built on top of [mo-sql-parsing](https://github.com/klahnakoski/mo-sql-parsing). Compiler frontend built on top of [mo-sql-parsing](https://github.com/klahnakoski/mo-sql-parsing).
## Roadmap ## Roadmap
- [x] SQL Parser -> AQuery Parser (Front End) - [x] SQL Parser -> AQuery Parser (Front End)
- [ ] AQuery-C++ Compiler (Back End) - [ ] AQuery-C++ Compiler (Back End)
- [x] Schema and Data Model - [x] Schema and Data Model
- [x] Data acquisition/output from/to csv file - [x] Data acquisition/output from/to csv file
- [ ] Single table queries - [x] Single table queries
- [x] Projections and Single Table Aggregations - [x] Projections and Single Table Aggregations
- [x] Group by Aggregations - [x] Group by Aggregations
- [x] Filters - [x] Filters
- [ ] Order by - [x] Order by
- [ ] Assumption - [x] Assumption
- [x] Flatten
- [ ] Multi-table - [ ] Multi-table
- [ ] Join - [ ] Join
- [ ] Subqueries - [ ] Subqueries
- [ ] -> Optimizing Compiler - [ ] -> Optimizing Compiler
## TODO:
- [ ] C++ Meta-Programming: Elimilate template recursions as much as possible.
- [ ] IPC: Better ways to communicate between Interpreter (Python) and Executer (C++).
- [ ] Sockets? stdin/stdout capture?
## Requirements
Recent version of Linux, Windows or MacOS, with recent C++ compiler that has C++17 (1z) support (e.g. gcc 6.0, MSVC 2017, clang 6.0), and python 3.6 or above.
## Usage
`python3 prompt.py` will launch the interactive command prompt. The server binary will be autometically rebuilt and started.
#### Commands:
- `<sql statement>`: parse sql statement
- `f <filename>`: parse all sql statements in file
- `print`: printout parsed sql statements
- `exec`: execute last parsed statement(s)
- `r`: run the last generated code snippet
- `save <OPTIONAL: filename>`: save current code snippet. will use random filename if not specified.
- `exit`: quit the prompt
#### Example:
`f moving_avg.a` <br>
`exec`

Binary file not shown.

@ -15,6 +15,9 @@ class ColRef:
self.order_pending = None # order_pending self.order_pending = None # order_pending
self.compound = compound # compound field (list as a field) self.compound = compound # compound field (list as a field)
self.views = [] 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) self.__arr__ = (cname, _ty, cobj, cnt, table, name, id)
def reference(self): def reference(self):
@ -89,7 +92,8 @@ class TableInfo:
type_tags = type_tags[:-1] type_tags = type_tags[:-1]
type_tags += '>' type_tags += '>'
self.cxt.emit(f'auto& {base_name} = *(TableInfo{type_tags} *)(cxt->tables[{self.table_name}]);') self.cxt.emit(f'auto& {base_name} = *(TableInfo{type_tags} *)(cxt->tables["{self.table_name}"]);')
return self.cxt_name
def refer_all(self): def refer_all(self):
self.reference() self.reference()
for c in self.columns: for c in self.columns:
@ -110,7 +114,10 @@ class TableInfo:
self.cxt.ccols_byname[cname] = col_object self.cxt.ccols_byname[cname] = col_object
self.columns_byname[c['name']] = col_object self.columns_byname[c['name']] = col_object
self.columns.append(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 @property
def n_cols(self): def n_cols(self):
return len(self.columns) return len(self.columns)
@ -136,8 +143,8 @@ class TableInfo:
def get_col_d(self, col_name): def get_col_d(self, col_name):
col = self.columns_byname[col_name] col = self.columns_byname[col_name]
if type(self.rec) is list: if type(self.rec) is set:
self.rec.append(col) self.rec.add(col)
return col return col
def get_ccolname_d(self, col_name): def get_ccolname_d(self, col_name):
@ -160,12 +167,12 @@ class TableInfo:
self.alias.add(alias) self.alias.add(alias)
def parse_tablenames(self, colExpr, materialize = True, raw = False): def parse_tablenames(self, colExpr, materialize = True, raw = False):
self.get_col = self.get_col if materialize else self.get_col_d # get_col = self.get_col if materialize else self.get_col_d
parsedColExpr = colExpr.split('.') parsedColExpr = colExpr.split('.')
ret = None ret = None
if len(parsedColExpr) <= 1: if len(parsedColExpr) <= 1:
ret = self.get_col(colExpr) ret = self.get_col_d(colExpr)
else: else:
datasource = self.cxt.tables_byname[parsedColExpr[0]] datasource = self.cxt.tables_byname[parsedColExpr[0]]
if datasource is None: if datasource is None:
@ -177,6 +184,7 @@ class TableInfo:
if self.groupinfo is not None and ret and ret in self.groupinfo.raw_groups: if self.groupinfo is not None and ret and ret in self.groupinfo.raw_groups:
string = f'get<{self.groupinfo.raw_groups.index(ret)}>({{y}})' string = f'get<{self.groupinfo.raw_groups.index(ret)}>({{y}})'
return string, ret if raw else string return string, ret if raw else string
class View: class View:
def __init__(self, context, table = None, tmp = True): def __init__(self, context, table = None, tmp = True):
self.table: TableInfo = table self.table: TableInfo = table
@ -193,6 +201,7 @@ class Context:
extern "C" int __DLLEXPORT__ dllmain(Context* cxt) { extern "C" int __DLLEXPORT__ dllmain(Context* cxt) {
using namespace std; using namespace std;
using namespace types; using namespace types;
''' '''
def __init__(self): def __init__(self):
self.tables:List[TableInfo] = [] self.tables:List[TableInfo] = []

@ -1,14 +1,17 @@
# code-gen for data decl languages # code-gen for data decl languages
from engine.orderby import orderby
from engine.ast import ColRef, TableInfo, ast_node, Context, include from engine.ast import ColRef, TableInfo, ast_node, Context, include
from engine.scan import scan
from engine.utils import base62uuid from engine.utils import base62uuid
class create_table(ast_node): class create_table(ast_node):
name = 'create_table' name = 'create_table'
def __init__(self, parent: "ast_node", node, context: Context = None, cexpr = None): def __init__(self, parent: "ast_node", node, context: Context = None, cexprs = None, lineage = False):
self.cexpr = cexpr self.cexprs = cexprs
self.lineage = lineage
super().__init__(parent, node, context) super().__init__(parent, node, context)
def produce(self, node): def produce(self, node):
if type(node) is not TableInfo: if type(node) is not TableInfo:
ct = node[self.name] ct = node[self.name]
tbl = self.context.add_table(ct['name'], ct['columns']) tbl = self.context.add_table(ct['name'], ct['columns'])
@ -22,14 +25,38 @@ class create_table(ast_node):
self.context.tables_in_context[tbl] = tbl.table_name self.context.tables_in_context[tbl] = tbl.table_name
tbl.cxt_name = tbl.table_name tbl.cxt_name = tbl.table_name
tbl.refer_all() tbl.refer_all()
if self.cexpr is None: # create an empty new table
if self.cexprs is None:
for c in tbl.columns: for c in tbl.columns:
self.emit(f"{c.cxt_name}.init();") self.emit(f"{c.cxt_name}.init();")
# create an output table
else: else:
for i, c in enumerate(tbl.columns): # 1 to 1 lineage.
self.emit(f"{c.cxt_name}.init();") if len(self.context.scans) == 0:
self.emit(f"{c.cxt_name} = {self.cexpr[i]()};") if self.lineage:
order = 'order_' + base62uuid(6)
self.emit(f'auto {order} = {self.parent.datasource.cxt_name}->order_by<{orderby(self.parent, self.parent.assumptions).result()}>();')
self.lineage = '*' + order
else:
self.lineage = None
for i, c in enumerate(tbl.columns):
self.emit(f"{c.cxt_name}.init();")
self.emit(f"{c.cxt_name} = {self.cexprs[i](self.lineage)};")
self.lineage = None
self.parent.assumptions = None
else:
scanner:scan = self.context.scans[-1]
if self.lineage:
lineage_var = 'lineage_' + base62uuid(6)
counter_var = 'counter_' + base62uuid(6)
scanner.add(f'auto {lineage_var} = {self.datasource.cxt_name}->bind({tbl.cxt_name});', "init")
scanner.add(f'auto {counter_var} = 0;', "init")
scanner.add(f"{lineage_var}.emplace_back({counter_var}++);", "front")
self.lineage = f"{lineage_var}.rid"
for i, c in enumerate(tbl.columns):
scanner.add(f"{c.cxt_name}.init();", "init")
scanner.add(f"{c.cxt_name} = {self.cexprs[i](scanner.it_ver)};")
class insert(ast_node): class insert(ast_node):
name = 'insert' name = 'insert'
def produce(self, node): def produce(self, node):
@ -81,32 +108,21 @@ class outfile(ast_node):
def produce(self, node): def produce(self, node):
out_table:TableInfo = self.parent.out_table out_table:TableInfo = self.parent.out_table
filename = node['loc']['literal'] if 'loc' in node else node['literal'] filename = node['loc']['literal'] if 'loc' in node else node['literal']
self.emit_no_ln(f"\"{filename}\"1:`csv@(+(") sep = ',' if 'term' not in node else node['term']['literal']
l_compound = False file_pointer = 'fp_' + base62uuid(6)
l_cols = '' self.emit(f'FILE* {file_pointer} = fopen("{filename}", "w");')
l_keys = '' self.emit(f'{out_table.cxt_name}->printall("{sep}", "\\n", nullptr, {file_pointer});')
ending = lambda x: x[:-1] if len(x) > 0 and x[-1]==';' else x self.emit(f'fclose({file_pointer});')
for i, c in enumerate(out_table.columns): # self.context.headers.add('fstream')
c:ColRef # cout_backup_buffer = 'stdout_' + base62uuid(4)
l_keys += '`' + c.name # ofstream = 'ofstream_' + base62uuid(6)
if c.compound: # self.emit(f'auto {cout_backup_buffer} = cout.rdbuf();')
if l_compound: # self.emit(f'auto {ofstream} = ofstream("{filename}");')
l_cols=f'flatBOTH\'+(({ending(l_cols)});{c.cname})' # self.emit(f'cout.rdbuf({ofstream}.rdbuf());')
else: # TODO: ADD STMTS.
l_compound = True # self.emit(f'cout.rdbuf({cout_backup_buffer});')
if i >= 1: # self.emit(f'{ofstream}.close();')
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 import sys
include(sys.modules[__name__]) include(sys.modules[__name__])

@ -11,10 +11,10 @@ class expr(ast_node):
'avg': 'avg', 'avg': 'avg',
'sum': 'sum', 'sum': 'sum',
'count' : 'count', 'count' : 'count',
'mins': ['mins', 'minsw'], 'mins': ['mins', 'minw'],
'maxs': ['maxs', 'maxsw'], 'maxs': ['maxs', 'maxw'],
'avgs': ['avgs', 'avgsw'], 'avgs': ['avgs', 'avgw'],
'sums': ['sums', 'sumsw'], 'sums': ['sums', 'sumw'],
} }
binary_ops = { binary_ops = {
@ -23,8 +23,8 @@ class expr(ast_node):
'mul':'*', 'mul':'*',
'div':'/', 'div':'/',
'mod':'%', 'mod':'%',
'and':'&', 'and':'&&',
'or':'|', 'or':'||',
'xor' : '^', 'xor' : '^',
'gt':'>', 'gt':'>',
'lt':'<', 'lt':'<',
@ -40,13 +40,16 @@ class expr(ast_node):
'not' : '!' '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() ) list( binary_ops.keys()) + list(compound_ops.keys()) + list(unary_ops.keys() )
def __init__(self, parent, node, materialize_cols = True, abs_col = False): def __init__(self, parent, node, materialize_cols = True, abs_col = False):
self.materialize_cols = materialize_cols self.materialize_cols = materialize_cols
self.raw_col = None self.raw_col = None
self.__abs = abs_col self.__abs = abs_col
self.inside_agg = False
if(type(parent) is expr):
self.inside_agg = parent.inside_agg
ast_node.__init__(self, parent, node, None) ast_node.__init__(self, parent, node, None)
def init(self, _): def init(self, _):
@ -67,7 +70,8 @@ class expr(ast_node):
if type(node) is dict: if type(node) is dict:
for key, val in node.items(): for key, val in node.items():
if key in self.func_maps: if key in self.func_maps:
# if type(val) in [dict, str]: # TODO: distinguish between UDF agg functions and other UDF functions.
self.inside_agg = True
self.context.headers.add('"./server/aggregations.h"') self.context.headers.add('"./server/aggregations.h"')
if type(val) is list and len(val) > 1: if type(val) is list and len(val) > 1:
cfunc = self.func_maps[key] cfunc = self.func_maps[key]
@ -81,6 +85,7 @@ class expr(ast_node):
self._expr += f"{funcname}(" self._expr += f"{funcname}("
self._expr += expr(self, val)._expr self._expr += expr(self, val)._expr
self._expr += ')' self._expr += ')'
self.inside_agg = False
elif key in self.binary_ops: elif key in self.binary_ops:
l = expr(self, val[0])._expr l = expr(self, val[0])._expr
r = expr(self, val[1])._expr r = expr(self, val[1])._expr
@ -92,7 +97,7 @@ class expr(ast_node):
x.append(expr(self, v)._expr) x.append(expr(self, v)._expr)
self._expr = self.compound_ops[key][1](x) self._expr = self.compound_ops[key][1](x)
elif key in self.unary_ops: 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: else:
print(f'Undefined expr: {key}{val}') print(f'Undefined expr: {key}{val}')
@ -112,7 +117,7 @@ class expr(ast_node):
self._expr, self.raw_col = self.datasource.parse_tablenames(node, self.materialize_cols, True) self._expr, self.raw_col = self.datasource.parse_tablenames(node, self.materialize_cols, True)
self.raw_col = self.raw_col if type(self.raw_col) is ColRef else None self.raw_col = self.raw_col if type(self.raw_col) is ColRef else None
if self.__abs and self.raw_col: if self.__abs and self.raw_col:
self._expr = self.raw_col.reference() + index_expr self._expr = self.raw_col.reference() + ("" if self.inside_agg else index_expr)
elif type(node) is bool: elif type(node) is bool:
self._expr = '1' if node else '0' self._expr = '1' if node else '0'
else: else:

@ -1,8 +1,9 @@
from engine.ast import TableInfo, ast_node from engine.ast import ColRef, TableInfo, ast_node
from engine.orderby import assumption
from engine.scan import scan from engine.scan import scan
from engine.utils import base62uuid from engine.utils import base62uuid
from engine.expr import expr from engine.expr import expr
import engine.types
class groupby(ast_node): class groupby(ast_node):
name = '_groupby' name = '_groupby'
def init(self, _): def init(self, _):
@ -12,7 +13,7 @@ class groupby(ast_node):
self.group_type = 'record_type' + base62uuid(7) self.group_type = 'record_type' + base62uuid(7)
self.datasource = self.parent.datasource self.datasource = self.parent.datasource
self.scanner = None self.scanner = None
self.datasource.rec = [] self.datasource.rec = set()
self.raw_groups = [] self.raw_groups = []
def produce(self, node): def produce(self, node):
@ -24,7 +25,8 @@ class groupby(ast_node):
for i, g in enumerate(node): for i, g in enumerate(node):
v = g['value'] v = g['value']
e = expr(self, v) e = expr(self, v)
self.raw_groups.append(e.raw_col) if type(e.raw_col) is ColRef:
self.raw_groups.append(e.raw_col)
e = e._expr e = e._expr
# if v is compound expr, create tmp cols # if v is compound expr, create tmp cols
if type(v) is not str: if type(v) is not str:
@ -40,7 +42,7 @@ class groupby(ast_node):
self.emit(f'unordered_map<{self.group_type}, vector_type<uint32_t>, ' self.emit(f'unordered_map<{self.group_type}, vector_type<uint32_t>, '
f'transTypes<{self.group_type}, hasher>> {self.group};') f'transTypes<{self.group_type}, hasher>> {self.group};')
self.n_grps = len(node) 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});') self.scanner.add(f'{self.group}[forward_as_tuple({g_contents(self.scanner.it_ver)})].emplace_back({self.scanner.it_ver});')
@ -48,7 +50,14 @@ class groupby(ast_node):
self.referenced = self.datasource.rec self.referenced = self.datasource.rec
self.datasource.rec = None self.datasource.rec = None
self.scanner.finalize() self.scanner.finalize()
def deal_with_assumptions(self, assumption:assumption, out:TableInfo):
gscanner = scan(self, self.group)
val_var = 'val_'+base62uuid(7)
gscanner.add(f'auto &{val_var} = {gscanner.it_ver}.second;')
gscanner.add(f'{out.cxt_name}->order_by<{assumption.result()}>(&{val_var});')
gscanner.finalize()
def finalize(self, cexprs, out:TableInfo): def finalize(self, cexprs, out:TableInfo):
gscanner = scan(self, self.group) gscanner = scan(self, self.group)
key_var = 'key_'+base62uuid(7) key_var = 'key_'+base62uuid(7)
@ -58,4 +67,6 @@ class groupby(ast_node):
gscanner.add(f'auto &{val_var} = {gscanner.it_ver}.second;') gscanner.add(f'auto &{val_var} = {gscanner.it_ver}.second;')
gscanner.add(';\n'.join([f'{out.columns[i].reference()}.emplace_back({ce(x=val_var, y=key_var)})' for i, ce in enumerate(cexprs)])+';') gscanner.add(';\n'.join([f'{out.columns[i].reference()}.emplace_back({ce(x=val_var, y=key_var)})' for i, ce in enumerate(cexprs)])+';')
gscanner.finalize() gscanner.finalize()
self.datasource.groupinfo = None

@ -16,43 +16,50 @@ class order_item:
return ('' if self.order else '-') + f'({self.name})' return ('' if self.order else '-') + f'({self.name})'
def __str__(self): def __str__(self):
return self.materialize() return self.name
def __repr__(self): def __repr__(self):
return self.__str__() 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): class orderby(ast_node):
name = '_orderby' name = '_orderby'
def __init__(self, parent: "ast_node", node, context: Context = None):
self.col_list = []
super().__init__(parent, node, context)
def init(self, _): def init(self, _):
self.datasource = self.parent.datasource self.datasource = self.parent.datasource
self.order = orders(self, self.datasource) self.order = []
self.view = '' self.view = ''
def produce(self, node): def produce(self, node):
if type(node) is not list: if type(node) is not list:
node = [node] node = [node]
for n in node: for n in node:
order = not ('sort' in n and n['sort'] == 'desc') order = not ('sort' in n and n['sort'] == 'desc')
self.order.append(order_item(n['value'], self, order)) col_id = self.datasource.columns_byname[n['value']].id
col_id = col_id if order else -col_id-1
if col_id not in self.col_list:
self.col_list.append(col_id)
self.order.append(order_item(n['value'], self, order))
def merge(self, node):
self.produce(node)
def finialize(self, references):
self.order = [ o for o in self.order if o.name in references ]
def result(self, sep:str = ','):
return sep.join([f"{c}" for c in self.col_list])
def consume(self, _): class assumption(orderby):
self.datasource.order.append(self.order) name = '_assumption'
def __init__(self, parent: "ast_node", node, context: Context = None, exclude = []):
self.exclude = exclude
super().__init__(parent, node, context)
def produce(self, node):
if type(node) is not list:
node = [node]
[n for n in node if n not in self.exclude]
return super().produce(node)
def empty(self):
return len(self.col_list) == 0

@ -2,9 +2,9 @@ from engine.ast import ColRef, TableInfo, ast_node, Context, include
from engine.groupby import groupby from engine.groupby import groupby
from engine.join import join from engine.join import join
from engine.expr import expr from engine.expr import expr
from engine.orderby import orderby from engine.orderby import assumption, orderby
from engine.scan import filter from engine.scan import filter
from engine.utils import base62uuid, enlist, base62alp from engine.utils import base62uuid, enlist, base62alp, has_other
from engine.ddl import create_table, outfile from engine.ddl import create_table, outfile
import copy import copy
@ -14,6 +14,8 @@ class projection(ast_node):
self.disp = disp self.disp = disp
self.outname = outname self.outname = outname
self.group_node = None self.group_node = None
self.assumptions = None
self.where = None
ast_node.__init__(self, parent, node, context) ast_node.__init__(self, parent, node, context)
def init(self, _): def init(self, _):
if self.outname is None: if self.outname is None:
@ -44,9 +46,8 @@ class projection(ast_node):
elif type(value) is str: elif type(value) is str:
self.datasource = self.context.tables_byname[value] self.datasource = self.context.tables_byname[value]
if 'assumptions' in from_clause: if 'assumptions' in from_clause:
for assumption in enlist(from_clause['assumptions']): self.assumptions = enlist(from_clause['assumptions'])
orderby(self, assumption)
elif type(from_clause) is str: elif type(from_clause) is str:
self.datasource = self.context.tables_byname[from_clause] self.datasource = self.context.tables_byname[from_clause]
@ -58,8 +59,9 @@ class projection(ast_node):
self.prev_datasource = self.context.datasource self.prev_datasource = self.context.datasource
self.context.datasource = self.datasource self.context.datasource = self.datasource
if 'where' in node: if 'where' in node:
self.datasource = filter(self, node['where'], True).output self.where = filter(self, node['where'], True)
self.context.datasource = self.datasource # self.datasource = filter(self, node['where'], True).output
# self.context.datasource = self.datasource
if 'groupby' in node: if 'groupby' in node:
self.group_node = groupby(self, node['groupby']) self.group_node = groupby(self, node['groupby'])
@ -71,62 +73,101 @@ class projection(ast_node):
def consume(self, node): def consume(self, node):
self.inv = True self.inv = True
disp_varname = 'd'+base62uuid(7) disp_varname = 'd'+base62uuid(7)
has_groupby = False has_groupby = self.group_node is not None
if self.group_node is not None:
# There is group by;
has_groupby = True
cexprs = [] cexprs = []
flatten = False flatten = False
cols = [] cols = []
self.out_table = TableInfo('out_'+base62uuid(4), [], self.context) self.out_table = TableInfo('out_'+base62uuid(4), [], self.context)
if 'outfile' in node: if 'outfile' in node:
flatten = True flatten = True
new_names = []
proj_raw_cols = []
for i, proj in enumerate(self.projections): for i, proj in enumerate(self.projections):
cname = '' cname = ''
compound = False compound = False
self.datasource.rec = [] self.datasource.rec = set()
if type(proj) is dict: if type(proj) is dict:
if 'value' in proj: if 'value' in proj:
e = proj['value'] e = proj['value']
sname = expr(self, e)._expr sname = expr(self, e)
fname = expr.toCExpr(sname) if type(sname.raw_col) is ColRef:
absname = expr(self, e, abs_col=True)._expr proj_raw_cols.append(sname.raw_col)
compound = True sname = sname._expr
fname = expr.toCExpr(sname) # fastest access method at innermost context
absname = expr(self, e, abs_col=True)._expr # absolute name at function scope
# TODO: Make it single pass here.
compound = True # compound column
cexprs.append(fname) 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
compound = compound and has_groupby and self.datasource.rec not in self.group_node.referenced cname = proj['name']
new_names.append(cname)
elif type(proj) is str:
col = self.datasource.get_col_d(proj)
if type(col) is ColRef:
col.reference()
compound = compound and has_groupby and has_other(self.datasource.rec, self.group_node.referenced)
self.datasource.rec = None
typename = f'decays<decltype({absname})>'
if not compound:
typename = f'value_type<{typename}>'
cols.append(ColRef(cname, expr.toCExpr(typename)(), self.out_table, 0, None, cname, i, compound=compound))
cols.append(ColRef(cname, expr.toCExpr(f'decays<decltype({absname})>')(0), self.out_table, 0, None, cname, i, compound=compound))
self.out_table.add_cols(cols, False) self.out_table.add_cols(cols, False)
lineage = None
if has_groupby: if has_groupby:
create_table(self, self.out_table) create_table(self, self.out_table) # creates empty out_table.
if self.assumptions is not None:
self.assumptions = assumption(self, self.assumptions, exclude=self.group_node.raw_groups)
if not self.assumptions.empty():
self.group_node.deal_with_assumptions(self.assumptions, self.out_table)
self.assumptions = None
self.group_node.finalize(cexprs, self.out_table) self.group_node.finalize(cexprs, self.out_table)
else: else:
create_table(self, self.out_table, cexpr = cexprs) # if all assumptions in projections, treat as orderby
self.datasource.group_node = None lineage = self.assumptions is not None and has_other(self.assumptions, proj_raw_cols)
spawn = create_table(self, self.out_table, cexprs = cexprs, lineage = lineage) # create and populate out_table.
has_orderby = 'orderby' in node if lineage and type(spawn.lineage) is str:
lineage = spawn.lineage
if has_orderby: self.assumptions = orderby(self, self.assumptions) # do not exclude proj_raw_cols
else:
lineage = None
if self.where is not None:
self.where.finalize()
if type(lineage) is str:
order = 'order_' + base62uuid(6)
self.emit(f'auto {order} = {self.datasource.cxt_name}->order_by<{self.assumptions.result()}>({lineage});')
self.emit(f'{self.out_table.cxt_name}->materialize(*{order});')
self.assumptions = None
if self.assumptions is not None:
orderby_node = orderby(self, self.assumptions)
else:
orderby_node = None
if 'orderby' in node:
self.datasource = self.out_table self.datasource = self.out_table
self.context.datasource = self.out_table # discard current ds self.context.datasource = self.out_table # discard current ds
orderby_node = orderby(self, node['orderby']) orderbys = node['orderby']
self.context.datasource.materialize_orderbys() orderby_node = orderby(self, orderbys) if orderby_node is None else orderby_node.merge(orderbys)
self.emit_no_ln(f"{f'{disp_varname}:+' if flatten else ''}(")
if orderby_node is not None:
self.emit(f'auto {disp_varname} = {self.out_table.reference()}->order_by_view<{orderby_node.result()}>();')
else:
disp_varname = f'*{self.out_table.cxt_name}'
if self.disp or has_orderby: if self.disp:
self.emit(f'print(*{self.out_table.cxt_name});') self.emit(f'print({disp_varname});')
if has_orderby:
self.emit(f')[{orderby_node.view}]')
else:
self.context.emit_flush()
if flatten: if flatten:
if len(self.projections) > 1 and not self.inv:
self.emit(f"{disp_varname}:+{disp_varname}")
outfile(self, node['outfile']) outfile(self, node['outfile'])
if self.datasource_changed: if self.datasource_changed:

@ -5,16 +5,20 @@ from engine.expr import expr
class scan(ast_node): class scan(ast_node):
name = 'scan' name = 'scan'
def __init__(self, parent: "ast_node", node, size = None, context: Context = None): def __init__(self, parent: "ast_node", node, size = None, context: Context = None, const = False):
self.type = type self.type = type
self.size = size self.size = size
self.const = "const " if const else ""
super().__init__(parent, node, context) super().__init__(parent, node, context)
def init(self, _): def init(self, _):
self.datasource = self.context.datasource self.datasource = self.context.datasource
self.initializers = ''
self.start = '' self.start = ''
self.front = ''
self.body = '' self.body = ''
self.end = '}' self.end = '}'
self.filter = None self.mode = None
self.filters = []
scan_vars = set(s.it_var for s in self.context.scans) scan_vars = set(s.it_var for s in self.context.scans)
self.it_ver = 'i' + base62uuid(2) self.it_ver = 'i' + base62uuid(2)
while(self.it_ver in scan_vars): while(self.it_ver in scan_vars):
@ -22,19 +26,33 @@ class scan(ast_node):
self.parent.context.scans.append(self) self.parent.context.scans.append(self)
def produce(self, node): def produce(self, node):
if type(node) is ColRef: if type(node) is ColRef:
self.colref = node
if self.size is None: if self.size is None:
self.start += f'for (auto& {self.it_ver} : {node.reference()}) {{\n' self.mode = ["col", node.table]
self.start += f'for ({self.const}auto& {self.it_ver} : {node.reference()}) {{\n'
else: 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" 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: elif type(node) is str:
self.start+= f'for(auto& {self.it_ver} : {node}) {{\n' self.mode = ["idx", None]
self.start+= f'for({self.const}auto& {self.it_ver} : {node}) {{\n'
else: 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" self.start += f"for (uint32_t {self.it_ver} = 0; {self.it_ver} < {self.size}; ++{self.it_ver}){{\n"
def add(self, stmt): def add(self, stmt, position = "body"):
self.body+=stmt + '\n' if position == "body":
self.body += stmt + '\n'
elif position == "init":
self.initializers += stmt + '\n'
else:
self.front += stmt + '\n'
def finalize(self): 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.front + self.body + self.end)
class filter(ast_node): class filter(ast_node):
name = 'filter' name = 'filter'
@ -45,7 +63,7 @@ class filter(ast_node):
self.datasource = self.context.datasource self.datasource = self.context.datasource
self.view = View(self.context, self.datasource) self.view = View(self.context, self.datasource)
self.value = None self.value = None
def spawn(self, node): def spawn(self, node):
# TODO: deal with subqueries # TODO: deal with subqueries
self.modified_node = node self.modified_node = node
@ -64,9 +82,18 @@ class filter(ast_node):
self.emit(f'{tmpVar}:{self.value}') self.emit(f'{tmpVar}:{self.value}')
for o, c in zip(self.output.columns, self.datasource.columns): for o, c in zip(self.output.columns, self.datasource.columns):
self.emit(f'{o.cname}:$[{tmpVar};{c.cname};()]') 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 # 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) self.expr = expr(self, self.modified_node)
print(node) self.scanner.filters.append(f'if ({self.expr.cexpr(self.scanner.it_ver)}) {{\n')

@ -16,4 +16,10 @@ def enlist(l):
return l if type(l) is list else [l] return l if type(l) is list else [l]
def seps(s, i, l): def seps(s, i, l):
return s if i < len(l) - 1 else '' return s if i < len(l) - 1 else ''
def has_other(a, b):
for ai in a:
if ai not in b:
return True
return False

@ -1,68 +0,0 @@
import`csv
md:{y-x*_y%x}
maxs:{[L]{max(x, y)}\L}
mins:{[L]{min(x, y)}\L}
sums:{[L]{(x + y)}\L}
avgsimpl:{[L;i] curr:L[i]%(i+1); $[i<(#L)-1;curr, avgsimpl[L;i+1];curr]}
avgs:{[L] avgsimpl[sums[L];0]}
/ maxswimp:{[L;w;i] curr:max(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]}
/ maxsw:{[w;L]maxswimp[L; w; 1]}
/ minswimp:{[L;w;i] curr:min(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]}
/ minsw:{[w;L]minswimp[L;w;1]}
/ avgswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];curr:s%((i+1)&w);$[i<(#L)-1; curr, avgswimp[L; w; s; i+1]; curr]}
/ avgsw:{[w;L] avgswimp[L;w;0;0]}
/ sumswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];$[i<(#L)-1; s, sumswimp[L; w; s; i+1]; s]}
/ sumsw:{[w;L] sumswimp[L;w;0;0]}
groupby0:{[L]
{[x;y]
x:$[(@x)=`i;(,(L[0]))!,(,0);x];
k:(,(L[y]));gvk:x[k][0];
found:$[(gvk[0]+gvk[1])>0;1;L[y] in !x];
cg:(,L[y])!$[found;,gvk[0],y;,(,y)];
(x,cg)}/!(#L)}
groupBy:{[x]groupBySingle:{[a;x]
findAll:{[c;xx]
f:{[i;c]$[(c[0])[i]~c[1];i+1;0]};
@[!#xx;!#xx;f;(#xx)#,(xx;c)]};
z:findAll[a;x];
b:(findAll[0;z]_(!(1+#z)))-1;(a;b)};
x:+x;y:?x;
@[y;!#y;groupBySingle;(#y)#,x]}
groupby:{[L]
L:^+L;
dimy:(#(L[0]))-1;
((({[L;dim;x;y]
x:$[x~0;(,(dim#(L[0])),0);x];
curr:dim#(L[y]);
$[(dim#*x)~curr;x;((,curr,y),x)]}[L;dimy])/!(#L));(+L)[dimy]) }
lststr:{[L](+({[x;y] ($x,$y)}/L))[0]}
delist:{[L] $[(@L)in(`LL`LC`LG`L);delist[(,/L)];L]}
cntlist:{[L;i] $[(@L)in(`LL`LC`LG`L);cntlist[(,/L);i+1];i+1]}
flatRO:{[x]x[0],/:x[1]}
flatLO:{[x]x[0],\:x[1]}
flatBOTH:{[x],/(x[0],/:\:x[1])}
sumswkrl:{[L;w;x;y] ((x-L[y-w])+L[y])}
sumsw:{[w;L] $[(#L)=0;L;(sumswkrl[L;w])\@[!#L;0;L[file 0]]]}
avgswkrl:{[L;w;x;y] (x-(L[y-w]-L[y])%w)}
avgsw:{[w;L] $[(#L)=0;L;(avgswkrl[L;w])\@[!#L;0;L[0]]]}
/ minsw:{[w;L] ({[L;w;x] min(L[$[x>w;(!w) + ((x-w)+1);!(x+1)]])}[L;w])'!#L}
import`mmw
minsw:{[w;L] ret:L; mmw[ret;((`g ($@ret)[0]), (#ret), w, 65536)];ret}
maxsw:{[w;L] ret:L; mmw[ret;((`g ($@ret)[0]), (#ret), w, 65537)];ret}
minswip:{[w;L] mmw[L;((`g ($@L)[0]), (#L), w, 65536)];}
maxswip:{[w;L] mmw[L;((`g ($@L)[0]), (#L), w, 65537)];}

@ -1 +0,0 @@
{[I;L;R;i] t:&(I[i]);d:(#t);$[d=0;!0;+(Aa[t];Ab[t];d#(Bb[i]))]}[(Aa {x>(y*10)}/: Ba); Aa; Ba]'!#Aa

Binary file not shown.

Binary file not shown.

BIN
mmw.so

Binary file not shown.

@ -8,7 +8,7 @@ SELECT Month,avgs(3,sales)
FROM sale FROM sale
ASSUMING ASC Month ASSUMING ASC Month
INTO OUTFILE "moving_avg_output.csv" INTO OUTFILE "moving_avg_output.csv"
FIELDS TERMINATED BY "," FIELDS TERMINATED BY ";"
select sales, mins(2,Month) from sale group by sales select sales, mins(2,Month) from sale group by sales
into outfile "flatten.csv" into outfile "flatten.csv"

@ -0,0 +1,5 @@
#pragma once
template <class...T1, class ...T2>
struct lineage {
};

@ -93,6 +93,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -108,6 +109,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -123,6 +125,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -138,6 +141,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

@ -0,0 +1,93 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>ccc243f5-663e-45b7-a6de-b2468c58b3a7</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>
</StartupFile>
<SearchPath>..\msvs-py</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<Name>msvs-py</Name>
<RootNamespace>msvs-py</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<ItemGroup>
<Folder Include="..\aquery_parser\" />
<Folder Include="..\aquery_parser\__pycache__\" />
<Folder Include="..\engine\" />
<Folder Include="..\engine\__pycache__\" />
<Folder Include="parser\" />
<Folder Include="parser\__pycache__\" />
<Folder Include="__pycache__\" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\aquery_parser\keywords.py" />
<Compile Include="..\aquery_parser\sql_parser.py" />
<Compile Include="..\aquery_parser\types.py" />
<Compile Include="..\aquery_parser\utils.py" />
<Compile Include="..\aquery_parser\windows.py" />
<Compile Include="..\aquery_parser\__init__.py" />
<Compile Include="..\engine\ast.py" />
<Compile Include="..\engine\ddl.py" />
<Compile Include="..\engine\expr.py" />
<Compile Include="..\engine\groupby.py" />
<Compile Include="..\engine\join.py" />
<Compile Include="..\engine\orderby.py" />
<Compile Include="..\engine\projection.py" />
<Compile Include="..\engine\scan.py" />
<Compile Include="..\engine\types.py" />
<Compile Include="..\engine\utils.py" />
<Compile Include="..\engine\__init__.py" />
<Compile Include="..\prompt.py" />
</ItemGroup>
<ItemGroup>
<Content Include="..\aquery_parser\__pycache__\keywords.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\keywords.cpython-39.pyc" />
<Content Include="..\aquery_parser\__pycache__\sql_parser.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\sql_parser.cpython-39.pyc" />
<Content Include="..\aquery_parser\__pycache__\types.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\types.cpython-39.pyc" />
<Content Include="..\aquery_parser\__pycache__\utils.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\utils.cpython-39.pyc" />
<Content Include="..\aquery_parser\__pycache__\windows.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\windows.cpython-39.pyc" />
<Content Include="..\aquery_parser\__pycache__\__init__.cpython-310.pyc" />
<Content Include="..\aquery_parser\__pycache__\__init__.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\ast.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\ast.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\ddl.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\ddl.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\expr.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\expr.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\groupby.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\join.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\join.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\orderby.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\projection.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\projection.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\scan.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\types.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\utils.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\utils.cpython-39.pyc" />
<Content Include="..\engine\__pycache__\__init__.cpython-310.pyc" />
<Content Include="..\engine\__pycache__\__init__.cpython-39.pyc" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
<!-- Uncomment the CoreCompile target to enable the Build command in
Visual Studio and specify your pre- and post-build commands in
the BeforeBuild and AfterBuild targets below. -->
<!--<Target Name="CoreCompile" />-->
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
</Project>

@ -1,60 +1,61 @@
#include "./server/hasher.h"
#include "./server/aggregations.h" #include "./server/aggregations.h"
#include "csv.h"
#include "./server/libaquery.h" #include "./server/libaquery.h"
#include <unordered_map>
extern "C" int __DLLEXPORT__ dllmain(Context* cxt) { extern "C" int __DLLEXPORT__ dllmain(Context* cxt) {
using namespace std; using namespace std;
using namespace types; using namespace types;
auto stocks = new TableInfo<int,int>("stocks", 2);
cxt->tables.insert({"stocks", stocks}); auto sale = new TableInfo<int,int>("sale", 2);
auto& stocks_timestamp = *(ColRef<int> *)(&stocks->colrefs[0]); cxt->tables.insert({"sale", sale});
auto& stocks_price = *(ColRef<int> *)(&stocks->colrefs[1]); auto& sale_Month = *(ColRef<int> *)(&sale->colrefs[0]);
stocks_timestamp.init(); auto& sale_sales = *(ColRef<int> *)(&sale->colrefs[1]);
stocks_price.init(); sale_Month.init();
stocks_timestamp.emplace_back(1); sale_sales.init();
stocks_price.emplace_back(15); io::CSVReader<2> csv_reader_6T89Ll("moving_avg.csv");
stocks_timestamp.emplace_back(2); csv_reader_6T89Ll.read_header(io::ignore_extra_column, "Month","sales");
stocks_price.emplace_back(19); int tmp_5vttJ2yV;
stocks_timestamp.emplace_back(3); int tmp_2ckq15YU;
stocks_price.emplace_back(16); while(csv_reader_6T89Ll.read_row(tmp_5vttJ2yV,tmp_2ckq15YU)) {
stocks_timestamp.emplace_back(4);
stocks_price.emplace_back(17);
stocks_timestamp.emplace_back(5);
stocks_price.emplace_back(15);
stocks_timestamp.emplace_back(6);
stocks_price.emplace_back(13);
stocks_timestamp.emplace_back(7);
stocks_price.emplace_back(5);
stocks_timestamp.emplace_back(8);
stocks_price.emplace_back(8);
stocks_timestamp.emplace_back(9);
stocks_price.emplace_back(7);
stocks_timestamp.emplace_back(10);
stocks_price.emplace_back(13);
stocks_timestamp.emplace_back(11);
stocks_price.emplace_back(11);
stocks_timestamp.emplace_back(12);
stocks_price.emplace_back(14);
stocks_timestamp.emplace_back(13);
stocks_price.emplace_back(10);
stocks_timestamp.emplace_back(14);
stocks_price.emplace_back(5);
stocks_timestamp.emplace_back(15);
stocks_price.emplace_back(2);
stocks_timestamp.emplace_back(16);
stocks_price.emplace_back(5);
auto out_ZPYh = new TableInfo<decays<decltype(max((stocks_price[0]-min(stocks_timestamp[0]))))>>("out_ZPYh", 1);
cxt->tables.insert({"out_ZPYh", out_ZPYh});
auto& out_ZPYh_maxstockspriceminstockstimestamp = *(ColRef<decays<decltype(max((stocks_price[0]-min(stocks_timestamp[0]))))>> *)(&out_ZPYh->colrefs[0]);
out_ZPYh_maxstockspriceminstockstimestamp.init();
out_ZPYh_maxstockspriceminstockstimestamp = max((stocks_price-min(stocks_timestamp)));
print(*out_ZPYh);
auto out_1ac3 = new TableInfo<decays<decltype(max((stocks_price[0]-mins(stocks_price[0]))))>>("out_1ac3", 1);
cxt->tables.insert({"out_1ac3", out_1ac3});
auto& out_1ac3_maxstockspriceminsstocksprice = *(ColRef<decays<decltype(max((stocks_price[0]-mins(stocks_price[0]))))>> *)(&out_1ac3->colrefs[0]);
out_1ac3_maxstockspriceminsstocksprice.init();
out_1ac3_maxstockspriceminsstocksprice = max((stocks_price-mins(stocks_price)));
print(*out_1ac3);
sale_Month.emplace_back(tmp_5vttJ2yV);
sale_sales.emplace_back(tmp_2ckq15YU);
}
auto out_2UiD = new TableInfo<value_type<decays<decltype(sale_Month)>>,value_type<decays<decltype(avgw(3,sale_sales))>>>("out_2UiD", 2);
cxt->tables.insert({"out_2UiD", out_2UiD});
auto& out_2UiD_Month = *(ColRef<value_type<decays<decltype(sale_Month)>>> *)(&out_2UiD->colrefs[0]);
auto& out_2UiD_avgw3salesales = *(ColRef<value_type<decays<decltype(avgw(3,sale_sales))>>> *)(&out_2UiD->colrefs[1]);
auto order_1NNZ9F = sale->order_by<0>();
out_2UiD_Month.init();
out_2UiD_Month = sale_Month[*order_1NNZ9F];
out_2UiD_avgw3salesales.init();
out_2UiD_avgw3salesales = avgw(3,sale_sales[*order_1NNZ9F]);
print(*out_2UiD);
FILE* fp_6xIJn4 = fopen("moving_avg_output.csv", "w");
out_2UiD->printall(";", "\n", nullptr, fp_6xIJn4);
fclose(fp_6xIJn4);
typedef record<decltype(sale_sales[0])> record_type6Lepq5T;
unordered_map<record_type6Lepq5T, vector_type<uint32_t>, transTypes<record_type6Lepq5T, hasher>> g4loWjmn;
for (uint32_t i5g = 0; i5g < sale_sales.size; ++i5g){
g4loWjmn[forward_as_tuple(sale_sales[i5g])].emplace_back(i5g);
}
auto out_2YlO = new TableInfo<value_type<decays<decltype(sale_sales)>>,decays<decltype(minw(2,sale_Month))>>("out_2YlO", 2);
cxt->tables.insert({"out_2YlO", out_2YlO});
auto& out_2YlO_sales = *(ColRef<value_type<decays<decltype(sale_sales)>>> *)(&out_2YlO->colrefs[0]);
auto& out_2YlO_minw2saleMonth = *(ColRef<decays<decltype(minw(2,sale_Month))>> *)(&out_2YlO->colrefs[1]);
out_2YlO_sales.init();
out_2YlO_minw2saleMonth.init();
for(auto& iFU : g4loWjmn) {
auto &key_3AwvKMR = iFU.first;
auto &val_7jtE12E = iFU.second;
out_2YlO_sales.emplace_back(get<0>(key_3AwvKMR));
out_2YlO_minw2saleMonth.emplace_back(minw(2,sale_Month[val_7jtE12E]));
}
print(*out_2YlO);
FILE* fp_45ld6S = fopen("flatten.csv", "w");
out_2YlO->printall(",", "\n", nullptr, fp_45ld6S);
fclose(fp_45ld6S);
return 0; return 0;
} }

@ -0,0 +1,60 @@
#include "./server/libaquery.h"
#include <unordered_map>
#include "./server/hasher.h"
#include "csv.h"
#include "./server/aggregations.h"
extern "C" int __DLLEXPORT__ dllmain(Context* cxt) {
using namespace std;
using namespace types;
auto sale = new TableInfo<int,int>("sale", 2);
cxt->tables.insert({"sale", sale});
auto& sale_Month = *(ColRef<int> *)(&sale->colrefs[0]);
auto& sale_sales = *(ColRef<int> *)(&sale->colrefs[1]);
sale_Month.init();
sale_sales.init();
io::CSVReader<2> csv_reader_53ychC("moving_avg.csv");
csv_reader_53ychC.read_header(io::ignore_extra_column, "Month","sales");
int tmp_7ttMnHd3;
int tmp_5nHjeAtP;
while(csv_reader_53ychC.read_row(tmp_7ttMnHd3,tmp_5nHjeAtP)) {
sale_Month.emplace_back(tmp_7ttMnHd3);
sale_sales.emplace_back(tmp_5nHjeAtP);
}
auto out_3Xio = new TableInfo<decays<decltype(sale_Month[0])>,decays<decltype(avgw(3,sale_sales))>>("out_3Xio", 2);
cxt->tables.insert({"out_3Xio", out_3Xio});
auto& out_3Xio_Month = *(ColRef<decays<decltype(sale_Month[0])>> *)(&out_3Xio->colrefs[0]);
auto& out_3Xio_avgsw3salesales = *(ColRef<decays<decltype(avgw(3,sale_sales))>> *)(&out_3Xio->colrefs[1]);
out_3Xio_Month.init();
out_3Xio_Month = sale_Month;
out_3Xio_avgsw3salesales.init();
out_3Xio_avgsw3salesales = avgw(3,sale_sales);
// print(*out_3Xio);
FILE* fp_4nKGhD = fopen("moving_avg_output.csv", "w");
out_3Xio->printall(",", "\n", nullptr, fp_4nKGhD);
fclose(fp_4nKGhD);
typedef record<decltype(sale_sales[0])> record_type1H2vDGL;
unordered_map<record_type1H2vDGL, vector_type<uint32_t>, transTypes<record_type1H2vDGL, hasher>> g6Mjxfk5;
for (uint32_t i7u = 0; i7u < sale_sales.size; ++i7u){
g6Mjxfk5[forward_as_tuple(sale_sales[i7u])].emplace_back(i7u);
}
auto out_2IU2 = new TableInfo<decays<decltype(sale_sales[0])>,decays<decltype(minw(2,sale_Month))>>("out_2IU2", 2);
cxt->tables.insert({"out_2IU2", out_2IU2});
auto& out_2IU2_sales = *(ColRef<decays<decltype(sale_sales[0])>> *)(&out_2IU2->colrefs[0]);
auto& out_2IU2_minsw2saleMonth = *(ColRef<decays<decltype(minw(2,sale_Month))>> *)(&out_2IU2->colrefs[1]);
out_2IU2_sales.init();
out_2IU2_minsw2saleMonth.init();
for(auto& i5J : g6Mjxfk5) {
auto &key_4jl5toH = i5J.first;
auto &val_VJGwVwH = i5J.second;
out_2IU2_sales.emplace_back(get<0>(key_4jl5toH));
out_2IU2_minsw2saleMonth.emplace_back(minw(2,sale_Month[val_VJGwVwH]));
}
// print(*out_2IU2);
FILE* fp_18R4fY = fopen("flatten.csv", "w");
out_2IU2->printall(",","\n", nullptr, fp_18R4fY);
fclose(fp_18R4fY);
return 0;
}

@ -1,46 +0,0 @@
#include "./server/libaquery.h"
#include <cstdio>
#include <threads.h>
extern "C" int dllmain(Context *cxt)
{
auto stocks = new TableInfo<int, int>("stocks", 2);
cxt->tables.insert(std::make_pair("stocks", stocks));
stocks->colrefs[0].ty = types::AINT;
stocks->colrefs[1].ty = types::AINT;
auto &stocks_0 = *(ColRef<int> *)(&stocks->colrefs[0]);
auto &stocks_1 = *(ColRef<int> *)(&stocks->colrefs[1]);
stocks_0.emplace_back(1);
stocks_1.emplace_back(15);
stocks_0.emplace_back(2);
stocks_1.emplace_back(19);
stocks_0.emplace_back(3);
stocks_1.emplace_back(16);
stocks_0.emplace_back(4);
stocks_1.emplace_back(17);
stocks_0.emplace_back(5);
stocks_1.emplace_back(15);
stocks_0.emplace_back(6);
stocks_1.emplace_back(13);
stocks_0.emplace_back(7);
stocks_1.emplace_back(5);
stocks_0.emplace_back(8);
stocks_1.emplace_back(8);
stocks_0.emplace_back(9);
stocks_1.emplace_back(7);
stocks_0.emplace_back(10);
stocks_1.emplace_back(13);
stocks_0.emplace_back(11);
stocks_1.emplace_back(11);
stocks_0.emplace_back(12);
stocks_1.emplace_back(14);
stocks_0.emplace_back(13);
stocks_1.emplace_back(10);
stocks_0.emplace_back(14);
stocks_1.emplace_back(5);
stocks_0.emplace_back(15);
stocks_1.emplace_back(2);
stocks_0.emplace_back(16);
stocks_1.emplace_back(5);
printf("%d\n", max(stocks_0 - min(stocks_1)));
return 0;
}

@ -1,6 +1,8 @@
from concurrent.futures import thread from concurrent.futures import thread
import re import re
import time import time
from mo_parsing import ParseException
import aquery_parser as parser import aquery_parser as parser
import engine import engine
import subprocess import subprocess
@ -90,6 +92,8 @@ cxt = None
while test_parser: while test_parser:
try: try:
if server.poll() is not None: if server.poll() is not None:
mm.seek(0,os.SEEK_SET)
mm.write(b'\x01\x00')
server = subprocess.Popen(["./server.bin", shm]) server = subprocess.Popen(["./server.bin", shm])
q = input() q = input()
if q == 'exec': if q == 'exec':
@ -126,6 +130,15 @@ while test_parser:
mm.seek(0,os.SEEK_SET) mm.seek(0,os.SEEK_SET)
mm.write(b'\x01\x01') mm.write(b'\x01\x01')
continue continue
elif q.startswith('save'):
filename = re.split(' |\t', q)
if (len(filename) > 1):
filename = filename[1]
else:
filename = f'out_{base62uuid(4)}.cpp'
with open(filename, 'wb') as outfile:
outfile.write((cxt.finalize()).encode('utf-8'))
continue
trimed = ws.sub(' ', q.lower()).split(' ') trimed = ws.sub(' ', q.lower()).split(' ')
if trimed[0].startswith('f'): if trimed[0].startswith('f'):
fn = 'stock.a' if len(trimed) <= 1 or len(trimed[1]) == 0 \ fn = 'stock.a' if len(trimed) <= 1 or len(trimed[1]) == 0 \
@ -137,7 +150,7 @@ while test_parser:
continue continue
stmts = parser.parse(q) stmts = parser.parse(q)
print(stmts) print(stmts)
except (ValueError, FileNotFoundError) as e: except (ValueError, FileNotFoundError, ParseException) as e:
rm() rm()
print(type(e), e) print(type(e), e)

@ -7,4 +7,4 @@ FIELDS TERMINATED BY ","
SELECT sum(c), b, d SELECT sum(c), b, d
FROM test FROM test
group by a,b,d group by a,b,d
-- order by d DESC, b ASC order by d DESC, b ASC

@ -39,10 +39,10 @@ T min(const VT<T>& v) {
return min_v; return min_v;
} }
template<class T, template<typename ...> class VT> template<class T, template<typename ...> class VT>
VT<T> mins(const VT<T>& arr) { decayed_t<VT,T> mins(const VT<T>& arr) {
const int& len = arr.size; const uint32_t& len = arr.size;
std::deque<std::pair<T, uint32_t>> cache; std::deque<std::pair<T, uint32_t>> cache;
VT<T> ret(len); decayed_t<VT,T> ret(len);
T min = std::numeric_limits<T>::max(); T min = std::numeric_limits<T>::max();
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
if (arr[i] < min) if (arr[i] < min)
@ -52,9 +52,9 @@ VT<T> mins(const VT<T>& arr) {
return ret; return ret;
} }
template<class T, template<typename ...> class VT> template<class T, template<typename ...> class VT>
VT<T> maxs(const VT<T>& arr) { decayed_t<VT,T> maxs(const VT<T>& arr) {
const int& len = arr.size; const uint32_t& len = arr.size;
VT<T> ret(len); decayed_t<VT,T> ret(len);
T max = std::numeric_limits<T>::min(); T max = std::numeric_limits<T>::min();
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
if (arr[i] > max) if (arr[i] > max)
@ -65,9 +65,9 @@ VT<T> maxs(const VT<T>& arr) {
} }
template<class T, template<typename ...> class VT> template<class T, template<typename ...> class VT>
VT<T> minw(const VT<T>& arr, uint32_t w) { decayed_t<VT,T> minw(uint32_t w, const VT<T>& arr) {
const int& len = arr.size; const uint32_t& len = arr.size;
VT<T> ret(len); decayed_t<VT,T> ret{len};
std::deque<std::pair<T, uint32_t>> cache; std::deque<std::pair<T, uint32_t>> cache;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
if (!cache.empty() && cache.front().second == i - w) cache.pop_front(); if (!cache.empty() && cache.front().second == i - w) cache.pop_front();
@ -79,9 +79,9 @@ VT<T> minw(const VT<T>& arr, uint32_t w) {
} }
template<class T, template<typename ...> class VT> template<class T, template<typename ...> class VT>
VT<T> maxw(const VT<T>& arr, uint32_t w) { decayed_t<VT,T> maxw(uint32_t w, const VT<T>& arr) {
const int& len = arr.size; const uint32_t& len = arr.size;
VT<T> ret(len); decayed_t<VT, T> ret(len);
std::deque<std::pair<T, uint32_t>> cache; std::deque<std::pair<T, uint32_t>> cache;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
if (!cache.empty() && cache.front().second == i - w) cache.pop_front(); if (!cache.empty() && cache.front().second == i - w) cache.pop_front();
@ -92,14 +92,66 @@ VT<T> maxw(const VT<T>& arr, uint32_t w) {
return ret; return ret;
} }
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetLongType<T>> sums(const VT<T>& arr) {
const uint32_t& len = arr.size;
decayed_t<VT, types::GetLongType<T>> ret(len);
uint32_t i = 0;
if(len) ret[i++] = arr[0];
for (; i < len; ++i)
ret[i] = ret[i-1] + arr[i];
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> avgs(const VT<T>& arr) {
const uint32_t& len = arr.size;
typedef types::GetFPType<T> FPType;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s;
if(len) s = ret[i++] = arr[0];
for (; i < len; ++i)
ret[i] = (s+=arr[i])/(FPType)(i+1);
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
const uint32_t& len = arr.size;
decayed_t<VT, types::GetLongType<T>> ret(len);
uint32_t i = 0;
w = w > len ? len : w;
if(len) ret[i++] = arr[0];
for (; i < w; ++i)
ret[i] = ret[i-1] + arr[i];
for (; i < len; ++i)
ret[i] = ret[i-1] + arr[i] - arr[i-w];
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> avgw(uint32_t w, const VT<T>& arr) {
typedef types::GetFPType<T> FPType;
const uint32_t& len = arr.size;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s;
w = w > len ? len : w;
if(len) s = ret[i++] = arr[0];
for (; i < w; ++i)
ret[i] = (s += arr[i])/(FPType)(i+1);
for (; i < len; ++i)
ret[i] = ret[i-1] + (arr[i] - arr[i-w])/(FPType)w;
return ret;
}
template <class T> constexpr inline T count(const T& v) { return 1; }
template <class T> constexpr inline T max(const T& v) { return v; } template <class T> constexpr inline T max(const T& v) { return v; }
template <class T> constexpr inline T min(const T& v) { return v; } template <class T> constexpr inline T min(const T& v) { return v; }
template <class T> constexpr inline T avg(const T& v) { return v; } template <class T> constexpr inline T avg(const T& v) { return v; }
template <class T> constexpr inline T sum(const T& v) { return v; } template <class T> constexpr inline T sum(const T& v) { return v; }
template <class T> constexpr inline T maxw(const T& v, uint32_t) { return v; } template <class T> constexpr inline T maxw(uint32_t, const T& v) { return v; }
template <class T> constexpr inline T minw(const T& v, uint32_t) { return v; } template <class T> constexpr inline T minw(uint32_t, const T& v) { return v; }
template <class T> constexpr inline T avgw(const T& v, uint32_t) { return v; } template <class T> constexpr inline T avgw(uint32_t, const T& v) { return v; }
template <class T> constexpr inline T sumw(const T& v, uint32_t) { return v; } template <class T> constexpr inline T sumw(uint32_t, const T& v) { return v; }
template <class T> constexpr inline T maxs(const T& v) { return v; } template <class T> constexpr inline T maxs(const T& v) { return v; }
template <class T> constexpr inline T mins(const T& v) { return v; } template <class T> constexpr inline T mins(const T& v) { return v; }
template <class T> constexpr inline T avgs(const T& v) { return v; } template <class T> constexpr inline T avgs(const T& v) { return v; }

@ -0,0 +1,15 @@
#pragma once
#include "types.h"
#include <cstdio>
#include <string>
template <class ...Types>
std::string generate_printf_string(const char* sep = " ", const char* end = "\n") {
std::string str;
((str += types::printf_str[types::Types<value_type_r<Types>>::getType()], str += sep), ...);
const auto trim = str.size() - strlen(sep);
if (trim > 0)
str.resize(trim);
str += end;
return str;
}

@ -0,0 +1,19 @@
#pragma once
#include "vector_type.hpp"
#include <algorithm>
#include <stdint.h>
template <class Comparator, typename T = uint32_t>
class priority_vector : public vector_type<T> {
const Comparator comp;
public:
priority_vector(Comparator comp = std::less<T>{}) :
comp(comp), vector_type<T>(0) {}
void emplace_back(T val) {
vector_type<T>::emplace_back(val);
std::push_heap(container, container + size, comp);
}
void pop_back() {
std::pop_heap(container, container + size, comp);
--size;
}
};

@ -75,6 +75,7 @@ int main(int argc, char** argv) {
shm.FreeMemoryMap(); shm.FreeMemoryMap();
return 0; return 0;
} }
#include "utils.h"
int _main() int _main()
{ {
@ -83,6 +84,7 @@ int _main()
//t.emplace_back(2); //t.emplace_back(2);
//print(t); //print(t);
//return 0; //return 0;
puts(cpp_17 ?"true":"false");
void* handle = dlopen("dll.so", RTLD_LAZY); void* handle = dlopen("dll.so", RTLD_LAZY);
printf("handle: %x\n", handle); printf("handle: %x\n", handle);
Context* cxt = new Context(); Context* cxt = new Context();
@ -96,7 +98,8 @@ int _main()
} }
dlclose(handle); dlclose(handle);
} }
//static_assert(std::is_same_v<decltype(fill_integer_array<5, 1>()), std::integer_sequence<bool, 1,1,1,1,1>>, "");
return 0; return 0;
std::unordered_map<int, int> a;
} }

@ -8,32 +8,50 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "server.vcxproj",
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81} = {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81} {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81} = {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project1", "..\Project1\Project1.vcxproj", "{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msc-plugin", "..\msc-plugin\msc-plugin.vcxproj", "{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "msvs-py", "..\msvs-py\msvs-py.pyproj", "{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|Any CPU.ActiveCfg = Debug|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|Any CPU.Build.0 = Debug|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x64.ActiveCfg = Debug|x64 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x64.ActiveCfg = Debug|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x64.Build.0 = Debug|x64 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x64.Build.0 = Debug|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x86.ActiveCfg = Debug|Win32 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x86.ActiveCfg = Debug|Win32
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x86.Build.0 = Debug|Win32 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Debug|x86.Build.0 = Debug|Win32
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|Any CPU.ActiveCfg = Release|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|Any CPU.Build.0 = Release|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x64.ActiveCfg = Release|x64 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x64.ActiveCfg = Release|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x64.Build.0 = Release|x64 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x64.Build.0 = Release|x64
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x86.ActiveCfg = Release|Win32 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x86.ActiveCfg = Release|Win32
{031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x86.Build.0 = Release|Win32 {031352C2-AFBB-45AA-9518-DBC1F9EF2AF3}.Release|x86.Build.0 = Release|Win32
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|Any CPU.ActiveCfg = Debug|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|Any CPU.Build.0 = Debug|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x64.ActiveCfg = Debug|x64 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x64.ActiveCfg = Debug|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x64.Build.0 = Debug|x64 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x64.Build.0 = Debug|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x86.ActiveCfg = Debug|Win32 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x86.ActiveCfg = Debug|Win32
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x86.Build.0 = Debug|Win32 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Debug|x86.Build.0 = Debug|Win32
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|Any CPU.ActiveCfg = Release|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|Any CPU.Build.0 = Release|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x64.ActiveCfg = Release|x64 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x64.ActiveCfg = Release|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x64.Build.0 = Release|x64 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x64.Build.0 = Release|x64
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x86.ActiveCfg = Release|Win32 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x86.ActiveCfg = Release|Win32
{8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x86.Build.0 = Release|Win32 {8081FDAA-4D13-4B7A-ADB2-8224AF7F1C81}.Release|x86.Build.0 = Release|Win32
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Debug|x86.ActiveCfg = Debug|Any CPU
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Release|x64.ActiveCfg = Release|Any CPU
{CCC243F5-663E-45B7-A6DE-B2468C58B3A7}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -23,32 +23,32 @@
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{031352c2-afbb-45aa-9518-dbc1f9ef2af3}</ProjectGuid> <ProjectGuid>{031352c2-afbb-45aa-9518-dbc1f9ef2af3}</ProjectGuid>
<RootNamespace>server</RootNamespace> <RootNamespace>server</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -88,9 +88,9 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -105,9 +105,9 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -122,9 +122,9 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -139,9 +139,9 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -167,7 +167,9 @@
<ClInclude Include="aggregations.h" /> <ClInclude Include="aggregations.h" />
<ClInclude Include="gc.hpp" /> <ClInclude Include="gc.hpp" />
<ClInclude Include="hasher.h" /> <ClInclude Include="hasher.h" />
<ClInclude Include="io.h" />
<ClInclude Include="libaquery.h" /> <ClInclude Include="libaquery.h" />
<ClInclude Include="priority_vector.hpp" />
<ClInclude Include="table.h" /> <ClInclude Include="table.h" />
<ClInclude Include="types.h" /> <ClInclude Include="types.h" />
<ClInclude Include="utils.h" /> <ClInclude Include="utils.h" />
@ -175,10 +177,4 @@
<ClInclude Include="winhelper.h" /> <ClInclude Include="winhelper.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
</Target>
</Project> </Project>

@ -1,9 +1,13 @@
// TODO: Replace `cout, printf` with sprintf&fputs and custom buffers
#ifndef _TABLE_H #ifndef _TABLE_H
#define _TABLE_H #define _TABLE_H
#include "types.h" #include "types.h"
#include "vector_type.hpp" #include "vector_type.hpp"
#include <iostream> #include <iostream>
#include <string>
#include "io.h"
template <typename T> template <typename T>
class vector_type; class vector_type;
template <> template <>
@ -24,8 +28,10 @@ template<typename _Ty>
class ColRef : public vector_type<_Ty> class ColRef : public vector_type<_Ty>
{ {
public: public:
typedef ColRef<_Ty> Decayed_t;
const char* name; const char* name;
types::Type_t ty = types::ERROR; types::Type_t ty = types::ERROR;
ColRef() : vector_type<_Ty>(0), name("") {}
ColRef(const uint32_t& size, const char* name = "") : vector_type<_Ty>(size), name(name) {} ColRef(const uint32_t& size, const char* name = "") : vector_type<_Ty>(size), name(name) {}
ColRef(const char* name) : name(name) {} ColRef(const char* name) : name(name) {}
void init() { ty = types::Types<_Ty>::getType(); this->size = this->capacity = 0; this->container = 0; } void init() { ty = types::Types<_Ty>::getType(); this->size = this->capacity = 0; this->container = 0; }
@ -35,6 +41,14 @@ public:
ColView<_Ty> operator [](const vector_type<uint32_t>&idxs) const { ColView<_Ty> operator [](const vector_type<uint32_t>&idxs) const {
return ColView<_Ty>(*this, idxs); return ColView<_Ty>(*this, idxs);
} }
void out(uint32_t n = 4, const char* sep = " ") const {
n = n > this->size ? this->size : n;
std::cout << '(';
for (uint32_t i = 0; i < n; ++i)
std::cout << this->operator[](i) << sep;
std::cout << ')';
}
template<typename T> template<typename T>
ColRef<T> scast(); ColRef<T> scast();
}; };
@ -42,6 +56,7 @@ public:
template<typename _Ty> template<typename _Ty>
class ColView { class ColView {
public: public:
typedef ColRef<_Ty> Decayed_t;
const vector_type<uint32_t>& idxs; const vector_type<uint32_t>& idxs;
const ColRef<_Ty>& orig; const ColRef<_Ty>& orig;
const uint32_t& size; const uint32_t& size;
@ -75,8 +90,22 @@ public:
Iterator_t end() const { Iterator_t end() const {
return Iterator_t(idxs.end(), orig); return Iterator_t(idxs.end(), orig);
} }
void out(uint32_t n = 4, const char* sep = " ") const {
n = n > size ? size : n;
std::cout<<'(';
for (uint32_t i = 0; i < n; ++i)
std::cout << this->operator[](i)<< sep;
std::cout << ')';
}
}; };
template <template <class...> class VT, class T>
std::ostream& operator<<(std::ostream& os, const VT<T>& v)
{
v.out();
return os;
}
template <class Type>
struct decayed_impl<ColView, Type> { typedef ColRef<Type> type; };
template<typename _Ty> template<typename _Ty>
template<typename T> template<typename T>
inline ColRef<T> ColRef<_Ty>::scast() inline ColRef<T> ColRef<_Ty>::scast()
@ -85,13 +114,62 @@ inline ColRef<T> ColRef<_Ty>::scast()
return *(ColRef<T> *)this; return *(ColRef<T> *)this;
} }
using uColRef = ColRef<void>; using uColRef = ColRef<void>;
template<class ...Types> struct TableInfo;
template<class ...Types> struct TableView;
template <long long _Index, bool order = true, class... _Types>
constexpr inline auto& get(const TableInfo<_Types...>& table) noexcept {
if constexpr (order)
return *(ColRef<std::tuple_element_t<_Index, std::tuple<_Types...>>> *) & (table.colrefs[_Index]);
else
return *(ColRef<std::tuple_element_t<-1-_Index, std::tuple<_Types...>>> *) & (table.colrefs[-1-_Index]);
}
template <long long _Index, class... _Types>
constexpr inline ColRef<std::tuple_element_t<_Index, std::tuple<_Types...>>>& get(const TableView<_Types...>& table) noexcept {
return *(ColRef<std::tuple_element_t<_Index, std::tuple<_Types...>>> *) & (table.info.colrefs[_Index]);
}
template <class V>
struct is_vector_impl<ColRef<V>> : std::true_type {};
template <class V>
struct is_vector_impl<ColView<V>> : std::true_type {};
template <class V>
struct is_vector_impl<vector_type<V>> : std::true_type {};
template<class ...Types>
struct TableView;
template<class ...Types> template<class ...Types>
struct TableInfo { struct TableInfo {
const char* name; const char* name;
ColRef<void>* colrefs; ColRef<void>* colrefs;
uint32_t n_cols; uint32_t n_cols;
void print(const char* __restrict sep, const char* __restrict end) const;
typedef std::tuple<Types...> tuple_type; typedef std::tuple<Types...> tuple_type;
void print(const char* __restrict sep, const char* __restrict end) const;
template <class ...Types2>
struct lineage_t {
TableInfo<Types...>* this_table;
TableInfo<Types2...>* table;
vector_type<uint32_t> rid;
constexpr lineage_t(TableInfo<Types...>*this_table, TableInfo<Types2...> *table)
: this_table(this_table), table(table), rid(0) {}
constexpr lineage_t() : this_table(0), table(0), rid(0) {}
template <int col>
inline auto& get(uint32_t idx) {
return get<col>(*table)[rid[idx]];
}
void emplace_back(const uint32_t& v) {
rid.emplace_back(v);
}
};
template<class ...Types2>
auto bind(TableInfo<Types2...>* table2) {
return lineage_t(this, table2);
}
template <size_t j = 0> template <size_t j = 0>
typename std::enable_if<j == sizeof...(Types) - 1, void>::type print_impl(const uint32_t& i, const char* __restrict sep = " ") const; typename std::enable_if<j == sizeof...(Types) - 1, void>::type print_impl(const uint32_t& i, const char* __restrict sep = " ") const;
template <size_t j = 0> template <size_t j = 0>
@ -103,12 +181,106 @@ struct TableInfo {
template <size_t ...Idxs> template <size_t ...Idxs>
using getRecordType = typename GetTypes<Idxs...>::type; using getRecordType = typename GetTypes<Idxs...>::type;
TableInfo(const char* name, uint32_t n_cols); TableInfo(const char* name, uint32_t n_cols);
template <int prog = 0>
inline void materialize(const vector_type<uint32_t>& idxs, TableInfo<Types...>* tbl = nullptr) { // inplace materialize
if constexpr(prog == 0) tbl = (tbl == 0 ? this : tbl);
if constexpr (prog == sizeof...(Types)) return;
else {
auto& col = get<prog>(*this);
auto new_col = decays<decltype(col)>{idxs.size};
for(uint32_t i = 0; i < idxs.size; ++i)
new_col[i] = col[idxs[i]];
get<prog>(*tbl) = new_col;
materialize<prog + 1>(idxs, tbl);
}
}
inline TableInfo<Types...>* materialize_copy(const vector_type<uint32_t>& idxs) {
auto tbl = new TableInfo<Types...>(this->name, sizeof...(Types));
materialize<0>(idxs, tbl);
return tbl;
}
template<int ...cols>
inline vector_type<uint32_t>* order_by(vector_type<uint32_t>* ord = nullptr) {
if (!ord) {
ord = new vector_type<uint32_t>(colrefs[0].size);
for (uint32_t i = 0; i < colrefs[0].size; ++i)
(*ord)[i] = i;
}
std::sort(ord->begin(), ord->end(), [this](const uint32_t& lhs, const uint32_t& rhs) {
return
std::forward_as_tuple((cols >= 0 ? get<cols, (cols >= 0)>(*this)[lhs] : -get<cols, (cols >= 0)>(*this)[lhs]) ...)
<
std::forward_as_tuple((cols >= 0 ? get<cols, (cols >= 0)>(*this)[rhs] : -get<cols, (cols >= 0)>(*this)[rhs]) ...);
});
return ord;
}
template <int ...cols>
auto order_by_view () {
return TableView<Types...>(order_by<cols...>(), *this);
}
// Print 2 -- generate printf string first, supports flattening, supports sprintf/printf/fprintf
template <int col, int ...rem_cols, class Fn, class ...__Types>
inline void print2_impl(Fn func, const uint32_t& i, const __Types& ... args) const {
using this_type = typename std::tuple_element<col, tuple_type>::type;
const auto& this_value = get<col>(*this)[i];
const auto& next = [&](auto &v) {
if constexpr (sizeof...(rem_cols) == 0)
func(args..., v);
else
print2_impl<rem_cols...>(func, i, args ..., v);
};
if constexpr (is_vector_type<this_type>)
for (int j = 0; j < this_value.size; ++j)
next(this_value[j]);
else
next(this_value);
}
template <int ...cols>
void print2(const char* __restrict sep = ",", const char* __restrict end = "\n",
const vector_type<uint32_t>* __restrict view = nullptr, FILE* __restrict fp = nullptr) const {
std::string printf_string =
generate_printf_string<typename std::tuple_element<cols, tuple_type>::type ...>(sep, end);
const auto& prt_loop = [&fp, &view, &printf_string, *this](const auto& f) {
if(view)
for (int i = 0; i < view->size; ++i)
print2_impl<cols...>(f, (*view)[i], printf_string.c_str());
else
for (int i = 0; i < colrefs[0].size; ++i)
print2_impl<cols...>(f, i, printf_string.c_str());
};
if (fp)
prt_loop([&fp](auto... args) { fprintf(fp, args...); });
else
prt_loop(printf);
}
template <int ...vals> struct applier {
inline constexpr static void apply(const TableInfo<Types...>& t, const char* __restrict sep = ",", const char* __restrict end = "\n",
const vector_type<uint32_t>* __restrict view = nullptr, FILE* __restrict fp = nullptr)
{ t.template print2<vals ...>(sep, end, view, fp); }};
inline void printall(const char* __restrict sep = ",", const char* __restrict end = "\n",
const vector_type<uint32_t>* __restrict view = nullptr, FILE* __restrict fp = nullptr) {
applyIntegerSequence<sizeof...(Types), applier>::apply(*this, sep, end, view, fp);
}
}; };
template <size_t _Index, class... _Types>
constexpr inline ColRef<std::tuple_element_t<_Index, std::tuple<_Types...>>>& get(const TableInfo<_Types...>& table) noexcept { template<class ...Types>
return *(ColRef<std::tuple_element_t<_Index, std::tuple<_Types...>>> *) & (table.colrefs[_Index]); struct TableView {
} const vector_type<uint32_t>* idxs;
const TableInfo<Types...>& info;
constexpr TableView(const vector_type<uint32_t>* idxs, const TableInfo<Types...>& info) noexcept : idxs(idxs), info(info) {}
void print(const char* __restrict sep, const char* __restrict end) const;
template <size_t j = 0>
typename std::enable_if<j == sizeof...(Types) - 1, void>::type print_impl(const uint32_t& i, const char* __restrict sep = " ") const;
template <size_t j = 0>
typename std::enable_if < j < sizeof...(Types) - 1, void>::type print_impl(const uint32_t& i, const char* __restrict sep = " ") const;
~TableView() {
delete idxs;
}
};
template <class T> template <class T>
constexpr static inline bool is_vector(const ColRef<T>&) { constexpr static inline bool is_vector(const ColRef<T>&) {
@ -118,15 +290,37 @@ template <class T>
constexpr static inline bool is_vector(const vector_type<T>&) { constexpr static inline bool is_vector(const vector_type<T>&) {
return true; return true;
} }
template <class T>
constexpr static inline bool is_vector(const T&) {
return false;
}
template<class ...Types> template<class ...Types>
TableInfo<Types...>::TableInfo(const char* name, uint32_t n_cols) : name(name), n_cols(n_cols) { TableInfo<Types...>::TableInfo(const char* name, uint32_t n_cols) : name(name), n_cols(n_cols) {
this->colrefs = (ColRef<void>*)malloc(sizeof(ColRef<void>) * n_cols); this->colrefs = (ColRef<void>*)malloc(sizeof(ColRef<void>) * n_cols);
} }
template <class ...Types>
template <size_t j>
inline typename std::enable_if<j == sizeof...(Types) - 1, void>::type
TableView<Types ...>::print_impl(const uint32_t& i, const char* __restrict sep) const {
std::cout << (get<j>(*this))[(*idxs)[i]];
}
template<class ...Types>
template<size_t j>
inline typename std::enable_if < j < sizeof...(Types) - 1, void>::type
TableView<Types...>::print_impl(const uint32_t& i, const char* __restrict sep) const
{
std::cout << (get<j>(*this))[(*idxs)[i]] << sep;
print_impl<j + 1>(i, sep);
}
template<class ...Types>
inline void TableView<Types...>::print(const char* __restrict sep, const char* __restrict end) const {
int n_rows = 0;
if (info.colrefs[0].size > 0)
n_rows = info.colrefs[0].size;
for (int i = 0; i < n_rows; ++i) {
print_impl(i);
std::cout << end;
}
}
template <class ...Types> template <class ...Types>
template <size_t j> template <size_t j>
inline typename std::enable_if<j == sizeof...(Types) - 1, void>::type inline typename std::enable_if<j == sizeof...(Types) - 1, void>::type
@ -153,60 +347,60 @@ inline void TableInfo<Types...>::print(const char* __restrict sep, const char* _
std::cout << end; std::cout << end;
} }
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT, template<typename ...> class VT2>
VT<typename types::Coercion<T1, T2>::type> operator -(const VT<T1>& lhs, const VT<T2>& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator -(const VT<T1>& lhs, const VT2<T2>& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] - rhs.container[i]; ret[i] = lhs[i] - rhs[i];
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT>
VT<typename types::Coercion<T1, T2>::type> operator -(const VT<T1>& lhs, const T2& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator -(const VT<T1>& lhs, const T2& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] - rhs; ret[i] = lhs[i] - rhs;
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT, template<typename ...> class VT2>
VT<typename types::Coercion<T1, T2>::type> operator +(const VT<T1>& lhs, const VT<T2>& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator +(const VT<T1>& lhs, const VT2<T2>& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] + rhs.container[i]; ret[i] = lhs[i] + rhs[i];
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT>
VT<typename types::Coercion<T1, T2>::type> operator +(const VT<T1>& lhs, const T2& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator +(const VT<T1>& lhs, const T2& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] + rhs; ret[i] = lhs[i] + rhs;
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT, template<typename ...> class VT2>
VT<typename types::Coercion<T1, T2>::type> operator *(const VT<T1>& lhs, const VT<T2>& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator *(const VT<T1>& lhs, const VT2<T2>& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] * rhs.container[i]; ret[i] = lhs[i] * rhs[i];
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT>
VT<typename types::Coercion<T1, T2>::type> operator *(const VT<T1>& lhs, const T2& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator *(const VT<T1>& lhs, const T2& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] * rhs; ret[i] = lhs[i] * rhs;
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT, template<typename ...> class VT2>
VT<typename types::Coercion<T1, T2>::type> operator /(const VT<T1>& lhs, const VT<T2>& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator /(const VT<T1>& lhs, const VT2<T2>& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] / rhs.container[i]; ret[i] = lhs[i] / rhs[i];
return ret; return ret;
} }
template <class T1, class T2, template<typename ...> class VT> template <class T1, class T2, template<typename ...> class VT>
VT<typename types::Coercion<T1, T2>::type> operator /(const VT<T1>& lhs, const T2& rhs) { decayed_t<VT, typename types::Coercion<T1, T2>::type> operator /(const VT<T1>& lhs, const T2& rhs) {
auto ret = VT<typename types::Coercion<T1, T2>::type>(lhs.size, ""); auto ret = decayed_t<VT, typename types::Coercion<T1, T2>::type>(lhs.size, "");
for (int i = 0; i < lhs.size; ++i) for (int i = 0; i < lhs.size; ++i)
ret.container[i] = lhs.container[i] / rhs; ret[i] = lhs[i] / rhs;
return ret; return ret;
} }
@ -214,17 +408,24 @@ template <class ...Types>
void print(const TableInfo<Types...>& v, const char* delimiter = " ", const char* endline = "\n") { void print(const TableInfo<Types...>& v, const char* delimiter = " ", const char* endline = "\n") {
v.print(delimiter, endline); v.print(delimiter, endline);
} }
template <class ...Types>
void print(const TableView<Types...>& v, const char* delimiter = " ", const char* endline = "\n") {
v.print(delimiter, endline);
}
template <class T> template <class T>
void print(const T& v, const char* delimiter = " ") { void print(const T& v, const char* delimiter = " ") {
printf(types::printf_str[types::Types<T>::getType()], v); std::cout<< v;
// printf(types::printf_str[types::Types<T>::getType()], v);
} }
template <class T> template <class T>
void inline print_impl(const T& v, const char* delimiter, const char* endline) { void inline print_impl(const T& v, const char* delimiter, const char* endline) {
for (const auto& vi : v) { for (const auto& vi : v) {
print(vi); print(vi);
printf("%s", delimiter); std::cout << delimiter;
// printf("%s", delimiter);
} }
printf("%s", endline); std::cout << endline;
//printf("%s", endline);
} }
template <class T, template<typename> class VT> template <class T, template<typename> class VT>

@ -1,11 +1,6 @@
#include "types.h" #include "types.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
//template<typename T>
//inline static constexpr void types::Types<T>::print(T& v)
//{
// std::cout << v;
//}
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>
namespace types { namespace types {

@ -9,25 +9,33 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define __restrict__ __restrict #define __restrict__ __restrict
#endif #endif
template <class T>
constexpr static inline bool is_vector(const T&) {
return false;
}
template <class T>
struct is_vector_impl : std::false_type {};
template <class T>
constexpr static bool is_vector_type = is_vector_impl<T>::value;
namespace types { namespace types {
enum Type_t { enum Type_t {
AINT, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, ALONG, ASHORT, ADATE, ATIME, ACHAR, AINT, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, ALONG, ASHORT, ADATE, ATIME, ACHAR,
AUINT, AULONG, AUSHORT, AUCHAR, NONE, ERROR AUINT, AULONG, AUSHORT, AUCHAR, VECTOR, NONE, ERROR
}; };
static constexpr const char* printf_str[] = { "%d ", "%f ", "%s ", "%lf ", "%llf ", "%ld ", "%hi ", "%s ", "%s ", "%c ", static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%llf", "%ld", "%hi", "%s", "%s", "%c",
"%u ", "%lu ", "%hu ", "%hhu ", "NULL " }; "%u", "%lu", "%hu", "%hhu", "Vector<%s>", "NULL", "ERROR" };
// TODO: deal with data/time <=> str/uint conversion // TODO: deal with data/time <=> str/uint conversion
struct date_t { struct date_t {
uint32_t val; uint32_t val;
date_t(const char* d) { date_t(const char* d) {
} }
std::string toString() const; std::string toString() const;
}; };
struct time_t { struct time_t {
uint32_t val; uint32_t val;
time_t(const char* d) { time_t(const char* d) {
} }
std::string toString() const; std::string toString() const;
}; };
@ -51,12 +59,14 @@ namespace types {
f(unsigned short, AUSHORT) \ f(unsigned short, AUSHORT) \
f(unsigned char, AUCHAR) f(unsigned char, AUCHAR)
constexpr static Type_t getType() { inline constexpr static Type_t getType() {
#define TypeConnect(x, y) if(typeid(T) == typeid(x)) return y; else #define TypeConnect(x, y) if constexpr(std::is_same<x, T>::value) return y; else
ConnectTypes(TypeConnect) ConnectTypes(TypeConnect)
if constexpr (is_vector_type<T>)
return VECTOR;
else
return NONE; return NONE;
} }
//static constexpr inline void print(T& v);
}; };
#define ATypeSize(t, at) sizeof(t), #define ATypeSize(t, at) sizeof(t),
static constexpr size_t AType_sizes[] = { ConnectTypes(ATypeSize) 1 }; static constexpr size_t AType_sizes[] = { ConnectTypes(ATypeSize) 1 };
@ -77,13 +87,13 @@ namespace types {
using type = Cond(__Eq(float), float, Cond(__Eq(double), double, long double)); using type = Cond(__Eq(float), float, Cond(__Eq(double), double, long double));
}; };
template<class T> template<class T>
using GetFPType = typename GetFPTypeImpl<T>::type; using GetFPType = typename GetFPTypeImpl<typename std::decay<T>::type>::type;
template<class T> template<class T>
struct GetLongTypeImpl { struct GetLongTypeImpl {
using type = Cond(_U(T), unsigned long long, Cond(Fp(T), long double, long long)); using type = Cond(_U(T), unsigned long long, Cond(Fp(T), long double, long long));
}; };
template<class T> template<class T>
using GetLongType = typename GetLongTypeImpl<T>::type; using GetLongType = typename GetLongTypeImpl<typename std::decay<T>::type>::type;
} }
#define getT(i, t) std::tuple_element_t<i, std::tuple<t...>> #define getT(i, t) std::tuple_element_t<i, std::tuple<t...>>
@ -118,6 +128,65 @@ struct decayS <T<Types...>>{
using type = T<typename std::decay<Types>::type ...>; using type = T<typename std::decay<Types>::type ...>;
}; };
template <class T> template <class T>
using decays = typename decayS<T>::type; using decays = typename decayS<typename std::decay<T>::type>::type;
template <class T>
using decay_inner = typename decayS<T>::type;
template <class, template <class...> class T>
struct instance_of_impl : std::false_type {};
template <class ...T1, template <class ...> class T2>
struct instance_of_impl<T2<T1...>, T2> : std::true_type {};
template <class T1, class T2>
struct same_class_impl : std::false_type {};
template <class ...T1s, class ...T2s, template <class...> class T1>
struct same_class_impl<T1<T1s...>, T1<T2s...>> : std::true_type {};
template <class T1, class T2>
bool same_class = same_class_impl<T1, T2>::value;
template <class T1, template <class...> class T2>
bool instance_of = instance_of_impl<T1, T2>::value;
template <class lT, template <typename ...> class rT>
using transTypes = typename transTypes_s<lT, rT>::type;
template <class lT, class vT, template <vT ...> class rT>
struct transValues_s;
template <class vT, template<class, vT ...> class lT, vT ...T, template<vT ...> class rT>
struct transValues_s<lT<vT, T...>, vT, rT> {
using type = rT<T...>;
};
#include <utility>
template <class vT, int i, template <vT ...> class rT>
using transValues = typename transValues_s<std::make_integer_sequence<vT, i>, vT, rT>::type;
template <int i, template <int ...> class rT>
using applyIntegerSequence = typename transValues_s<std::make_integer_sequence<int, i>, int, rT>::type;
template <template <class ...> class T, class ...Types>
struct decayed_impl{ typedef T<Types...> type;};
template <template <typename ...> class VT, class ...Types>
using decayed_t = typename decayed_impl<VT, Types...>::type;
template <class First = void, class...Rest>
struct get_first_impl {
typedef First first;
constexpr static size_t rest_len = sizeof...(Rest);
typedef get_first_impl<Rest...> rest;
};
template <class ...T>
using get_first = typename get_first_impl<T...>::first;
template <class T>
struct value_type_impl { typedef T type; };
template <template <class...> class VT, class ...V>
struct value_type_impl<VT<V...>> { typedef get_first<V...> type; };
template <class T>
using value_type = typename value_type_impl<T>::type;
template <class ...T>
using get_first = typename get_first_impl<T...>::first;
template <class T>
struct value_type_rec_impl { typedef T type; };
template <template <class...> class VT, class ...V>
struct value_type_rec_impl<VT<V...>> { typedef typename value_type_rec_impl<get_first<int>>::type type; };
template <class T>
using value_type_r = typename value_type_rec_impl<T>::type;
#endif // !_TYPES_H #endif // !_TYPES_H

@ -1,18 +1,16 @@
#pragma once #pragma once
#include <string> #include <string>
#include <ctime> #include <ctime>
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
template<int cnt, int begin = 0, int interval = 1> constexpr static bool cpp_17 = true;
struct const_range { #else
int arr[cnt]; constexpr static bool cpp_17 = false;
constexpr const_range() { #endif
for (int i = begin, n = 0; n < cnt; ++n, i += interval) template <class T>
arr[n] = i; inline const char* str(const T& v) {
} return "";
const int* begin() const { }
return arr; template <>
} inline const char* str(const bool& v) {
const int* end() const { return v ? "true" : "false";
return arr + cnt; }
}
};

@ -1 +1,11 @@
#include "vector_type.hpp" #include "vector_type.hpp"
#include <iostream>
template<typename _Ty>
inline void vector_type<_Ty>::out(uint32_t n, const char* sep) const
{
n = n > size ? size : n;
std::cout << '(';
for (uint32_t i = 0; i < n; ++i)
std::cout << this->operator[](i) << sep;
std::cout << ')';
}

@ -22,7 +22,11 @@
template <typename _Ty> template <typename _Ty>
class vector_type { class vector_type {
public: public:
void inline _copy(vector_type<_Ty>& vt) { typedef vector_type<_Ty> Decayed_t;
void inline _copy(const vector_type<_Ty>& vt) {
// quick init while using malloc
//if (capacity > 0) free(container);
this->size = vt.size; this->size = vt.size;
this->capacity = vt.capacity; this->capacity = vt.capacity;
this->container = (_Ty*)malloc(size * sizeof(_Ty)); this->container = (_Ty*)malloc(size * sizeof(_Ty));
@ -30,6 +34,8 @@ public:
memcpy(container, vt.container, sizeof(_Ty) * size); memcpy(container, vt.container, sizeof(_Ty) * size);
} }
void inline _move(vector_type<_Ty>&& vt) { void inline _move(vector_type<_Ty>&& vt) {
if (capacity > 0) free(container);
this->size = vt.size; this->size = vt.size;
this->capacity = vt.capacity; this->capacity = vt.capacity;
this->container = vt.container; this->container = vt.container;
@ -52,10 +58,10 @@ public:
} }
} }
constexpr vector_type() noexcept : size(0), capacity(0), container(0) {}; constexpr vector_type() noexcept : size(0), capacity(0), container(0) {};
constexpr vector_type(vector_type<_Ty>& vt) noexcept { constexpr vector_type(const vector_type<_Ty>& vt) noexcept : capacity(0) {
_copy(vt); _copy(vt);
} }
constexpr vector_type(vector_type<_Ty>&& vt) noexcept { constexpr vector_type(vector_type<_Ty>&& vt) noexcept : capacity(0) {
_move(std::move(vt)); _move(std::move(vt));
} }
vector_type<_Ty> operator =(const _Ty& vt) { vector_type<_Ty> operator =(const _Ty& vt) {
@ -67,7 +73,7 @@ public:
container[0] = vt; container[0] = vt;
return *this; return *this;
} }
vector_type<_Ty> operator =(vector_type<_Ty>& vt) { vector_type<_Ty> operator =(const vector_type<_Ty>& vt) {
_copy(vt); _copy(vt);
return *this; return *this;
} }
@ -75,6 +81,18 @@ public:
_move(std::move(vt)); _move(std::move(vt));
return *this; return *this;
} }
template <template <class> class VT>
vector_type<_Ty> operator =(const VT<_Ty>& vt) {
if (capacity > 0) free(container);
container = static_cast<_Ty*>(malloc(size * sizeof(_Ty)));
size = vt.size;
capacity = size;
for(uint32_t i = 0; i < size; ++i)
container[i] = vt[i];
return *this;
}
void emplace_back(_Ty _val) { void emplace_back(_Ty _val) {
if (size >= capacity) { // geometric growth if (size >= capacity) { // geometric growth
capacity += 1 + (capacity >> 1); capacity += 1 + (capacity >> 1);
@ -177,6 +195,7 @@ public:
} }
size = this->size + dist; size = this->size + dist;
} }
void out(uint32_t n = 4, const char* sep = " ") const;
~vector_type() { ~vector_type() {
if (capacity > 0) free(container); if (capacity > 0) free(container);
container = 0; size = capacity = 0; container = 0; size = capacity = 0;
@ -248,7 +267,7 @@ public:
} }
} }
constexpr vector_type() : size(0), capacity(0), container(0) {}; constexpr vector_type() : size(0), capacity(0), container(0) {};
void *get(uint32_t i, types::Type_t atype){ void* get(uint32_t i, types::Type_t atype){
return static_cast<void*>(static_cast<char*>(container) + (i * types::AType_sizes[atype])); return static_cast<void*>(static_cast<char*>(container) + (i * types::AType_sizes[atype]));
} }
void operator[](const uint32_t& i) { void operator[](const uint32_t& i) {

@ -17,16 +17,16 @@ INSERT INTO stocks VALUES(14,5)
INSERT INTO stocks VALUES(15,2) INSERT INTO stocks VALUES(15,2)
INSERT INTO stocks VALUES(16,5) INSERT INTO stocks VALUES(16,5)
/*<k> "q1" </k>*/
SELECT max(price-min(timestamp)) FROM stocks SELECT max(price-min(timestamp)) FROM stocks
/*<k> "q1" </k> /*<k> "q2" </k>*/
*/
SELECT max(price-mins(price)) FROM stocks SELECT max(price-mins(price)) FROM stocks
/*
<k> "q2" </k> /*<k> "q3"</k>*/
SELECT price, timestamp FROM stocks where price -timestamp > 1 and not (price*timestamp<100); SELECT price, timestamp FROM stocks where price - timestamp > 1 and not (price*timestamp<100)
<k> "q3"</k>
/*<k> "q4"</k>*/
SELECT max(price-mins(price)) SELECT max(price-mins(price))
FROM stocks FROM stocks
ASSUMING ASC timestamp ASSUMING DESC timestamp
*/

Loading…
Cancel
Save