diff --git a/Makefile b/Makefile index ee54d9d..10ef0a7 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,15 @@ else UNAME_S = $(shell uname -s) UNAME_M = $(shell uname -m) NULL_DEVICE = /dev/null + MonetDB_LIB = + ifeq ($(UNAME_S),Darwin) + MonetDB_LIB += -L`brew --prefix monetdb`/lib + ifneq ($(UNAME_M),arm64) + OPTFLAGS += -march=native + endif + else + OPTFLAGS += -march=native + endif MonetDB_LIB += -I/usr/local/include/monetdb -I/usr/include/monetdb -lmonetdbe endif diff --git a/reconstruct/ast.py b/reconstruct/ast.py index 1a76a92..d94b6ca 100644 --- a/reconstruct/ast.py +++ b/reconstruct/ast.py @@ -91,12 +91,15 @@ class projection(ast_node): def consume(self, node): # deal with projections - if 'into' not in node: - out_table_name = 'out_'+base62uuid(6) - else: + out_table_varname = 'out_'+base62uuid(6) + if 'into' in node: out_table_name = node['into'] + else: + out_table_name = out_table_varname self.out_table : TableInfo = TableInfo(out_table_name, [], self.context) + self.out_table.contextname_cpp = out_table_varname + cols = [] self.col_ext : Set[ColRef]= set() col_exprs : List[Tuple[str, Types]] = [] @@ -117,24 +120,27 @@ class projection(ast_node): name = proj_expr.sql compound = True # compound column proj_expr.cols_mentioned = self.datasource.rec + alias = '' + if 'name' in proj: # renaming column by AS keyword + alias = proj['name'] + if not proj_expr.is_special: y = lambda x:x name = eval('f\'' + name + '\'') if name not in self.var_table: self.var_table[name] = len(col_exprs) proj_map[i] = [this_type, len(col_exprs), proj_expr] - col_exprs.append((name, proj_expr.type)) + col_expr = name + ' AS ' + alias if alias else name + if alias: + self.var_table[alias] = len(col_exprs) + col_exprs.append((col_expr, proj_expr.type)) else: self.context.headers.add('"./server/aggregations.h"') if self.datasource.rec is not None: self.col_ext = self.col_ext.union(self.datasource.rec) proj_map[i] = [this_type, proj_expr.sql, proj_expr] - if 'name' in proj: # renaming column by AS keyword - name += ' AS ' + proj['name'] - if not proj_expr.is_special: - self.var_table[proj['name']] = len(col_exprs) - - disp_name = get_legal_name(name) + + disp_name = get_legal_name(alias if alias else name) elif type(proj) is str: col = self.datasource.get_col(proj) @@ -207,7 +213,6 @@ class projection(ast_node): self.context.emitc(f'auto {vname} = ColRef<{typenames[idx].cname}>({length_name}, server->getCol({idx}));') vid2cname[idx] = vname # Create table into context - self.outtable_name = self.out_table.table_name out_typenames = [None] * len(proj_map) for key, val in proj_map.items(): @@ -232,9 +237,12 @@ class projection(ast_node): self.datasource.all_cols.difference(self.group_node.refs)) ): out_typenames[key] = f'ColRef<{out_typenames[key]}>' - + + outtable_col_nameslist = ', '.join([f'"{c.name}"' for c in self.out_table.columns]) + self.outtable_col_names = 'names_' + base62uuid(4) + self.context.emitc(f'const char* {self.outtable_col_names}[] = {{{outtable_col_nameslist}}};') # out_typenames = [v[0].cname for v in proj_map.values()] - self.context.emitc(f'auto {self.outtable_name} = new TableInfo<{",".join(out_typenames)}>("{self.outtable_name}");') + self.context.emitc(f'auto {self.out_table.contextname_cpp} = new TableInfo<{",".join(out_typenames)}>("{self.out_table.table_name}", {self.outtable_col_names});') # TODO: Inject custom group by code here and flag them in proj_map # Type of UDFs? Complex UDFs, ones with static vars? if self.group_node is not None and self.group_node.use_sp_gb: @@ -243,20 +251,20 @@ class projection(ast_node): for key, val in proj_map.items(): col_name = 'col_' + base62uuid(6) - self.context.emitc(f'decltype(auto) {col_name} = {self.outtable_name}->get_col<{key}>();') + self.context.emitc(f'decltype(auto) {col_name} = {self.out_table.contextname_cpp}->get_col<{key}>();') gb_cexprs.append((col_name, val[2])) self.group_node.finalize(gb_cexprs, gb_vartable) else: for i, (key, val) in enumerate(proj_map.items()): if type(val[1]) is int: self.context.emitc( - f'{self.outtable_name}->get_col<{key}>().initfrom({vid2cname[val[1]]}, "{cols[i].name}");' + f'{self.out_table.contextname_cpp}->get_col<{key}>().initfrom({vid2cname[val[1]]}, "{cols[i].name}");' ) else: # for funcs evaluate f_i(x, ...) - self.context.emitc(f'{self.outtable_name}->get_col<{key}>() = {val[1]};') + self.context.emitc(f'{self.out_table.contextname_cpp}->get_col<{key}>() = {val[1]};') # print out col_is - self.context.emitc(f'print(*{self.outtable_name});') + self.context.emitc(f'print(*{self.out_table.contextname_cpp});') if self.outfile: self.outfile.finalize() @@ -756,7 +764,7 @@ class outfile(ast_node): sep = ',' if 'term' not in self.node else self.node['term']['literal'] file_pointer = 'fp_' + base62uuid(6) self.addc(f'FILE* {file_pointer} = fopen("{filename}", "w");') - self.addc(f'{self.parent.outtable_name}->printall("{sep}", "\\n", nullptr, {file_pointer});') + self.addc(f'{self.parent.out_table.contextname_cpp}->printall("{sep}", "\\n", nullptr, {file_pointer});') self.addc(f'fclose({file_pointer});') self.context.ccode += self.ccode diff --git a/reconstruct/storage.py b/reconstruct/storage.py index 8aa6aed..7846817 100644 --- a/reconstruct/storage.py +++ b/reconstruct/storage.py @@ -32,7 +32,8 @@ class ColRef: class TableInfo: def __init__(self, table_name, cols, cxt:'Context'): # statics - self.table_name : str= table_name + self.table_name : str = table_name + self.contextname_cpp : str = '' self.alias : Set[str] = set([table_name]) self.columns_byname : Dict[str, ColRef] = dict() # column_name, type self.columns : List[ColRef] = [] diff --git a/server/table.h b/server/table.h index 639d761..5bf1341 100644 --- a/server/table.h +++ b/server/table.h @@ -260,7 +260,7 @@ struct TableInfo { template using getRecordType = typename GetTypes::type; TableInfo(const char* name, uint32_t n_cols); - TableInfo(const char* name = ""); + TableInfo(const char* name = "", const char **col_names = nullptr); template inline void materialize(const vector_type& idxs, TableInfo* tbl = nullptr) { // inplace materialize if constexpr(prog == 0) tbl = (tbl == 0 ? this : tbl); @@ -319,8 +319,8 @@ struct TableInfo { std::string get_header_string(const char* __restrict sep, const char* __restrict end) const{ std::string header_string = std::string(); for (int i = 0; i < sizeof...(Types); ++i) - header_string += std::string(this->colrefs[i].name) + sep; - const size_t l_sep = strlen(sep); + header_string += std::string(this->colrefs[i].name) + sep + '|' + sep; + const size_t l_sep = strlen(sep) + 1; if (header_string.size() - l_sep >= 0) header_string.resize(header_string.size() - l_sep); header_string += end + std::string(header_string.size(), '=') + end; @@ -420,10 +420,10 @@ TableInfo::TableInfo(const char* name, uint32_t n_cols) : name(name), } } template -TableInfo::TableInfo(const char* name) : name(name), n_cols(sizeof...(Types)) { +TableInfo::TableInfo(const char* name, const char** col_names) : name(name), n_cols(sizeof...(Types)) { this->colrefs = (ColRef*)malloc(sizeof(ColRef) * this->n_cols); for (uint32_t i = 0; i < n_cols; ++i) { - this->colrefs[i].init(); + this->colrefs[i].init(col_names? col_names[i] : ""); } } template