diff --git a/Makefile b/Makefile index a1b1a13..7eea0e9 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,11 @@ MonetDB_INC = Defines = CC = $(CXX) -xc CXXFLAGS = --std=c++2a -ifeq ($(AQ_DEBUG), 1) - OPTFLAGS = -g3 #-static-libsan -fsanitize=address - LINKFLAGS = -else - OPTFLAGS = -Ofast -DNDEBUG -fno-stack-protector - LINKFLAGS = -flto -s + +ifdef AQ_LINKER + CXX += -fuse-ld=$(AQ_LINKER) endif + SHAREDFLAGS = -shared FPIC = -fPIC _COMPILER = $(shell $(CXX) --version | grep -q clang && echo clang|| echo gcc) @@ -47,7 +45,7 @@ else LIBTOOL = gcc-ar rcs endif endif -LINKFLAGS += $(SEMANTIC_INTERPOSITION) +LINKFLAGS = $(SEMANTIC_INTERPOSITION) ifeq ($(PCH), 1) PCHFLAGS = -include server/pch.hpp @@ -79,10 +77,10 @@ else LIBTOOL = libtool -static -o endif ifneq ($(UNAME_M),arm64) - OPTFLAGS += -march=native + OPTFLAGS = -march=native endif else - OPTFLAGS += -march=native + OPTFLAGS = -march=native MonetDB_LIB += $(AQ_MONETDB_LIB) MonetDB_INC += $(AQ_MONETDB_INC) MonetDB_INC += -I/usr/local/include/monetdb -I/usr/include/monetdb @@ -90,6 +88,15 @@ else MonetDB_LIB += -lmonetdbe -lmonetdbsql -lbat endif + +ifeq ($(AQ_DEBUG), 1) + OPTFLAGS = -g3 #-static-libsan -fsanitize=address +# LINKFLAGS = +else + OPTFLAGS += -Ofast -DNDEBUG -fno-stack-protector + LINKFLAGS += -flto -s +endif + ifeq ($(THREADING),1) LIBAQ_SRC += server/threading.cpp LIBAQ_OBJ += threading.o @@ -133,7 +140,7 @@ pch: $(CXX) -x c++-header server/pch.hpp $(FPIC) $(CXXFLAGS) libaquery: $(CXX) -c $(FPIC) $(PCHFLAGS) $(LIBAQ_SRC) $(OS_SUPPORT) $(CXXFLAGS) &&\ - $(CC) -c server/monetdb_ext.c $(OPTFLAGS) $(MonetDB_INC) &&\ + $(CC) -c $(FPIC) server/monetdb_ext.c $(OPTFLAGS) $(MonetDB_INC) &&\ $(LIBTOOL) libaquery.a $(LIBAQ_OBJ) &&\ $(RANLIB) libaquery.a diff --git a/aquery_config.py b/aquery_config.py index 752d754..6b7a00f 100644 --- a/aquery_config.py +++ b/aquery_config.py @@ -7,7 +7,7 @@ add_path_to_ldpath = True rebuild_backend = False run_backend = True have_hge = False -cygroot = 'c:/msys64/usr/bin' +cygroot = 'c:/mingw64/usr/bin' msbuildroot = '' os_platform = 'unknown' build_driver = 'Auto' @@ -49,9 +49,9 @@ def init_config(): os_platform = 'cygwin' # deal with msys dependencies: if os_platform == 'win': - add_dll_dir(cygroot) add_dll_dir(os.path.abspath('./msc-plugin')) add_dll_dir(os.path.abspath('./deps')) + add_dll_dir(cygroot) if build_driver == 'Auto': try: import vswhere @@ -72,6 +72,8 @@ def init_config(): print("Warning: Readline module not present") if build_driver == 'Auto': build_driver = 'Makefile' + if os_platform == 'linux': + os.environ['PATH'] = os.environ['PATH'] + os.pathsep + '/usr/lib' if os_platform == 'cygwin': add_dll_dir('./lib') __config_initialized__ = True diff --git a/aquery_parser/parser.py b/aquery_parser/parser.py index 0cf9eec..fb2985d 100644 --- a/aquery_parser/parser.py +++ b/aquery_parser/parser.py @@ -591,24 +591,12 @@ def parser(literal_string, ident): drop_trigger = (keyword("drop trigger") + var_name("name")) ("drop_trigger") - cache_options = Optional(( - keyword("options").suppress() - + LB - + Dict(delimited_list(Group( - literal_string / (lambda tokens: tokens[0]["literal"]) - + Optional(EQ) - + var_name - ))) - + RB - )("options")) - create_cache = ( keyword("cache").suppress() + Optional(flag("lazy")) + TABLE - + var_name("name") - + cache_options - + Optional(AS + query("query")) + + FROM + + var_name("source") # AQuery, MonetDB, DuckDB ... )("cache") drop_table = ( diff --git a/build.py b/build.py index 11c08fb..9a0222e 100644 --- a/build.py +++ b/build.py @@ -122,23 +122,23 @@ class build_manager: os.environ['AQ_DEBUG'] = ('0' if mgr.OptimizationLv != '0' else '1') def libaquery_a(self): - self.build_cmd = [['rm', 'libaquery.a'],['make', 'libaquery']] + self.build_cmd = [['rm', 'libaquery.a'],['make', 'libaquery', '-j']] return self.build() def pch(self): - self.build_cmd = [['rm', 'server/pch.hpp.gch'], ['make', 'pch']] + self.build_cmd = [['rm', 'server/pch.hpp.gch'], ['make', 'pch', '-j']] return self.build() def server(self): if self.mgr.StaticLib: - self.build_cmd = [['rm', '*.o'],['rm', 'server.so'], ['make', 'server_uselib']] + self.build_cmd = [['rm', '*.o'],['rm', 'server.so'], ['make', 'server_uselib', '-j']] else: - self.build_cmd = [['rm', 'server.so'], ['make', 'server.so']] + self.build_cmd = [['rm', 'server.so'], ['make', 'server.so', '-j']] return self.build() def snippet(self): if self.mgr.StaticLib: - self.build_cmd = [['make', 'snippet_uselib']] + self.build_cmd = [['make', 'snippet_uselib', '-j']] else: - self.build_cmd = [['rm', 'dll.so'], ['make', 'snippet']] + self.build_cmd = [['rm', 'dll.so'], ['make', 'snippet', '-j']] return self.build() class MSBuildDriver(DriverBase): diff --git a/common/types.py b/common/types.py index f4d7354..aa72f63 100644 --- a/common/types.py +++ b/common/types.py @@ -4,14 +4,22 @@ from typing import Dict, List from aquery_config import have_hge from common.utils import base62uuid, defval +aquery_types: Dict[str, int] = {} type_table: Dict[str, "Types"] = {} +with open('server/aquery_types.h', 'r') as f: + f.readline() + types = f.read() + import re + types = re.compile(r'(\s|\\)+').sub('', types).split(',') + aquery_types = { t : i for i, t in enumerate(types)} + class Types: def init_any(self): self.name : str = 'Any' self.sqlname : str = 'Int' self.cname : str = 'void*' - self.ctype_name : str = "types::NONE" + self.ctype_name : str = "None" self.null_value = 0 self.priority : int= 0 self.cast_to_dict = dict() @@ -31,7 +39,7 @@ class Types: self.name = name self.cname = defval(cname, name.lower() + '_t') self.sqlname = defval(sqlname, name.upper()) - self.ctype_name = defval(ctype_name, f'types::A{name.upper()}') + self.ctype_name = defval(ctype_name, f'A{name.upper()}') self.null_value = defval(null_value, 0) self.cast_to_dict = defval(cast_to, dict()) self.cast_from_dict = defval(cast_from, dict()) @@ -89,8 +97,8 @@ class TypeCollection: type_table = dict() AnyT = Types(-1) LazyT = Types(240, name = 'Lazy', cname = '', sqlname = '', ctype_name = '') -DateT = Types(200, name = 'DATE', cname = 'types::date_t', sqlname = 'DATE', ctype_name = 'types::ADATE') -TimeT = Types(201, name = 'TIME', cname = 'types::time_t', sqlname = 'TIME', ctype_name = 'types::ATIME') +DateT = Types(200, name = 'DATE', cname = 'types::date_t', sqlname = 'DATE', ctype_name = 'ADATE') +TimeT = Types(201, name = 'TIME', cname = 'types::time_t', sqlname = 'TIME', ctype_name = 'ATIME') TimeStampT = Types(202, name = 'TIMESTAMP', cname = 'types::timestamp_t', sqlname = 'TIMESTAMP', ctype_name = 'ATIMESTAMP') DoubleT = Types(17, name = 'double', cname='double', sqlname = 'DOUBLE', is_fp = True) LDoubleT = Types(18, name = 'long double', cname='long double', sqlname = 'LDOUBLE', is_fp = True) @@ -102,15 +110,15 @@ LongT = Types(4, name = 'int64', sqlname = 'BIGINT', fp_type = DoubleT) BoolT = Types(0, name = 'bool', cname='bool', sqlname = 'BOOL', long_type=LongT, fp_type=FloatT) ByteT = Types(1, name = 'int8', sqlname = 'TINYINT', long_type=LongT, fp_type=FloatT) ShortT = Types(2, name = 'int16', sqlname='SMALLINT', long_type=LongT, fp_type=FloatT) -IntT = Types(3, name = 'int', cname = 'int', long_type=LongT, ctype_name = 'types::AINT32', fp_type=FloatT) +IntT = Types(3, name = 'int', cname = 'int', long_type=LongT, ctype_name = 'AINT32', fp_type=FloatT) ULongT = Types(8, name = 'uint64', sqlname = 'UINT64', fp_type=DoubleT) UIntT = Types(7, name = 'uint32', sqlname = 'UINT32', long_type=ULongT, fp_type=FloatT) UShortT = Types(6, name = 'uint16', sqlname = 'UINT16', long_type=ULongT, fp_type=FloatT) UByteT = Types(5, name = 'uint8', sqlname = 'UINT8', long_type=ULongT, fp_type=FloatT) -StrT = Types(200, name = 'str', cname = 'string_view', sqlname='TEXT', ctype_name = 'types::ASTR') -TextT = Types(200, name = 'text', cname = 'string_view', sqlname='TEXT', ctype_name = 'types::ASTR') -VarcharT = Types(200, name = 'varchar', cname = 'string_view', sqlname='VARCHAR', ctype_name = 'types::ASTR') -VoidT = Types(200, name = 'void', cname = 'void', sqlname='Null', ctype_name = 'types::None') +StrT = Types(200, name = 'str', cname = 'string_view', sqlname='TEXT', ctype_name = 'ASTR') +TextT = Types(200, name = 'text', cname = 'string_view', sqlname='TEXT', ctype_name = 'ASTR') +VarcharT = Types(200, name = 'varchar', cname = 'string_view', sqlname='VARCHAR', ctype_name = 'ASTR') +VoidT = Types(200, name = 'void', cname = 'void', sqlname='Null', ctype_name = 'None') class VectorT(Types): def __init__(self, inner_type : Types, vector_type:str = 'vector_type'): diff --git a/common/utils.py b/common/utils.py index 5df3037..bd9e3d7 100644 --- a/common/utils.py +++ b/common/utils.py @@ -130,16 +130,21 @@ class _Counter: import re ws = re.compile(r'\s+') -import os +def encode_integral(val : int): + return val.to_bytes(4, 'little').decode('latin-1') +import os def add_dll_dir(dll: str): import sys - if sys.version_info.major >= 3 and sys.version_info.minor >7 and os.name == 'nt': - os.add_dll_directory(dll) - else: - os.environ['PATH'] = os.path.abspath(dll) + os.pathsep + os.environ['PATH'] - + try: + if sys.version_info.major >= 3 and sys.version_info.minor >7 and os.name == 'nt': + os.add_dll_directory(dll) + else: + os.environ['PATH'] = os.path.abspath(dll) + os.pathsep + os.environ['PATH'] + except FileNotFoundError: + print(f"Error: path not found") + nullstream = open(os.devnull, 'w') diff --git a/data/h2o b/data/h2o deleted file mode 120000 index 8c5669e..0000000 --- a/data/h2o +++ /dev/null @@ -1 +0,0 @@ -/Users/bill/Downloads/db-benchmark-master/data \ No newline at end of file diff --git a/docs/paper b/docs/paper index c8d27fe..88d6445 160000 --- a/docs/paper +++ b/docs/paper @@ -1 +1 @@ -Subproject commit c8d27fe131e952ca4a30b0de27ff58b28a9990ad +Subproject commit 88d64456343506aae785a938c295864572fe6c0b diff --git a/engine/ast.py b/engine/ast.py index 30b1f9f..17c400e 100644 --- a/engine/ast.py +++ b/engine/ast.py @@ -1746,13 +1746,35 @@ class user_module_function(OperatorBase): # builtin_operators[name] = self udf.try_init_udf(context) +class cache(ast_node): + name = 'cache' + first_order = name + def init(self, node): + source = node['cache']['source'] + # lazy = node['cache']['lazy'] + lazy = 0 + try: + tbl : TableInfo = self.context.tables_byname[source] + except KeyError: + raise ValueError(f'Cannot find table {source}.') + from common.utils import encode_integral + + tbl.cached = True + schema_string = encode_integral(len(tbl.columns)) + for t in tbl.columns: + schema_string += t.name + '\0' + \ + encode_integral(aquery_types[t.type.ctype_name]) + + from common.utils import send_to_server + send_to_server(f'C{source}\0{"l" if lazy else "e"}\0{schema_string}\0') + def include(objs): import inspect for _, cls in inspect.getmembers(objs): if inspect.isclass(cls) and issubclass(cls, ast_node) and type(cls.first_order) is str: ast_node.types[cls.first_order] = cls - - + + import sys include(sys.modules[__name__]) diff --git a/engine/storage.py b/engine/storage.py index 4ce402e..9d36912 100644 --- a/engine/storage.py +++ b/engine/storage.py @@ -73,6 +73,7 @@ class TableInfo: self.columns : List[ColRef] = [] self.triggers : Set[create_trigger] = set() self.cxt = cxt + self.cached = False # keep track of temp vars self.rec = None self.add_cols(cols) @@ -186,7 +187,7 @@ class Context: self.force_compiled = False self.use_gc = compile_use_gc self.system_state: Optional[PromptState] = state - + self.use_cached_tables = True # self.new() called everytime new query batch is started def get_scan_var(self): @@ -267,9 +268,10 @@ class Context: self.finalize_query() def direct_output(self, limit = -1, sep = ' ', end = '\n'): + from common.utils import encode_integral if type(limit) is not int or limit > 2**32 - 1 or limit < 0: limit = 2**32 - 1 - limit = limit.to_bytes(4, 'little').decode('latin-1') + limit = encode_integral(limit) self.queries.append( 'O' + limit + sep + end) diff --git a/msvs-py/msvs-py.pyproj b/msvs-py/msvs-py.pyproj index 1ccdd88..a6fc940 100644 --- a/msvs-py/msvs-py.pyproj +++ b/msvs-py/msvs-py.pyproj @@ -11,7 +11,7 @@ msvs-py msvs-py False - Global|PythonCore|3.10 + Global|PythonCore|3.9 Standard Python launcher True AQ_DEBUG=1 @@ -32,7 +32,6 @@ - diff --git a/server/DataSource_conn.h b/server/DataSource_conn.h index b1c90e4..b6a51fc 100644 --- a/server/DataSource_conn.h +++ b/server/DataSource_conn.h @@ -44,6 +44,7 @@ struct DataSource { virtual void connect(Context* cxt) = 0; virtual void exec(const char* q) = 0; virtual void* getCol(int col_idx, int type) = 0; + virtual void getDSTable(const char* name, void* tbl) = 0; // virtual long long getFirstElement() = 0; virtual void close() = 0; virtual bool haserror() = 0; diff --git a/server/aquery_types.h b/server/aquery_types.h new file mode 100644 index 0000000..40ff939 --- /dev/null +++ b/server/aquery_types.h @@ -0,0 +1,5 @@ +#define __AQUERY_TYPES__ \ + AINT32, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, AINT64, AINT128, \ + AINT16, ADATE, ATIME, AINT8, AUINT32, AUINT64, AUINT128, \ + AUINT16, AUINT8, ABOOL, VECTOR, ATIMESTAMP, ACHAR, ASV, \ + NONE, ERROR diff --git a/server/duckdb_conn.cpp b/server/duckdb_conn.cpp index 51a973f..319424a 100644 --- a/server/duckdb_conn.cpp +++ b/server/duckdb_conn.cpp @@ -1,6 +1,6 @@ #include "pch_msc.hpp" #include "duckdb_conn.h" -#include "../deps/duckdb.hpp" +#include "duckdb.hpp" #include "libaquery.h" #include "types.h" #include @@ -73,6 +73,10 @@ void* DuckdbServer::getCol(int col_idx, int ty) { } } +void DuckdbServer::getDSTable(const char* name, void* tbl) { + // not implemented. + puts("NOT IMPLEMENTED ERROR: DuckdbServer::getDSTable"); +} bool DuckdbServer::haserror() { if (last_error) { puts(last_error); diff --git a/server/duckdb_conn.h b/server/duckdb_conn.h index c4ca9b9..484ae88 100644 --- a/server/duckdb_conn.h +++ b/server/duckdb_conn.h @@ -6,7 +6,8 @@ struct DuckdbServer : DataSource { explicit DuckdbServer(Context* cxt); void connect(Context* cxt); void exec(const char* q); - void* getCol(int col_idx, int type); + void* getCol(int col_idx, int type) override; + void getDSTable(const char* name, void* tbl) override; long long getFirstElement(); void close(); bool haserror(); diff --git a/server/gc.h b/server/gc.h index e911b44..b5c22a3 100644 --- a/server/gc.h +++ b/server/gc.h @@ -104,6 +104,7 @@ public: } constexpr static void(*_free) (void*) = free; }; + #else class GC { public: diff --git a/server/hasher.h b/server/hasher.h index e907ec1..00eb80a 100644 --- a/server/hasher.h +++ b/server/hasher.h @@ -7,6 +7,7 @@ #include "types.h" // #include "robin_hood.h" #include "unordered_dense.h" + template using aq_map = ankerl::unordered_dense::map; @@ -137,3 +138,66 @@ namespace ankerl::unordered_dense{ struct hash> : public hasher{ }; } +template < + typename ValueType = bool, + int PerfectHashingThreshold = 12 +> +struct PerfectHashTable { + // static int m_PerfectHashingThreshold = 12; + using key_t = std::conditional_t>>; + + int n_cols, n_rows = 0; + // char bits[32]; + ValueType table[1 << PerfectHashingThreshold]; + // PerfectHashTable(int n_cols, char* bits) { + // this->n_cols = n_cols; + // memcpy(this->bits, bits, 32); + // } + // template class VT> + // PerfectHashTable(VT ... args) { + + // } + template class VT> + void construct(VT&... args) { + ((this->n_cols = args.size), ...); + static_assert( + (sizeof...(Types) < PerfectHashingThreshold) && + //(sizeof(Types) + ...) < PerfectHashingThreshold && + (std::is_integral_v && ...), + "Types must be integral and less than 12 wide in total." + ); + // this should be an attrib of VT. + key_t* // this better be automatically determined by Threshould + hash_values = static_cast( + calloc(this->n_cols, sizeof(key_t)) + ); + //new short[this->n_cols] {0}; // use calloc/delete + auto get_hash = [&hash_values](auto& arg, int idx) { + uint32_t i = 0; + if(idx > 0) + for (auto& a : arg) { + hash_values[i] = + (hash_values[i] << arg.stats.bits) + + (a - arg.stats.minima); + ++i; + } + else + for (auto& a : arg) { + hash_values[i] = a - arg.stats.minima; + ++i; + } + }; + int idx = 0; + (get_hash(args, idx++), ...); + for (uint32_t i = 0; i < this->n_cols; ++i) { + this->table[hash_values[i]] = true; + // problem: random memory access + } + // delete[] hash_values; + free(hash_values); + } +}; diff --git a/server/libaquery.h b/server/libaquery.h index 8d3c2f4..d08d130 100644 --- a/server/libaquery.h +++ b/server/libaquery.h @@ -235,6 +235,13 @@ inline _This_Type* AQ_DupObject(_This_Type* __val) { return ret; } +inline char* AQ_DupString(const char* __val) { + auto __len = strlen(__val) + 1; + auto ret = (char*)malloc(__len); + memcpy(ret, __val, __len); + return ret; +} + #ifdef __USE_STD_SEMAPHORE__ #include class A_Semaphore { diff --git a/server/monetdb_conn.cpp b/server/monetdb_conn.cpp index 2e63809..73e9018 100644 --- a/server/monetdb_conn.cpp +++ b/server/monetdb_conn.cpp @@ -267,6 +267,20 @@ long long MonetdbServer::getFirstElement() { return 0; } +void MonetdbServer::getDSTable(const char* name, void* tbl) { + TableInfo *table = static_cast*>(tbl); + void*** cols = static_cast(alloca(table->n_cols * sizeof(void**))); + printf("\tncols: %d\n", table->n_cols); + for (int i = 0; i < table->n_cols; ++i) { + cols[i] = static_cast( + static_cast( + &(table->colrefs[i].container) + ) + ); + } + monetdbe_get_cols(*(void**)(this->server), name, cols, table->n_cols); +} + MonetdbServer::~MonetdbServer(){ close(); } diff --git a/server/monetdb_conn.h b/server/monetdb_conn.h index f85b192..c82323a 100644 --- a/server/monetdb_conn.h +++ b/server/monetdb_conn.h @@ -7,6 +7,7 @@ struct MonetdbServer : DataSource { void connect(Context* cxt) override; void exec(const char* q) override; void *getCol(int col_idx, int) override; + void getDSTable(const char* name, void* tbl) override; long long getFirstElement(); void close() override; bool haserror() override; @@ -24,8 +25,12 @@ struct monetdbe_table_data{ }; extern "C" size_t -monetdbe_get_size(void* dbhdl, const char *table_name); +monetdbe_get_size(void* dbhdl, const char *table_name, void*); extern "C" void* monetdbe_get_col(void* dbhdl, const char *table_name, uint32_t col_id); + +extern "C" void +monetdbe_get_cols(void* dbhdl, const char* table_name, void*** cols, int i); + #endif diff --git a/server/monetdb_ext.c b/server/monetdb_ext.c index ab66fea..89c7441 100644 --- a/server/monetdb_ext.c +++ b/server/monetdb_ext.c @@ -80,6 +80,19 @@ monetdbe_get_size(monetdbe_database dbhdl, const char *table_name) return sz; } +void * +monetdbe_list_fetch(list *l, int pos) +{ + node *n = NULL; + int i; + + for (n = l->h, i=0; n && inext, i++) + ; + if (n) + return n->data; + return NULL; +} + void* monetdbe_get_col(monetdbe_database dbhdl, const char *table_name, uint32_t col_id) { monetdbe_database_internal* hdl = (monetdbe_database_internal*)dbhdl; @@ -95,3 +108,24 @@ monetdbe_get_col(monetdbe_database dbhdl, const char *table_name, uint32_t col_i //mvc_cancel_session(m); return iter.base; } + +void monetdbe_get_cols( + monetdbe_database dbhdl, + const char* table_name, + void*** cols, + int i +) { + monetdbe_database_internal* hdl = (monetdbe_database_internal*)dbhdl; + backend* be = ((backend *)(((monetdbe_database_internal*)dbhdl)->c->sqlcontext)); + mvc *m = be->mvc; + sql_table *t = find_table_or_view_on_scope(m, NULL, "sys", table_name, "CATALOG", false); + if (!i || !t) return; + node *n = t->columns->l->h; + sqlstore* store = m->store; + while(n && i-- > 0) { + BAT *b = store->storage_api.bind_col(m->session->tr, n->data, QUICK); + BATiter iter = bat_iterator(b); + *(cols++) = iter.base; + n = n->next; + } +} diff --git a/server/server.cpp b/server/server.cpp index d74d3b4..57a9164 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -549,6 +549,37 @@ start: } } break; + case 'C': //Caching + { + char* cached_table = n_recvd[i] + 1; + char *lazy = (cached_table + 1); + cached_table = AQ_DupString(cached_table); + while(*lazy++); + // get schema + int* n_cols = reinterpret_cast(lazy + 2); + char* col_schema = reinterpret_cast(n_cols + 1); + TableInfo *tbl = new TableInfo; + tbl->name = cached_table;//AQ_DupString(cached_table); + tbl->n_cols = *n_cols; + + for (int i = 0; i < *n_cols; ++i) { + char* col_name = col_schema; + char* mem_coltype = col_name + 1; + while(*mem_coltype++); + int coltype = *(reinterpret_cast(mem_coltype)); + // + tbl->colrefs[i].name = AQ_DupString(col_name); + tbl->colrefs[i].ty = static_cast(coltype); + } + + server->getDSTable(cached_table, tbl); + // server->exec( ( + // std::string("SELECT * FROM ") + cached_table + std::string(";") + // ).c_str() ); + // server->getCol() + // free(cached_table); + break; + } } } diff --git a/server/table.h b/server/table.h index 644a092..6fadd84 100644 --- a/server/table.h +++ b/server/table.h @@ -21,6 +21,8 @@ template <> class vector_type; #ifdef _MSC_VER +#include +#define __builtin_popcount __popcnt namespace types { enum Type_t; template @@ -54,6 +56,13 @@ std::ostream& operator<<(std::ostream& os, uint8_t& v); std::ostream& operator<<(std::ostream& os, types::date_t& v); std::ostream& operator<<(std::ostream& os, types::time_t& v); std::ostream& operator<<(std::ostream& os, types::timestamp_t& v); + +template +struct TableStats { + T minima = 0; + unsigned char bits = 255; +}; + template class ColView; template @@ -63,6 +72,23 @@ public: typedef ColRef<_Ty> Decayed_t; const char* name; types::Type_t ty = types::Type_t::ERROR; + TableStats<_Ty> stats; + bool populate_stats() { + if constexpr (std::is_integral_v<_Ty>) { + if (stats.bits <= 128) return true; + stats.minima = std::numeric_limits<_Ty>::max(); + _Ty maxima = std::numeric_limits<_Ty>::min(); + for (uint32_t i = 0; i < this->size; ++i) { + if (this->container[i] < stats.minima) + stats.minima = this->container[i]; + else if (this->container[i] > maxima) + maxima = this->container[i]; + } + stats.bits = ceil(log2(maxima - stats.minima)); + return true; + } + return false; + } ColRef(const ColRef<_Ty>& vt) : vector_type<_Ty>(vt) {} ColRef(ColRef<_Ty>&& vt) : vector_type<_Ty>(std::move(vt)) {} ColRef() : vector_type<_Ty>(0), name("") {} diff --git a/server/types.h b/server/types.h index 921eabd..b51e992 100644 --- a/server/types.h +++ b/server/types.h @@ -6,6 +6,7 @@ #include #include #include +#include "aquery_types.h" using std::size_t; #if defined(__SIZEOF_INT128__) and not defined(_WIN32) @@ -68,8 +69,7 @@ constexpr bool aqis_same = aqis_same_impl::value; namespace types { enum Type_t { - AINT32, AFLOAT, ASTR, ADOUBLE, ALDOUBLE, AINT64, AINT128, AINT16, ADATE, ATIME, AINT8, - AUINT32, AUINT64, AUINT128, AUINT16, AUINT8, ABOOL, VECTOR, ATIMESTAMP, ACHAR, ASV, NONE, ERROR + __AQUERY_TYPES__ }; static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%Lf", "%ld", "%s", "%hi", "%s", "%s", "%hhd", "%u", "%lu", "%s", "%hu", "%hhu", "%s", "Vector<%s>", "%s", "%c", "%s", "NULL", "ERROR" };