diff --git a/Makefile b/Makefile index 81b2645..dd7747e 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ CXXFLAGS = --std=c++1z ifeq ($(AQ_DEBUG), 1) OPTFLAGS = -g3 else - OPTFLAGS = -O3 -DNDEBUG -fno-stack-protector + OPTFLAGS = -O3 -DNDEBUG -fno-stack-protector endif LINKFLAGS = -flto # + $(AQ_LINK_FLAG) SHAREDFLAGS = -shared diff --git a/README.md b/README.md index 9c15dfd..de90bab 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,11 @@ There're multiple options to run AQuery on Windows. But for better consistency I - `exec`: execute last parsed statement(s) with Hybrid Execution Engine. Hybrid Execution Engine decouples the query into two parts. The standard SQL (MonetDB dialect) 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. - `stats ` configure statistics. - no options: show statistics for all queries so far. + - `reset`: resets statistics. - `on` : statistics will be shown for every future query. - `off`: statistics will not be shown for every future query. - `script `: use automated testing script, this will execute all commands in the script +- `sh ` launch a shell. Shell name can be specified (e.g. `sh fish`). - `dbg` start python interactive interpreter at the current context. - `print`: print parsed AQuery statements (AST in JSON form) - `save `: save current code snippet. will use random filename if not specified. @@ -182,3 +184,4 @@ See files in ./tests/ for more examples. - [ ] Bug: Join-Aware Column management - [ ] Bug: Order By after Group By - [ ] Functionality: Having clause, With clause +- [ ] Decouple expr.py diff --git a/engine/types.py b/engine/types.py index c719e06..8eac736 100644 --- a/engine/types.py +++ b/engine/types.py @@ -311,6 +311,8 @@ opeq = OperatorBase('eq', 2, logical, cname = '==', sqlname = '=', call = binary opnot = OperatorBase('not', 1, logical, cname = '!', sqlname = 'NOT', call = unary_op_behavior) opdistinct = OperatorBase('distinct', 1, as_is, cname = '.distinct()', sqlname = 'distinct', call = distinct_behavior) # functional +fnprev = OperatorBase('prev', 1, as_is, cname = 'prev', sqlname = 'PREV', call = fn_behavior) +fnnext = OperatorBase('next', 1, as_is, cname = 'aggnext', sqlname = 'NEXT', call = fn_behavior) fnmax = OperatorBase('max', 1, as_is, cname = 'max', sqlname = 'MAX', call = fn_behavior) fnmin = OperatorBase('min', 1, as_is, cname = 'min', sqlname = 'MIN', call = fn_behavior) fndeltas = OperatorBase('deltas', 1, as_is, cname = 'deltas', sqlname = 'DELTAS', call = fn_behavior) @@ -358,7 +360,7 @@ builtin_cstdlib = _op_make_dict(fnsqrt, fnlog, fnsin, fncos, fntan, fnpow) builtin_func = _op_make_dict(fnmax, fnmin, fnsum, fnavg, fnmaxs, fnmins, fndeltas, fnratios, fnlast, fnfirst, fnsums, fnavgs, fncnt, - fnpack, fntrunc) + fnpack, fntrunc, fnprev, fnnext) 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, diff --git a/prompt.py b/prompt.py index 58eea0a..cd17360 100644 --- a/prompt.py +++ b/prompt.py @@ -563,14 +563,14 @@ def prompt(running = lambda:True, next = lambda:input('> '), state = None): if len(qs) > 1: if qs[1].startswith('on'): state.need_print = True - continue elif qs[1].startswith('off'): state.need_print = False - continue elif qs[1].startswith('last'): state.currstats.need_print = True state.currstats.print() - continue + elif qs[1].startswith('reset'): + state.currstats.clear() + continue state.stats.need_print = True state.stats.print(clear = False) continue diff --git a/reconstruct/ast.py b/reconstruct/ast.py index 72d91bd..f81083e 100644 --- a/reconstruct/ast.py +++ b/reconstruct/ast.py @@ -293,7 +293,7 @@ class projection(ast_node): val[1] = val[1](False) if val[0] == LazyT: - decltypestring = val[2].eval(x,y,gettype=True,c_code=True)(True) + decltypestring = val[2].eval(y=y,gettype=True,c_code=True)(True) decltypestring = f'value_type>' out_typenames[key] = decltypestring else: diff --git a/reconstruct/expr.py b/reconstruct/expr.py index 403ec42..4fd483b 100644 --- a/reconstruct/expr.py +++ b/reconstruct/expr.py @@ -88,7 +88,7 @@ class expr(ast_node): self.udf_map = parent.context.udf_map self.func_maps = {**builtin_func, **self.udf_map, **user_module_func} self.operators = {**builtin_operators, **self.udf_map, **user_module_func} - self.ext_aggfuncs = ['sum', 'avg', 'count', 'min', 'max', 'last', 'first'] + self.ext_aggfuncs = ['sum', 'avg', 'count', 'min', 'max', 'last', 'first', 'prev', 'next'] def produce(self, node): from engine.utils import enlist diff --git a/server/aggregations.h b/server/aggregations.h index b3aecb7..5338e23 100644 --- a/server/aggregations.h +++ b/server/aggregations.h @@ -214,6 +214,28 @@ decayed_t deltas(const VT& arr) { return ret; } +template class VT> +decayed_t prev(const VT& arr) { + const uint32_t& len = arr.size; + decayed_t ret(len); + uint32_t i = 0; + if (len) ret[i++] = arr[0]; + for (; i < len; ++i) + ret[i] = arr[i - 1]; + return ret; +} + +template class VT> +decayed_t aggnext(const VT& arr) { + const uint32_t& len = arr.size; + decayed_t ret(len); + uint32_t i = 1; + for (; i < len; ++i) + ret[i - 1] = arr[i]; + if (len > 0) ret[len - 1] = arr[len - 1]; + return ret; +} + template class VT> T last(const VT& arr) { if (!arr.size) return 0; @@ -232,7 +254,7 @@ T first(const VT& arr) { #define __DEFAULT_AGGREGATE_FUNCTION__(NAME, RET) \ template constexpr inline T NAME(const T& v) { return RET; } -// wrong behavior with count(0) +// non-aggreation count. E.g. SELECT COUNT(col) from table; template constexpr inline T count(const T& v) { return 1; } template constexpr inline T max(const T& v) { return v; } template constexpr inline T min(const T& v) { return v; } @@ -248,5 +270,7 @@ template constexpr inline T mins(const T& v) { return v; } template constexpr inline T avgs(const T& v) { return v; } template constexpr inline T sums(const T& v) { return v; } template constexpr inline T last(const T& v) { return v; } +template constexpr inline T prev(const T& v) { return v; } +template constexpr inline T aggnext(const T& v) { return v; } template constexpr inline T daltas(const T& v) { return 0; } template constexpr inline T ratios(const T& v) { return 1; } diff --git a/tests/q4.a b/tests/q4.a index 005cbdf..4237b16 100644 --- a/tests/q4.a +++ b/tests/q4.a @@ -10,3 +10,11 @@ into table ticks fields terminated by "," select max(price - mins(price)) from ticks assuming asc timestamp where ID = "S" and tradeDate= '2022-10-01'; +DROP TABLE IF EXISTS ticks +CREATE TABLE ticks(ID varchar(20), date int, endofdayprice int) +LOAD DATA INFILE "data/ticks.csv" INTO TABLE TICKS FIELDS TERMINATED BY "," + +SELECT max(endofdayprice/prev(endofdayprice)) as Max_Ratio +FROM ticks +ASSUMING ASC date +WHERE ID = "3001" \ No newline at end of file