From 780a60fa5d79d9b8022b648dc6ab1f768405afa2 Mon Sep 17 00:00:00 2001 From: Bill Date: Sun, 28 Aug 2022 19:39:18 +0800 Subject: [PATCH] restructure --- Dockerfile | 24 +++++++ Makefile | 26 ++++++-- README.md | 49 ++++++++------ aquery_config.py | 2 +- aquery_parser/sql_parser.py | 7 +- ..._instructions.md => build_instructions.txt | 0 engine/types.py | 33 +++++++++- prompt.py | 16 +++-- reconstruct/ast.py | 65 +++++++++++++++++-- reconstruct/storage.py | 17 +++-- requirements.txt | 2 +- server/libaquery.h | 3 +- server/server.cpp | 58 ++++++++++++++--- server/threading.cpp | 15 +++++ server/threading.h | 2 + test.aquery | 10 +++ tests/funcs.a | 12 +--- tests/joins.a | 4 +- tests/moving_avg.a | 2 +- tests/q1.sql | 2 +- tests/strings.a | 2 +- tests/udf3.a | 2 +- 22 files changed, 279 insertions(+), 74 deletions(-) create mode 100644 Dockerfile rename build_instructions.md => build_instructions.txt (100%) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d463363 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:latest + +RUN cp /bin/bash /bin/sh + +RUN apt update && apt install -y wget + +RUN export OS_VER=`cat /etc/os-release | grep VERSION_CODENAME` &&\ + export OS_VER=${OS_VER#*=} &&\ + printf "deb https://dev.monetdb.org/downloads/deb/ "${OS_VER}" monetdb \ndeb-src https://dev.monetdb.org/downloads/deb/ "${OS_VER}" monetdb\n">/etc/apt/sources.list.d/monetdb.list + +RUN wget --output-document=/etc/apt/trusted.gpg.d/monetdb.gpg https://dev.monetdb.org/downloads/MonetDB-GPG-KEY.gpg + +RUN apt update && apt install -y python3 python3-pip clang-14 libmonetdbe-dev git + +RUN git clone https://github.com/sunyinqi0508/AQuery2 + +RUN python3 -m pip install -r AQuery2/requirements.txt + +ENV IS_DOCKER_IMAGE=1 CXX=clang-14 + +CMD cd AQuery2 && python3 prompt.py + + + diff --git a/Makefile b/Makefile index ff7b6e3..d8af5bd 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,29 @@ OS_SUPPORT = MonetDB_LIB = Threading = +CXXFLAGS = --std=c++1z +OPTFLAGS = -O3 -flto -march=native +SHAREDFLAGS = -shared -fPIC +ifeq ($(PCH), 1) +PCHFLAGS = -include server/aggregations.h +else +PCHFLAGS = +endif ifeq ($(OS),Windows_NT) + NULL_DEVICE = NUL OS_SUPPORT += server/winhelper.cpp MonetDB_LIB += -Imonetdb/msvc msc-plugin/monetdbe.dll else + NULL_DEVICE = /dev/null MonetDB_LIB += -I/usr/local/include/monetdb -I/usr/include/monetdb -lmonetdbe endif ifeq ($(THREADING),1) Threading += server/threading.cpp -DTHREADING endif - +pch: + $(CXX) -x c++-header server/aggregations.h -o server/aggregations.h.pch info: $(info $(OS_SUPPORT)) $(info $(OS)) @@ -20,11 +31,16 @@ info: $(info "test") $(info $(CXX)) server.bin: - $(CXX) server/server.cpp server/io.cpp server/table.cpp $(OS_SUPPORT) $(Threading) -flto --std=c++1z -O3 -march=native -o server.bin + $(CXX) server/server.cpp server/io.cpp server/table.cpp $(OS_SUPPORT) $(Threading) $(OPTFLAGS) $(CXXFLAGS) -o server.bin server.so: # $(CXX) server/server.cpp server/monetdb_conn.cpp -fPIC -shared $(OS_SUPPORT) monetdb/msvc/monetdbe.dll --std=c++1z -O3 -march=native -o server.so -I./monetdb/msvc - $(CXX) -shared -fPIC -flto server/server.cpp server/io.cpp server/table.cpp $(OS_SUPPORT) server/monetdb_conn.cpp $(Threading) $(MonetDB_LIB) --std=c++1z -o server.so -O3 + $(CXX) $(SHAREDFLAGS) server/server.cpp server/io.cpp server/table.cpp $(OS_SUPPORT) server/monetdb_conn.cpp $(Threading) $(MonetDB_LIB) $(OPTFLAGS) $(CXXFLAGS) -o server.so snippet: - $(CXX) -shared -fPIC -flto --std=c++1z -include server/aggregations.h out.cpp server/monetdb_conn.cpp server/table.cpp server/io.cpp $(MonetDB_LIB) -O3 -march=native -o dll.so + $(CXX) $(SHAREDFLAGS) $(PCHFLAGS) out.cpp server/monetdb_conn.cpp server/table.cpp server/io.cpp $(MonetDB_LIB) $(OPTFLAGS) $(CXXFLAGS) -o dll.so +docker: + docker build -t aquery . + clean: - rm *.shm -rf + rm *.shm *.o dll.so server.so server.bin -rf 2> $(NULL_DEVICE) || true + + diff --git a/README.md b/README.md index 47ecdaa..1497a06 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# AQuery++ DB +# AQuery++ Database ## Introduction AQuery++ Database is a cross-platform, In-Memory Column-Store Database that incorporates compiled query execution. @@ -12,40 +12,51 @@ AQuery++ Database is a cross-platform, In-Memory Column-Store Database that inco - AQuery++ supports different execution engines thanks to the decoupled compiler structure. - AQuery Execution Engine: executes query by compiling the query plan to C++ code. Doesn't support joins and udf functions. - Hybrid Execution Engine: decouples the query into two parts. The sql-compliant part is executed by an Embedded version of Monetdb and everything else is executed by a post-process module which is generated by AQuery++ Compiler in C++ and then compiled and executed. -- K9 Execution Engine (discontinued). +- K9 Execution Engine: (discontinued). ## Roadmap - [x] SQL Parser -> AQuery Parser (Front End) -- [ ] AQuery-C++ Compiler (Back End) +- [x] AQuery-C++ Compiler (Back End) - [x] Schema and Data Model - [x] Data acquisition/output from/to csv file - - [x] Single table queries - - [x] Projections and Single Table Aggregations - - [x] Group by Aggregations - - [x] Filters - - [x] Order by - - [x] Assumption - - [x] Flatten - - [x] Multi-table - - [x] Join +- [ ] Execution Engine + - [x] Projections and single-group Aggregations + - [x] Group by Aggregations + - [x] Filters + - [x] Order by + - [x] Assumption + - [x] Flatten + - [x] UDFs (Hybrid Engine only) + - [ ] User Module + - [ ] Triggers + - [x] Join (Hybrid Engine only) - [ ] Subqueries -- [ ] -> Optimizing Compiler +- [ ] Query Optimization + - [x] Selection/Order by push-down + - [ ] Join Optimization ## TODO: - [ ] User Module load syntax parsing (fn definition/registration) - [ ] User Module test - [ ] Interval based triggers +- [ ] Bug fixes: type deduction misaligned in Hybrid Engine +- [ ] Limitation: putting ColRefs back to monetdb. - [ ] C++ Meta-Programming: Eliminate template recursions as much as possible. -- [ ] IPC: Better ways to communicate between Interpreter (Python) and Executer (C++). - - [ ] Sockets? stdin/stdout capture? +# Installation ## Requirements -Recent version of Linux, Windows or MacOS, with recent C++ compiler that has C++17 (1z) support. -- GCC: 9.0 or above (g++ 7.x, 8.x fail to handle variadic template expansion due to compiler bug) -- Clang: 6.0 or above (Recommended) -- MSVC: 2019 or later +1. Recent version of Linux, Windows or MacOS, with recent C++ compiler that has C++17 (1z) support. + - GCC: 9.0 or above (g++ 7.x, 8.x fail to handle variadic template expansion due to a compiler bug) + - Clang: 5.0 or above (Recommended) + - MSVC: 2017 or later +2. Monetdb for Hybrid Engine + - On windows, the required libraries and headers are already included in the repo. + - On Linux, see [Monetdb Easy Setup](https://www.monetdb.org/easy-setup/) for instructions. + - On MacOS, Monetdb can be easily installed in homebrew `brew install monetdb`. + +3. Python 3.6 or above and install required packages in requirements.txt by `python3 -m pip install -r requirements.txt` ## Usage `python3 prompt.py` will launch the interactive command prompt. The server binary will be autometically rebuilt and started. #### Commands: diff --git a/aquery_config.py b/aquery_config.py index 6b5f320..462232f 100644 --- a/aquery_config.py +++ b/aquery_config.py @@ -1,7 +1,7 @@ # put environment specific configuration here ## GLOBAL CONFIGURATION FLAGS -version_string = '0.3.3a' +version_string = '0.4.0a' add_path_to_ldpath = True rebuild_backend = True run_backend = True diff --git a/aquery_parser/sql_parser.py b/aquery_parser/sql_parser.py index 814305f..a531e7f 100644 --- a/aquery_parser/sql_parser.py +++ b/aquery_parser/sql_parser.py @@ -650,7 +650,7 @@ def parser(literal_string, ident, sqlserver=False): ) / to_json_call load_data = ( - keyword("data").suppress() + keyword("data") ("file_type") + keyword("infile")("loc") + literal_string ("file") + INTO @@ -680,7 +680,7 @@ def parser(literal_string, ident, sqlserver=False): ) load_module = ( - keyword("module").suppress() + keyword("module") ("file_type") + FROM + literal_string ("file") + Optional( @@ -696,12 +696,11 @@ def parser(literal_string, ident, sqlserver=False): ) load = ( - keyword("load")("op") + keyword("load") + (load_data | load_module) ) ("load") - sql_stmts = delimited_list( ( query | (insert | update | delete | load) diff --git a/build_instructions.md b/build_instructions.txt similarity index 100% rename from build_instructions.md rename to build_instructions.txt diff --git a/engine/types.py b/engine/types.py index 921f966..cbc0933 100644 --- a/engine/types.py +++ b/engine/types.py @@ -62,6 +62,13 @@ class Types: return self.sqlname def __str__(self) -> str: return self.sqlname + + @staticmethod + def decode(aquery_type : str, vector_type:str = 'ColRef') -> "Types": + if (aquery_type.startswith('vec')): + return VectorT(Types.decode(aquery_type[3:]), vector_type) + return type_table[aquery_type] + class TypeCollection: def __init__(self, sz, deftype, fptype = None, utype = None, *, collection = None) -> None: self.size = sz @@ -95,6 +102,28 @@ UIntT = Types(7, name = 'uint32', sqlname = 'UINT32', long_type=ULongT, fp_type= 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 = 'const char*', sqlname='VARCHAR', ctype_name = 'types::STRING') +VoidT = Types(200, name = 'void', cname = 'void', sqlname='Null', ctype_name = 'types::None') + +class VectorT(Types): + def __init__(self, inner_type : Types, vector_type:str = 'ColRef'): + self.inner_type = inner_type + self.vector_type = vector_type + + @property + def name(self) -> str: + return f'{self.vector_type}<{self.inner_type.name}>' + @property + def sqlname(self) -> str: + return 'BINARY' + @property + def cname(self) -> str: + return self.name + @property + def fp_type(self) -> Types: + return VectorT(self.inner_type.fp_type, self.vector_type) + @property + def long_type(self): + return VectorT(self.inner_type.long_type, self.vector_type) def _ty_make_dict(fn : str, *ty : Types): @@ -265,6 +294,8 @@ builtin_unary_arith = _op_make_dict(opneg) builtin_unary_special = _op_make_dict(spnull) builtin_cstdlib = _op_make_dict(fnsqrt, fnlog, fnsin, fncos, fntan, fnpow) builtin_func = _op_make_dict(fnmax, fnmin, fnsum, fnavg, fnmaxs, fnmins, fnsums, fnavgs, fncnt) +user_module_func = {} builtin_operators : Dict[str, OperatorBase] = {**builtin_binary_arith, **builtin_binary_logical, - **builtin_unary_arith, **builtin_unary_logical, **builtin_unary_special, **builtin_func, **builtin_cstdlib} + **builtin_unary_arith, **builtin_unary_logical, **builtin_unary_special, **builtin_func, **builtin_cstdlib, + **user_module_func} \ No newline at end of file diff --git a/prompt.py b/prompt.py index d383c9c..bf765ce 100644 --- a/prompt.py +++ b/prompt.py @@ -85,7 +85,6 @@ if __name__ == '__main__': import os from dataclasses import dataclass import enum -from tabnanny import check import time # import dbconn import re @@ -317,7 +316,7 @@ def save(q:str, cxt: xengine.Context): savefile('udf', 'udf', '.hpp') savefile('sql', 'sql') -def main(running = lambda:True, next = input, state = None): +def prompt(running = lambda:True, next = input, state = None): if state is None: state = init_prompt() q = '' @@ -442,9 +441,12 @@ def main(running = lambda:True, next = input, state = None): if trimed[0].startswith('f'): fn = 'stock.a' if len(trimed) <= 1 or len(trimed[1]) == 0 \ else trimed[1] - - with open(fn, 'r') as file: - contents = file.read()#.lower() + try: + with open(fn, 'r') as file: + contents = file.read()#.lower() + except FileNotFoundError: + with open('tests/' + fn, 'r') as file: + contents = file.read() state.stmts = parser.parse(contents) continue state.stmts = parser.parse(q) @@ -488,7 +490,7 @@ if __name__ == '__main__': while(not ws.sub('', nextcmd) or nextcmd.strip().startswith('#')): nextcmd = file.readline() cnt = _Counter(1) - main(lambda : cnt.inc(-1) > 0, lambda:nextcmd.strip(), state) + prompt(lambda : cnt.inc(-1) > 0, lambda:nextcmd.strip(), state) nextcmd = file.readline() if check_param(['-p', '--parse']): @@ -505,5 +507,5 @@ if __name__ == '__main__': elif any([s in nextcmd for s in thread_string]): server_mode = RunType.Threaded - main(state=state) + prompt(state=state) diff --git a/reconstruct/ast.py b/reconstruct/ast.py index 0061ec7..2eedc2b 100644 --- a/reconstruct/ast.py +++ b/reconstruct/ast.py @@ -601,18 +601,62 @@ class insert(ast_node): pass self.sql += ', '.join(list_values) + ')' - + class load(ast_node): name="load" first_order = name - def init(self, _): - if self.context.dialect == 'MonetDB': + def init(self, node): + self.module = False + if node['load']['file_type'] == 'module': + self.produce = self.produce_module + self.module = True + elif self.context.dialect == 'MonetDB': self.produce = self.produce_monetdb - else: + else: self.produce = self.produce_aq if self.parent is None: self.context.sql_begin() - + + def produce_module(self, node): + # create command for exec engine -> done + # create c++ stub + # create dummy udf obj for parsing + # def decode_type(ty : str) -> str: + # ret = '' + # back = '' + # while(ty.startswith('vec')): + # ret += 'ColRef<' + # back += '>' + # ty = ty[3:] + # ret += ty + # return ret + back + node = node['load'] + file = node['file']['literal'] + self.context.queries.append(f'M{file}') + self.module_name = file + self.functions = {} + if 'funcs' in node: + for f in enlist(node['funcs']): + fname = f['fname'] + self.context.queries.append(f'F{fname}') + ret_type = VoidT + if 'ret_type' in f: + ret_type = Types.decode(f['ret_type']) + nargs = 0 + arglist = '' + if 'var' in f: + arglist = [] + for v in enlist(f['var']): + arglist.append(f'{Types.decode(v["type"]).cname} {v["arg"]}') + nargs = len(arglist) + arglist = ', '.join(arglist) + # create c++ stub + cpp_stub = f'{ret_type.cname} (*{fname})({arglist});' + self.context.module_stubs += cpp_stub + '\n' + self.context.module_map[fname] = cpp_stub + #registration for parser + self.functions[fname] = user_module_function(fname, nargs, ret_type) + def produce_aq(self, node): node = node['load'] s1 = 'LOAD DATA INFILE ' @@ -710,7 +754,11 @@ class udf(ast_node): self.var_table = {} self.args = [] if self.context.udf is None: - self.context.udf = Context.udf_head + self.context.udf = ( + Context.udf_head + + self.context.module_stubs + + self.context.get_init_func() + ) self.context.headers.add('\"./udf.hpp\"') self.vecs = set() self.code_list = [] @@ -933,6 +981,11 @@ class udf(ast_node): else: return udf.ReturnPattern.bulk_return +class user_module_function(OperatorBase): + def __init__(self, name, nargs, ret_type): + super().__init__(name, nargs, lambda: ret_type, call=fn_behavior) + user_module_func[name] = self + builtin_operators[name] = self def include(objs): import inspect diff --git a/reconstruct/storage.py b/reconstruct/storage.py index 4820475..fe95607 100644 --- a/reconstruct/storage.py +++ b/reconstruct/storage.py @@ -102,6 +102,8 @@ class Context: self.tables = [] self.cols = [] self.datasource = None + self.module_stubs = '' + self.module_map = {} self.udf_map = dict() self.udf_agg_map = dict() self.use_columnstore = False @@ -134,21 +136,28 @@ class Context: '#include \"./server/libaquery.h\"\n' '#include \"./server/aggregations.h\"\n\n' ) + def get_init_func(self): + if self.module_map: + return '' + ret = 'void init(Context* cxt){\n' + for fname in self.module_map.keys(): + ret += f'{fname} = (decltype({fname}))(cxt->get_module_function("{fname}"));\n' + return ret + '}\n' def sql_begin(self): self.sql = '' def sql_end(self): self.queries.append('Q' + self.sql) - self.sql = '' + self.sql = '' def postproc_begin(self, proc_name: str): self.ccode = self.function_deco + proc_name + self.function_head def postproc_end(self, proc_name: str): self.procs.append(self.ccode + 'return 0;\n}') self.ccode = '' - self.queries.append('P' + proc_name) - + self.queries.append('P' + proc_name) + def finalize(self): if not self.finalized: headers = '' @@ -159,4 +168,4 @@ class Context: headers += '#include ' + h + '\n' self.ccode = headers + '\n'.join(self.procs) self.headers = set() - return self.ccode \ No newline at end of file + return self.ccode diff --git a/requirements.txt b/requirements.txt index d48c2ed..5e69829 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ mo-future -mo-dots==8.20.21357 +mo-dots mo-parsing mo-imports dataclasses; python_version < '3.7' diff --git a/server/libaquery.h b/server/libaquery.h index b103fcf..e4f6674 100644 --- a/server/libaquery.h +++ b/server/libaquery.h @@ -34,7 +34,7 @@ struct Context{ typedef int (*printf_type) (const char *format, ...); std::unordered_map tables; std::unordered_map cols; - + void* module_function_maps = 0; Config* cfg; int n_buffers, *sz_bufs; @@ -62,6 +62,7 @@ struct Context{ } void init_session(); void end_session(); + void* get_module_function(const char*); }; #ifdef _WIN32 diff --git a/server/server.cpp b/server/server.cpp index 7bd7916..99c539c 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -77,10 +77,21 @@ void Context::init_session(){ Session::Statistic stats; } } +void* Context::get_module_function(const char* fname){ + auto fmap = static_cast*> + (this->module_function_maps); + auto ret = fmap->find(fname); + return ret == fmap->end() ? nullptr : ret->second; +} int dll_main(int argc, char** argv, Context* cxt){ Config *cfg = reinterpret_cast(argv[0]); - + std::unordered_map user_module_map; + if (cxt->module_function_maps == 0) + cxt->module_function_maps = new std::unordered_map(); + auto module_fn_map = + static_cast*>(cxt->module_function_maps); + auto buf_szs = cfg->buffer_sizes; void** buffers = (void**)malloc(sizeof(void*) * cfg->n_buffers); for (int i = 0; i < cfg->n_buffers; i++) @@ -95,6 +106,7 @@ int dll_main(int argc, char** argv, Context* cxt){ while(cfg->running){ if (cfg->new_query) { void *handle = 0; + void *user_module_handle = 0; if (cfg->backend_type == BACKEND_MonetDB){ if (cxt->alt_server == 0) cxt->alt_server = new Server(cxt); @@ -106,13 +118,43 @@ int dll_main(int argc, char** argv, Context* cxt){ for(int i = 0; i < n_recv; ++i) { //printf("%s, %d\n", n_recvd[i], n_recvd[i][0] == 'Q'); - if (n_recvd[i][0] == 'Q'){ - server->exec(n_recvd[i] + 1); - printf("Exec Q%d: %s", i, n_recvd[i]); - } - else if (n_recvd[i][0] == 'P' && handle && !server->haserror()) { - code_snippet c = reinterpret_cast(dlsym(handle, n_recvd[i]+1)); - c(cxt); + switch(n_recvd[i][0]){ + case 'Q': + { + server->exec(n_recvd[i] + 1); + printf("Exec Q%d: %s", i, n_recvd[i]); + } + break; + case 'P': + if(handle && !server->haserror()) { + code_snippet c = reinterpret_cast(dlsym(handle, n_recvd[i]+1)); + c(cxt); + } + break; + case 'M': + { + auto mname = n_recvd[i] + 1; + user_module_handle = dlopen(mname, RTLD_LAZY); + user_module_map[mname] = user_module_handle; + } + break; + case 'F': + { + auto fname = n_recvd[i] + 1; + module_fn_map->insert_or_assign(fname, dlsym(user_module_handle, fname)); + } + break; + case 'U': + { + auto mname = n_recvd[i] + 1; + auto it = user_module_map.find(mname); + if (user_module_handle == it->second) + user_module_handle = 0; + dlclose(it->second); + user_module_map.erase(it); + } + break; + } } if(handle) { diff --git a/server/threading.cpp b/server/threading.cpp index 64f0022..7d7ca22 100644 --- a/server/threading.cpp +++ b/server/threading.cpp @@ -151,3 +151,18 @@ bool ThreadPool::busy(){ } return true; } + +void IntervalBasedTrigger::timer::reset(){ + time_remaining = interval; +} + +bool IntervalBasedTrigger::timer::tick(uint32_t t){ + if (time_remaining > t) { + time_remaining -= t; + return false; + } + else{ + time_remaining = interval - t%interval; + return true; + } +} \ No newline at end of file diff --git a/server/threading.h b/server/threading.h index c78283d..1144de7 100644 --- a/server/threading.h +++ b/server/threading.h @@ -53,6 +53,8 @@ public: struct timer{ uint32_t interval; // in milliseconds uint32_t time_remaining; + void reset(); + bool tick(uint32_t t); }; void add_trigger(); private: diff --git a/test.aquery b/test.aquery index 50cc7c9..746eab0 100644 --- a/test.aquery +++ b/test.aquery @@ -2,13 +2,23 @@ f stock.a xexec + f moving_avg.a xexec + f q1.sql xexec + f joins.a xexec + f udf3.a xexec +f strings.a +xexec + +f funcs.a +xexec + exit diff --git a/tests/funcs.a b/tests/funcs.a index 3bf922e..817efdd 100644 --- a/tests/funcs.a +++ b/tests/funcs.a @@ -9,23 +9,13 @@ FUNCTION sd ( x) { sqrt ( covariance (x , x) ) } -AGGREGATION FUNCTION covariances(x, y, w){ - static xmeans := 0, ymeans := 0, cnt := 0; - if (cnt < w) { xmeans += x; } - else { - xmeans += (x - x.vec[cnt - w]) / w; - ymeans += (y - y.vec[cnt - w]) / w; - } - avg (( x.vec(x.len-w, x.len) - xmean ) * (y.vec(y.len - w, y.len) - ymean )) -} - FUNCTION pairCorr (x , y ) { covariance (x , y ) / ( sd (x) * sd (y )) } CREATE TABLE test1(a INT, b INT, c INT, d INT) -LOAD DATA INFILE "test.csv" +LOAD DATA INFILE "data/test.csv" INTO TABLE test1 FIELDS TERMINATED BY "," diff --git a/tests/joins.a b/tests/joins.a index 3ed82a1..3510b6f 100644 --- a/tests/joins.a +++ b/tests/joins.a @@ -20,13 +20,13 @@ covariance (x , y ) / ( sd (x) * sd (y )) CREATE TABLE tt(a INT, b INT, c INT, d INT) -LOAD DATA INFILE "test.csv" +LOAD DATA INFILE "data/test.csv" INTO TABLE tt FIELDS TERMINATED BY "," CREATE TABLE sale(Mont INT, sales INT) -LOAD DATA INFILE "moving_avg.csv" +LOAD DATA INFILE "data/moving_avg.csv" INTO TABLE sale FIELDS TERMINATED BY "," diff --git a/tests/moving_avg.a b/tests/moving_avg.a index 0c87841..e9e2e79 100644 --- a/tests/moving_avg.a +++ b/tests/moving_avg.a @@ -1,6 +1,6 @@ CREATE TABLE sale(Mont INT, sales INT) -LOAD DATA INFILE "moving_avg.csv" +LOAD DATA INFILE "data/moving_avg.csv" INTO TABLE sale FIELDS TERMINATED BY "," diff --git a/tests/q1.sql b/tests/q1.sql index 0e182d4..747b83b 100644 --- a/tests/q1.sql +++ b/tests/q1.sql @@ -1,6 +1,6 @@ CREATE TABLE testq1(a INT, b INT, c INT, d INT) -LOAD DATA INFILE "test.csv" +LOAD DATA INFILE "data/test.csv" INTO TABLE testq1 FIELDS TERMINATED BY "," diff --git a/tests/strings.a b/tests/strings.a index 80d0ead..74c8629 100644 --- a/tests/strings.a +++ b/tests/strings.a @@ -1,6 +1,6 @@ CREATE TABLE types_test(names varchar(10), val real, id int) -LOAD DATA INFILE "datatypes.csv" +LOAD DATA INFILE "data/datatypes.csv" INTO TABLE types_test FIELDS TERMINATED BY "," diff --git a/tests/udf3.a b/tests/udf3.a index 0368a8b..b345f0d 100644 --- a/tests/udf3.a +++ b/tests/udf3.a @@ -31,7 +31,7 @@ AGGREGATION FUNCTION covariances2(x, y, w){ CREATE TABLE test(a INT, b INT, c INT, d INT) -LOAD DATA INFILE "test2.csv" +LOAD DATA INFILE "data/test2.csv" INTO TABLE test FIELDS TERMINATED BY ","