diff --git a/README.md b/README.md
index 760acf3..41c4b42 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ There're multiple options to run AQuery on Windows. You can use the native toolc
- For WSL, Docker or Linux virtual machines, see Linux, Docker sections below
- For Visual Studio (Recommended):
- 1. Install python3.6 or above from [official website](https://www.python.org/downloads/windows/) or Microsoft Store.
+1. Install python3.6 or above from [official website](https://www.python.org/downloads/windows/) or Microsoft Store.
2. Install Microsoft Visual Studio 2022 or later with **Desktop development with C++** selected.
3. Clone AQuery repo from [Github](https://github.com/sunyinqi0508/AQuery2)
4. Install python requirements with pip `python3 -m pip install -r requirements.txt`
@@ -108,7 +108,7 @@ There're multiple options to run AQuery on Windows. You can use the native toolc
`f moving_avg.a`
`xexec`
-See ./tests/ for more examples.
+See files in ./tests/ for more examples.
## Automated Testing Scripts
- A series of commands can be put in a script file and execute using `script` command.
@@ -174,4 +174,4 @@ See ./tests/ for more examples.
- [x] Functionality: Basic helper functions in aquery
- [ ] Bug: Join-Aware Column management
- [ ] Bug: Order By after Group By
-- [ ] Functionality: Having clause
+- [ ] Functionality: Having clause, With clause
diff --git a/aquery_parser/sql_parser.py b/aquery_parser/sql_parser.py
index 45bbe28..987f92c 100644
--- a/aquery_parser/sql_parser.py
+++ b/aquery_parser/sql_parser.py
@@ -672,13 +672,15 @@ def parser(literal_string, ident, sqlserver=False):
module_func_def = (
var_name("fname")
+ LB
- + delimited_list(
- (
- var_name("arg")
- + COLON
- + var_name("type")
- )("vars")
- )
+ + Optional(
+ delimited_list(
+ (
+ var_name("arg")
+ + COLON
+ + var_name("type")
+ )("vars")
+ )
+ )
+ RB
+ LAMBDA
+ var_name("ret_type")
diff --git a/engine/types.py b/engine/types.py
index 74541c6..ee7cbcf 100644
--- a/engine/types.py
+++ b/engine/types.py
@@ -98,7 +98,7 @@ FloatT = Types(16, name = 'float', cname = 'float', sqlname = 'REAL',
HgeT = Types(9, name = 'int128',cname='__int128_t', sqlname = 'HUGEINT', fp_type = DoubleT)
UHgeT = Types(10, name = 'uint128', cname='__uint128_t', sqlname = 'HUGEINT', fp_type = DoubleT)
LongT = Types(4, name = 'int64', sqlname = 'BIGINT', fp_type = DoubleT)
-BoolT = Types(0, name = 'bool', sqlname = 'BOOL', long_type=LongT, fp_type=FloatT)
+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, fp_type=FloatT)
diff --git a/prompt.py b/prompt.py
index 356026a..8a00dcc 100644
--- a/prompt.py
+++ b/prompt.py
@@ -558,7 +558,7 @@ def prompt(running = lambda:True, next = lambda:input('> '), state = None):
state.stmts = parser.parse(og_q.strip())
cxt.Info(state.stmts)
state.currstats.parse_time = state.currstats.stop()
- except ParseException as e:
+ except (ParseException, KeyError) as e:
print(e)
continue
except (ValueError, FileNotFoundError) as e:
@@ -574,9 +574,15 @@ def prompt(running = lambda:True, next = lambda:input('> '), state = None):
raise
except ValueError as e:
import code, traceback
+ __stdin = os.dup(0)
raise_exception = True
sh = code.InteractiveConsole({**globals(), **locals()})
- sh.interact(banner = traceback.format_exc(), exitmsg = 'debugging session ended.')
+ try:
+ sh.interact(banner = traceback.format_exc(), exitmsg = 'debugging session ended.')
+ except:
+ pass
+ finally:
+ sys.stdin = io.TextIOWrapper(io.BufferedReader(io.FileIO(__stdin, mode='rb', closefd=False)), encoding='utf8')
save('', cxt)
rm(state)
# control whether to raise exception in interactive console
diff --git a/reconstruct/ast.py b/reconstruct/ast.py
index da8e01c..3f56048 100644
--- a/reconstruct/ast.py
+++ b/reconstruct/ast.py
@@ -916,7 +916,7 @@ class insert(ast_node):
# raise ValueError("Column Mismatch")
list_values = []
- for i, s in enumerate(values):
+ for i, s in enumerate(enlist(values)):
if 'value' in s:
list_values.append(f"{s['value']}")
else:
diff --git a/reconstruct/expr.py b/reconstruct/expr.py
index ec8897c..c82712c 100644
--- a/reconstruct/expr.py
+++ b/reconstruct/expr.py
@@ -362,7 +362,7 @@ class expr(ast_node):
elif self.is_recursive_call_inudf:
for b in builtin_vars:
exec(f'loc["{b}"] = lambda : "{b}"')
-
+
x = self.c_code if c_code is None else c_code
from engine.utils import escape_qoutes
if decltypestr:
diff --git a/sdk/aquery.h b/sdk/aquery.h
index 15848f9..261b204 100644
--- a/sdk/aquery.h
+++ b/sdk/aquery.h
@@ -86,11 +86,26 @@ __AQEXPORT__(void) init_session(Context* cxt);
#else
void* memcpy(void*, const void*, unsigned long long);
#endif
+
+struct vectortype_storage{
+ void* container = nullptr;
+ unsigned int size = 0, capacity = 0;
+ vectortype_storage(void* container, unsigned int size, unsigned int capacity) :
+ container(container), size(size), capacity(capacity) {}
+ vectortype_storage() = default;
+ template class VT>
+ vectortype_storage(const VT& vt) {
+ memcpy(this, &vt, sizeof(vectortype_storage));
+ }
+};
struct ColRef_storage {
- void* container;
- unsigned int capacity, size;
- const char* name;
- int ty; // what if enum is not int?
+ void* container = nullptr;
+ unsigned int size = 0, capacity = 0;
+ const char* name = nullptr;
+ int ty = 0; // what if enum is not int?
+ ColRef_storage(void* container, unsigned int size, unsigned int capacity, const char* name, int ty) :
+ container(container), size(size), capacity(capacity), name(name), ty(ty) {}
+ ColRef_storage() = default;
template class VT>
ColRef_storage(const VT& vt) {
memcpy(this, &vt, sizeof(ColRef_storage));
diff --git a/tests/dt.a b/tests/dt.a
new file mode 100644
index 0000000..af851e6
--- /dev/null
+++ b/tests/dt.a
@@ -0,0 +1,25 @@
+LOAD MODULE FROM "./libirf.so"
+FUNCTIONS (
+ mydiv(a:int, b:int) -> double,
+ mulvec(a:int, b:vecfloat) -> vecfloat,
+ newtree(height:int, f:int64, sparse:vecint, forget:double, maxF:int64, noClasses:int64, e:int, r:int64, rb:int64) -> bool,
+ additem(X:vecdouble, y:int64, size:int64) -> bool,
+ fit() -> bool,
+ predict() -> vecint
+);
+
+select mydiv(2,3);
+create table tb(x int);
+create table tb2(x double, y double, z double);
+insert into tb values (0);
+insert into tb values (0);
+insert into tb values (0);
+select newtree(5, 3, tb.x, 0, 3, 2, 0, 100, 1) from tb;
+insert into tb2 values (1, 0, 1);
+insert into tb2 values (0, 1, 1);
+insert into tb2 values (1, 1, 1);
+select additem(tb2.x, 1, 3) from tb2;
+select additem(tb2.y, 0, -1) from tb2;
+select additem(tb2.z, 1, -1) from tb2;
+select fit();
+select predict();
\ No newline at end of file