udf support for monetdbe backend

dev
bill sun 2 years ago
parent 3b659b99f8
commit ece2a6cc9f

Binary file not shown.

@ -1,15 +1,18 @@
OS_SUPPORT =
MonetDB_LIB =
ifeq ($(OS),Windows_NT)
OS_SUPPORT += server/winhelper.cpp
MonetDB_LIB += -Imonetdb/msvc msc-plugin/monetdbe.dll
endif
$(info $(OS_SUPPORT))
server.bin:
g++ server/server.cpp $(OS_SUPPORT) --std=c++1z -O3 -march=native -o server.bin
$(CXX) server/server.cpp $(OS_SUPPORT) --std=c++1z -O3 -march=native -o server.bin
server.so:
g++ server/server.cpp -shared $(OS_SUPPORT) --std=c++1z -O3 -march=native -o 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 server/server.cpp $(OS_SUPPORT) server/monetdb_conn.cpp $(MonetDB_LIB) --std=c++1z -o server.so -O3
snippet:
g++ -shared -fPIC --std=c++1z out.cpp -O3 -march=native -o dll.so
$(CXX) -shared -fPIC --std=c++1z out.cpp server/monetdb_conn.cpp $(MonetDB_LIB) -O3 -march=native -o dll.so
clean:
rm *.shm -rf

BIN
a.exe

Binary file not shown.

BIN
a.exp

Binary file not shown.

BIN
a.lib

Binary file not shown.

@ -0,0 +1,30 @@
# put environment specific configuration here
import os
# os.environ['CXX'] = 'C:/Program Files/LLVM/bin/clang.exe'
add_path_to_ldpath = True
os_platform = 'unkown'
import sys
if os.name == 'nt':
if sys.platform == 'win32':
os_platform = 'win'
elif sys.platform == 'cygwin' or sys.platform == 'msys':
os_platform = 'cygwin'
elif os.name == 'posix':
if sys.platform == 'darwin':
os_platform = 'mac'
elif 'linux' in sys.platform:
os_platform = 'linux'
elif 'bsd' in sys.platform:
os_platform = 'bsd'
# deal with msys dependencies:
if os_platform == 'win':
os.add_dll_directory('c:/msys64/usr/bin')
os.add_dll_directory(os.path.abspath('./msc-plugin'))
print("adding path")

@ -344,7 +344,7 @@ def parser(literal_string, ident, sqlserver=False):
+ LBRACE
+ fbody
+ RBRACE
)
)("udf")
selection = (
(SELECT + DISTINCT + ON + LB)

@ -0,0 +1,15 @@
## Windows
- clang-msvc:
- "%CXX%" -D_CRT_SECURE_NO_WARNINGS -shared server/server.cpp server/winhelper.cpp server/monetdb_conn.cpp -Imonetdb/msvc -Lmonetdb/msvc -lmonetdbe.lib --std=c++2a -o server.so
- os.add_dll_directory(os.path.abspath('./monetdb/msvc'))
- gcc-mingw (link w/ msvc monetdb):
- "%CXX%" -shared -fPIC server/server.cpp server/winhelper.cpp server/monetdb_conn.cpp -Imonetdb/msvc msc-plugin/monetdbe.dll --std=c++2a -o server.so
- os.add_dll_directory('c:/msys64/usr/bin')
- os.add_dll_directory(os.path.abspath('./monetdb/msvc'))
- gcc-mingw (link w/ mingw monetdb, can only load under mingw python):
- $(CXX) server/server.cpp server/monetdb_conn.cpp -fPIC -shared $(OS_SUPPORT) --std=c++1z -O3 -march=native -o server.so -I./monetdb/msys64 -L./lib -lmonetdbe
- os.add_dll_directory('c:/msys64/usr/bin')
- os.add_dll_directory(os.path.abspath('./lib'))
- msvc:
- D:\gg\vs22\MSBuild\Current\Bin\msbuild "d:\gg\AQuery++\server\server.vcxproj" /p:configuration=Release /p:platform=x64
- os.add_dll_directory(os.path.abspath('./monetdb/msvc'))

@ -1,12 +1,37 @@
from engine.ast import Context, ast_node
import engine.ddl, engine.projection
saved_cxt = None
def initialize():
return Context()
def initialize(cxt = None, keep = False):
global saved_cxt
if cxt is None or not keep or type(cxt) is not Context:
if saved_cxt is None or not keep:
cxt = Context()
saved_cxt = cxt
else:
cxt = saved_cxt
cxt.new()
return cxt
def generate(ast, cxt):
for k in ast.keys():
if k in ast_node.types.keys():
root = ast_node.types[k](None, ast, cxt)
__all__ = ["initialize", "generate"]
def exec(stmts, cxt = None, keep = None):
cxt = initialize(cxt, keep)
stmts_stmts = stmts['stmts']
if type(stmts_stmts) is list:
for s in stmts_stmts:
generate(s, cxt)
else:
generate(stmts_stmts, cxt)
cxt.Info(cxt.ccode)
with open('out.cpp', 'wb') as outfile:
outfile.write((cxt.finalize()).encode('utf-8'))
return cxt
__all__ = ["initialize", "generate", "exec", "saved_cxt"]

@ -1,5 +1,6 @@
from engine.utils import base62uuid
from copy import copy
from typing import *
# replace column info with this later.
class ColRef:
def __init__(self, cname, _ty, cobj, cnt, table:'TableInfo', name, id, compound = False):
@ -65,7 +66,7 @@ class TableInfo:
self.views = set()
#keep track of temp vars
self.local_vars = dict()
self.rec = None
self.rec = None # a hook on get_col_d to record tables being referenced in the process
self.groupinfo = None
self.add_cols(cols)
# runtime
@ -207,14 +208,17 @@ class Context:
LOG_INFO = 'INFO'
LOG_ERROR = 'ERROR'
LOG_SILENT = 'SILENT'
from engine.types import Types
type_table : Dict[str, Types] = dict()
def new(self):
self.tmp_names = set()
self.udf_map = dict()
self.headers = set(['\"./server/libaquery.h\"'])
self.finalized = False
# read header
self.ccode = ''
self.ccodelet = ''
self.ccode = str()
self.ccodelet = str()
with open('header.cxx', 'r') as outfile:
self.ccode = outfile.read()
# datasource will be availible after `from' clause is parsed
@ -236,8 +240,8 @@ class Context:
self.log_level = Context.LOG_SILENT
self.print = print
# read header
self.ccode = ''
self.ccodelet = ''
self.ccode = str()
self.ccodelet = str()
self.columns_in_context = dict()
self.tables_in_context = dict()
with open('header.cxx', 'r') as outfile:

@ -28,11 +28,14 @@ class expr(ast_node):
'xor' : '^',
'gt':'>',
'lt':'<',
'le':'<=',
'gt':'>='
'lte':'<=',
'gte':'>=',
'neq':'!=',
'eq':'=='
}
compound_ops = {
'missing' : ['missing', lambda x: f'{x[0]} == nullval<decays<decltype({x[0]})>>'],
}
unary_ops = {

@ -1,34 +1,230 @@
from engine.ast import Context
from engine.utils import defval
from typing import Dict, List
type_table: Dict[str, "Types"] = {}
class Types:
name = 'Any'
cname = 'void*'
ctype_name = "types::NONE"
def __init__(self, context:Context):
self.cxt = context
def cast_to(self, *_):
return self
def cast_from(self, *_):
return self
def init_any(self):
self.name : str = 'Any'
self.sqlname : str = 'Int'
self.cname : str = 'void*'
self.ctype_name : str = "types::NONE"
self.null_value = 0
self.priority : int= 0
self.cast_to_dict = dict()
self.cast_from_dict = dict()
def __init__(self, priority = 0, *,
name = None, cname = None, sqlname = None,
ctype_name = None, null_value = None,
fp_type = None, long_type = None, is_fp = False,
cast_to = None, cast_from = None
):
self.is_fp = is_fp
if name is None:
self.init_any()
else:
self.name = name
self.cname = defval(cname, name.lower() + '_t')
self.sqlname = defval(sqlname, name.upper())
self.ctype_name = defval(ctype_name, f'types::{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())
self.priority = priority
self.long_type = defval(long_type, self)
self.fp_type = defval(fp_type, self)
global type_table
type_table[name] = self
def cast_to(self, ty : "Types"):
if ty in self.cast_to_dict:
return self.cast_to_dict[ty.name](ty)
else:
raise Exception(f'Illeagal cast: from {self.name} to {ty.name}.')
def cast_from(self, ty : "Types"):
if ty in self.cast_from_dict:
return self.cast_from_dict[ty.name](ty)
else:
raise Exception(f'Illeagal cast: from {ty.name} to {self.name}.')
def __repr__(self) -> str:
return self.cname
class String(Types):
name = 'String'
cname = 'const char*'
ctype_name = "types::ASTR"
def cast_from(self, ty, val, container = None):
if type(ty) is Int:
self.cxt.emit()
class Int(Types):
name = "Int"
cname = "int"
ctype_name = "types::AINT"
class Float(Types):
name = "Float"
cname = "float"
ctype_name = "types::AFLOAT"
return self.sqlname
def __str__(self) -> str:
return self.sqlname
class TypeCollection:
def __init__(self, sz, deftype, fptype = None, utype = None, *, collection = None) -> None:
self.size = sz
self.type = deftype
self.fptype = fptype
self.utype = utype
self.all_types = [deftype]
if fptype is not None:
self.all_types.append(fptype)
if utype is not None:
self.all_types.append(utype)
if collection is not None:
for ty in collection:
self.all_types.append(ty)
type_table = dict()
AnyT = Types(0)
LazyT = Types(240, name = 'Lazy', cname = '', sqlname = '', ctype_name = '')
DoubleT = Types(17, name = 'double', cname='double', sqlname = 'DOUBLE', is_fp = True)
FloatT = Types(16, name = 'float', cname = 'float', sqlname = 'REAL',
long_type = DoubleT, is_fp = True)
LongT = Types(4, name = 'int64', sqlname = 'BIGINT', fp_type = DoubleT)
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)
StrT = Types(200, name = 'str', cname = 'const char*', sqlname='VARCHAR', ctype_name = 'types::STRING')
def _ty_make_dict(fn : str, *ty : Types):
return {eval(fn):t for t in ty}
int_types : Dict[str, Types] = _ty_make_dict('t.sqlname.lower()', LongT, ByteT, ShortT, IntT)
fp_types : Dict[str, Types] = _ty_make_dict('t.sqlname.lower()', FloatT, DoubleT)
builtin_types : Dict[str, Types] = {**_ty_make_dict('t.sqlname.lower()', AnyT, StrT), **int_types, **fp_types}
type_bylength : Dict[int, TypeCollection] = {}
type_bylength[1] = TypeCollection(1, ByteT)
type_bylength[2] = TypeCollection(2, ShortT)
type_bylength[4] = TypeCollection(4, IntT, FloatT)
type_bylength[8] = TypeCollection(8, LongT, DoubleT, collection=[AnyT])
class OperatorBase:
def extending_type(ops:Types):
return ops.long_type
def fraction_type (ops:Types):
return ops.fp_type
def __init__(self, opname, n_ops, return_fx, * ,
optypes = None, cname = None, sqlname = None,
call = None):
self.name = opname
self.cname = defval(cname, opname)
self.sqlname = defval(sqlname, opname.upper())
self.n_ops = n_ops
self.optypes = optypes
self.return_type = defval(return_fx, lambda: self.optypes[0])
self.call = defval(call, lambda _, c_code = False, *args:
f'{self.cname if c_code else self.sqlname}({", ". join(args)})')
def __call__(self, c_code = False, *args) -> str:
return self.call(self, c_code, *args)
def get_return_type(self, inputs):
return self.return_type(inputs)
def __repr__(self) -> str:
return self.name
def __str__(self) -> str:
return self.name
# TODO: Type checks, Type catagories, e.g.: value type, etc.
# return type deduction
def auto_extension(*args : Types) -> Types:
final_type = AnyT
is_fp = False
for a in args:
if not is_fp and a.is_fp:
is_fp = True
final_type = final_type.fp_type
elif is_fp:
a = a.fp_type
final_type = a if a.priority > final_type.priority else final_type
return final_type
def auto_extension_int(*args : Types) -> Types:
final_type = AnyT
for a in args:
final_type = a if a.priority > final_type.priority else final_type
return final_type
def ty_clamp(fn, l:int = None, r:int = None):
return lambda *args : fn(*args[l: r])
def logical(*_ : Types) -> Types:
return ByteT
def int_return(*_ : Types) -> Types:
return IntT
def as_is (t: Types) -> Types:
return t
def fp (fx):
return lambda *args : fx(*args).fp_type
def ext (fx):
return lambda *args : fx(*args).long_type
# operator call behavior
def binary_op_behavior(op:OperatorBase, c_code, x, y):
name = op.cname if c_code else op.sqlname
return f'({x} {name} {y})'
def unary_op_behavior(op:OperatorBase, c_code, x):
name = op.cname if c_code else op.sqlname
return f'({x} {name})'
def fn_behavior(op:OperatorBase, c_code, *x):
name = op.cname if c_code else op.sqlname
return f'{name}({", ".join([f"{xx}" for xx in x])})'
def windowed_fn_behavor(op: OperatorBase, c_code, *x):
if not c_code:
return f'{op.sqlname}({", ".join([f"{xx}" for xx in x])})'
else:
name = op.cname if len(x) == 1 else op.cname[:-1] + 'w'
return f'{name}({", ".join([f"{xx}" for xx in x])})'
# arithmetic
opadd = OperatorBase('add', 2, auto_extension, cname = '+', sqlname = '+', call = binary_op_behavior)
opdiv = OperatorBase('div', 2, fp(auto_extension), cname = '/', sqlname = '/', call = binary_op_behavior)
opmul = OperatorBase('mul', 2, fp(auto_extension), cname = '*', sqlname = '*', call = binary_op_behavior)
opsub = OperatorBase('sub', 2, auto_extension, cname = '-', sqlname = '-', call = binary_op_behavior)
opmod = OperatorBase('mod', 2, auto_extension_int, cname = '%', sqlname = '%', call = binary_op_behavior)
opneg = OperatorBase('neg', 1, as_is, cname = '-', sqlname = '-', call = unary_op_behavior)
# logical
opand = OperatorBase('and', 2, logical, cname = '&&', sqlname = ' AND ', call = binary_op_behavior)
opor = OperatorBase('or', 2, logical, cname = '||', sqlname = ' OR ', call = binary_op_behavior)
opxor = OperatorBase('xor', 2, logical, cname = '^', sqlname = ' XOR ', call = binary_op_behavior)
opgt = OperatorBase('gt', 2, logical, cname = '>', sqlname = '>', call = binary_op_behavior)
oplt = OperatorBase('lt', 2, logical, cname = '<', sqlname = '<', call = binary_op_behavior)
opge = OperatorBase('gte', 2, logical, cname = '>=', sqlname = '>=', call = binary_op_behavior)
oplte = OperatorBase('lte', 2, logical, cname = '<=', sqlname = '<=', call = binary_op_behavior)
opneq = OperatorBase('neq', 2, logical, cname = '!=', sqlname = '!=', call = binary_op_behavior)
opeq = OperatorBase('eq', 2, logical, cname = '==', sqlname = '=', call = binary_op_behavior)
opnot = OperatorBase('not', 1, logical, cname = '!', sqlname = 'NOT', call = unary_op_behavior)
# functional
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)
fnsum = OperatorBase('sum', 1, ext(auto_extension), cname = 'sum', sqlname = 'SUM', call = fn_behavior)
fnavg = OperatorBase('avg', 1, fp(ext(auto_extension)), cname = 'avg', sqlname = 'AVG', call = fn_behavior)
fnmaxs = OperatorBase('maxs', [1, 2], ty_clamp(as_is, -1), cname = 'maxs', sqlname = 'MAXS', call = windowed_fn_behavor)
fnmins = OperatorBase('mins', [1, 2], ty_clamp(as_is, -1), cname = 'mins', sqlname = 'MINS', call = windowed_fn_behavor)
fnsums = OperatorBase('sums', [1, 2], ext(ty_clamp(auto_extension, -1)), cname = 'sums', sqlname = 'SUMS', call = windowed_fn_behavor)
fnavgs = OperatorBase('avgs', [1, 2], fp(ext(ty_clamp(auto_extension, -1))), cname = 'avgs', sqlname = 'AVGS', call = windowed_fn_behavor)
fncnt = OperatorBase('count', 1, int_return, cname = 'count', sqlname = 'COUNT', call = fn_behavior)
# special
def is_null_call_behavior(op:OperatorBase, c_code : bool, x : str):
if c_code :
return f'{x} == nullval<decays<decltype({x})>>'
else :
return f'{x} IS NULL'
spnull = OperatorBase('missing', 1, logical, cname = "", sqlname = "", call = is_null_call_behavior)
# cstdlib
fnsqrt = OperatorBase('sqrt', 1, lambda *_ : DoubleT, cname = 'sqrt', sqlname = 'SQRT', call = fn_behavior)
# type collections
def _op_make_dict(*items : OperatorBase):
return { i.name: i for i in items}
builtin_binary_arith = _op_make_dict(opadd, opdiv, opmul, opsub, opmod)
builtin_binary_logical = _op_make_dict(opand, opor, opxor, opgt, oplt, opge, oplte, opneq, opeq)
builtin_unary_logical = _op_make_dict(opnot)
builtin_unary_arith = _op_make_dict(opneg)
builtin_unary_special = _op_make_dict(spnull)
builtin_cstdlib = _op_make_dict(fnsqrt)
builtin_func = _op_make_dict(fnmax, fnmin, fnsum, fnavg, fnmaxs, fnmins, fnsums, fnavgs, fncnt)
builtin_operators : dict[str, OperatorBase] = {**builtin_binary_arith, **builtin_binary_logical,
**builtin_unary_arith, **builtin_unary_logical, **builtin_unary_special, **builtin_func, **builtin_cstdlib}

@ -1,7 +1,8 @@
import uuid
base62alp = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
nums = '0123456789'
reserved_monet = ['month']
def base62uuid(crop=8):
id = uuid.uuid4().int
ret = ''
@ -12,6 +13,33 @@ def base62uuid(crop=8):
return ret[:crop] if len(ret) else '0'
def get_leagl_name(name, lower = True):
if name is not None:
if lower:
name = name.lower()
name = ''.join([n for n in name if n in base62alp or n == '_'])
if name is None or len(name) == 0 or set(name) == set('_'):
name = base62uuid(8)
if(name[0] in nums):
name = '_' + name
return name
def check_leagl_name(name):
all_underscores = True
for c in name:
if c not in base62alp and c != '_':
return False
if c != '_':
all_underscores = False
if all_underscores:
return False
if name[0] in nums:
return False
return True
def enlist(l):
return l if type(l) is list else [l]
@ -23,3 +51,6 @@ def has_other(a, b):
if ai not in b:
return True
return False
def defval(val, default):
return default if val is None else val

@ -0,0 +1,24 @@
FUNCTION covariance (x , y ) {
xmean := avg (x) ;
ymean := avg (y) ;
avg (( x - xmean ) * (y - ymean ))
}
FUNCTION sd ( x) {
sqrt ( covariance (x , x) )
}
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"
INTO TABLE test1
FIELDS TERMINATED BY ","
SELECT pairCorr(c, b) * d, sum(a), b
FROM test1
group by c,b,d
order by b ASC

@ -0,0 +1,34 @@
FUNCTION covariance (x , y ) {
xmean := avg (x) ;
ymean := avg (y) ;
avg (( x - xmean ) * (y - ymean ))
}
FUNCTION sd ( x) {
sqrt ( covariance (x , x) )
}
FUNCTION pairCorr (x , y ) {
covariance (x , y ) / ( sd (x) * sd (y ))
}
-- FUNCTION covariances (w, x , y ) {
-- xmean := avgs (w, x) ;
-- ymean := avgs (y) ;
-- avg (( x - xmean ) * (y - ymean ))
-- }
CREATE TABLE tt(a INT, b INT, c INT, d INT)
LOAD DATA INFILE "test.csv"
INTO TABLE tt
FIELDS TERMINATED BY ","
CREATE TABLE sale(Mont INT, sales INT)
LOAD DATA INFILE "moving_avg.csv"
INTO TABLE sale
FIELDS TERMINATED BY ","
select sd(a) + sales from tt, sale where tt.a = sale.Mont

@ -0,0 +1,26 @@
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include "monetdbe.h"
int main() {
monetdbe_database db;
puts("alive");
monetdbe_open(&db, NULL, NULL);
printf("%lx", db);
monetdbe_result *res;
monetdbe_cnt cnt = 0;
char* ret = 0;
ret = monetdbe_query(db, const_cast<char*>(" CREATE TABLE test(a INT, b INT, c INT, d INT);\n"), &res, &cnt);
if(ret) puts(ret);
ret = monetdbe_query(db, const_cast<char*>(" COPY OFFSET 2 INTO test FROM 'd:/gg/AQuery++/test.csv' ON SERVER USING DELIMITERS ',';"), &res, &cnt);
if(ret) puts(ret);
ret = monetdbe_query(db, const_cast<char*>(" SELECT SUM(c), b, d FROM test GROUP BY a, b, d ORDER BY d DESC, b ;"), &res, &cnt);
if(ret) puts(ret);
monetdbe_column* cols;
monetdbe_result_fetch(res, &cols, 0);
printf("%lx, %d\n", cols, cols->count);
for(int i = 0; i < cols->count; ++i)
printf("%d ", ((long long*)cols->data)[i]);
monetdbe_close(db);
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,98 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6...3.21)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget MonetDB::monetdb_config_header)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target MonetDB::monetdb_config_header
add_library(MonetDB::monetdb_config_header INTERFACE IMPORTED)
set_target_properties(MonetDB::monetdb_config_header PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/monetdb"
)
if(CMAKE_VERSION VERSION_LESS 3.0.0)
message(FATAL_ERROR "This file relies on consumers using CMake 3.0.0 or greater.")
endif()
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/monetdb_config_headerTargets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -73,7 +73,7 @@
#endif /* _MSC_VER */
#if !defined(WIN32) && defined(__CYGWIN__)
#if !defined(WIN32) && (defined(__CYGWIN__) || defined(__MINGW32__))
#define WIN32 1
#endif

Binary file not shown.

@ -0,0 +1,473 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V.
*/
/* monetdb_config.h.in. Generated from CMakeLists.txt */
#ifndef MT_SEEN_MONETDB_CONFIG_H
#define MT_SEEN_MONETDB_CONFIG_H 1
#ifdef _MSC_VER
#if _MSC_VER < 1900
#error Versions below Visual Studio 2015 are no longer supported
#endif
/* Prevent pollution through excessive inclusion of include files by Windows.h. */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
/* Visual Studio 8 has deprecated lots of stuff: suppress warnings */
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#define _CRT_RAND_S /* for Windows rand_s, before stdlib.h */
#define HAVE_RAND_S 1
#endif
#if !defined(_XOPEN_SOURCE) && defined(__CYGWIN__)
#define _XOPEN_SOURCE 700
#endif
#include <stdlib.h>
#if defined(_MSC_VER) && defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
/* In this case, malloc and friends are redefined in crtdbg.h to debug
* versions. We need to include stdlib.h first or else we get
* conflicting declarations. */
#include <crtdbg.h>
#endif
#define HAVE_SYS_TYPES_H 1
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
/* standard C-99 include files */
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#ifdef _MSC_VER
/* Windows include files */
#include <process.h>
#include <windows.h>
#include <ws2tcpip.h>
/* indicate to sqltypes.h that windows.h has already been included and
that it doesn't have to define Windows constants */
#define ALREADY_HAVE_WINDOWS_TYPE 1
#define NATIVE_WIN32 1
#endif /* _MSC_VER */
#if !defined(WIN32) && (defined(__CYGWIN__)||defined(__MINGW32__))
#define WIN32 1
#endif
// Section: monetdb configure defines
/* #undef HAVE_DISPATCH_DISPATCH_H */
#define HAVE_DLFCN_H 1
#define HAVE_FCNTL_H 1
#define HAVE_IO_H 1
/* #undef HAVE_KVM_H */
#define HAVE_LIBGEN_H 1
/* #undef HAVE_LIBINTL_H */
/* #undef HAVE_MACH_MACH_INIT_H */
/* #undef HAVE_MACH_TASK_H */
/* #undef HAVE_MACH_O_DYLD_H */
#define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1
#define HAVE_POLL_H 1
/* #undef HAVE_PROCFS_H */
#define HAVE_PWD_H 1
#define HAVE_STRINGS_H 1
/* #undef HAVE_STROPTS_H */
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
/* #undef HAVE_SYS_SYSCTL_H */
#define HAVE_SYS_MMAN_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_RANDOM_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_UIO_H 1
#define HAVE_SYS_UN_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_TERMIOS_H 1
#define HAVE_UNISTD_H 1
#define HAVE_WINSOCK_H 1
#define HAVE_SEMAPHORE_H 1
#define HAVE_GETOPT_H 1
#define HAVE_STDATOMIC_H 1
#define HAVE_DIRENT_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_SYS_STAT_H 1
#define HAVE_FDATASYNC 1
#define HAVE_ACCEPT4 1
#define HAVE_ASCTIME_R 1
#define HAVE_CLOCK_GETTIME 1
#define HAVE_CTIME_R 1
/* #undef HAVE_DISPATCH_SEMAPHORE_CREATE */
/* #undef HAVE_FALLOCATE */
#define HAVE_FCNTL 1
#define HAVE_FORK 1
#define HAVE_FSYNC 1
#define HAVE_FTIME 1
#define HAVE_GETENTROPY 1
/* #undef HAVE_GETEXECNAME */
#define HAVE_GETLOGIN 1
#define HAVE_GETOPT_LONG 1
#define HAVE_GETRLIMIT 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_GETUID 1
#define HAVE_GMTIME_R 1
#define HAVE_LOCALTIME_R 1
#define HAVE_STRERROR_R 1
#define HAVE_LOCKF 1
#define HAVE_MADVISE 1
/* #undef HAVE_MREMAP */
#define HAVE_NANOSLEEP 1
#define HAVE_NL_LANGINFO 1
/* #undef HAVE__NSGETEXECUTABLEPATH */
/* #undef HAVE_PIPE2 */
#define HAVE_POLL 1
#define HAVE_POPEN 1
#define HAVE_POSIX_FADVISE 1
#define HAVE_POSIX_FALLOCATE 1
#define HAVE_POSIX_MADVISE 1
#define HAVE_PUTENV 1
#define HAVE_SETSID 1
#define HAVE_SHUTDOWN 1
#define HAVE_SIGACTION 1
#define HAVE_STPCPY 1
#define HAVE_STRCASESTR 1
#define HAVE_STRNCASECMP 1
#define HAVE_STRPTIME 1
#define HAVE_STRSIGNAL 1
#define HAVE_SYSCONF 1
/* #undef HAVE_TASK_INFO */
#define HAVE_TIMES 1
#define HAVE_UNAME 1
/* #undef HAVE_SEMTIMEDOP */
#define HAVE_PTHREAD_KILL 1
#define HAVE_PTHREAD_SIGMASK 1
#define HAVE_GETOPT 1
#define ICONV_CONST
#define FLEXIBLE_ARRAY_MEMBER
#define ENABLE_MAPI 1
#define HAVE_MAPI 1
// End Section: monetdb configure defines
// Section: monetdb macro variables
/* #undef HAVE_ICONV */
#define HAVE_PTHREAD_H 1
/* #undef HAVE_LIBPCRE */
/* #undef HAVE_LIBBZ2 */
/* #undef HAVE_CURL */
/* #undef HAVE_LIBLZMA */
/* #undef HAVE_LIBXML */
/* #undef HAVE_LIBZ */
/* #undef HAVE_LIBLZ4 */
/* #undef HAVE_PROJ */
/* #undef HAVE_SNAPPY */
/* #undef HAVE_FITS */
/* #undef HAVE_VALGRIND */
/* #undef HAVE_NETCDF */
/* #undef HAVE_READLINE */
/* #undef HAVE_LIBR */
#define RHOME "/registry"
/* #undef HAVE_GEOM */
/* #undef HAVE_SHP */
/* #undef HAVE_LIBPY3 */
// #define SOCKET_LIBRARIES
#define HAVE_GETADDRINFO 1
/* #undef HAVE_CUDF */
#define MAPI_PORT 50000
#define MAPI_PORT_STR "50000"
#ifdef _MSC_VER
#define DIR_SEP '\\'
#define PATH_SEP ';'
#define DIR_SEP_STR "\\"
#define SO_PREFIX ""
#else
#define DIR_SEP '/'
#define PATH_SEP ':'
#define DIR_SEP_STR "/"
#define SO_PREFIX "lib"
#endif
#define SO_EXT ".dll"
#define BINDIR "C:/Program Files (x86)/MonetDB/bin"
#define LIBDIR "C:/Program Files (x86)/MonetDB/lib"
#define LOCALSTATEDIR "C:/Program Files (x86)/MonetDB/var"
// End Section: monetdb macro variables
// Section: monetdb configure misc
#define MONETDB_RELEASE "unreleased"
#define MONETDB_VERSION "11.44.0"
#define MONETDB_VERSION_MAJOR 11
#define MONETDB_VERSION_MINOR 44
#define MONETDB_VERSION_PATCH 0
#define GDK_VERSION "25.1.0"
#define GDK_VERSION_MAJOR 25
#define GDK_VERSION_MINOR 1
#define GDK_VERSION_PATCH 0
#define MAPI_VERSION "14.0.2"
#define MAPI_VERSION_MAJOR 14
#define MAPI_VERSION_MINOR 0
#define MAPI_VERSION_PATCH 2
#define MONETDB5_VERSION "32.0.6"
#define MONETDB5_VERSION_MAJOR 32
#define MONETDB5_VERSION_MINOR 0
#define MONETDB5_VERSION_PATCH 6
#define MONETDBE_VERSION "3.0.2"
#define MONETDBE_VERSION_MAJOR 3
#define MONETDBE_VERSION_MINOR 0
#define MONETDBE_VERSION_PATCH 2
#define STREAM_VERSION "16.0.1"
#define STREAM_VERSION_MAJOR 16
#define STREAM_VERSION_MINOR 0
#define STREAM_VERSION_PATCH 1
#define SQL_VERSION "12.0.5"
#define SQL_VERSION_MAJOR 12
#define SQL_VERSION_MINOR 0
#define SQL_VERSION_PATCH 5
/* Host identifier */
#define HOST "amd64-pc-windows-gnu"
/* The used password hash algorithm */
#define MONETDB5_PASSWDHASH "SHA512"
/* The used password hash algorithm */
#define MONETDB5_PASSWDHASH_TOKEN SHA512
#ifndef _Noreturn
#ifdef __cplusplus
#define _Noreturn
#else
/* #undef _Noreturn */
#endif
#endif
/* Does your compiler support `inline' keyword? (C99 feature) */
#ifndef inline
#ifdef __cplusplus
#define inline
#else
/* #undef inline */
#endif
#endif
/* Does your compiler support `restrict' keyword? (C99 feature) */
#ifndef restrict
#ifdef __cplusplus
#define restrict
#else
/* #undef restrict */
#endif
#endif
// End Section: monetdb configure misc
// Section: monetdb configure sizes
#define SIZEOF_SIZE_T 8
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 8
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 4
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF_DOUBLE 8
#define SIZEOF_WCHAR_T 2
#define HAVE_LONG_LONG 1 /* for ODBC include files */
#ifdef _MSC_VER
#ifdef _WIN64
#define LENP_OR_POINTER_T SQLLEN *
#else
#define LENP_OR_POINTER_T SQLPOINTER
#endif
#else
/* #undef LENP_OR_POINTER_T */
#endif
/* #undef SIZEOF_SQLWCHAR */
/* #undef WORDS_BIGENDIAN */
/* Does your compiler support `ssize_t' type? (Posix type) */
#ifndef ssize_t
/* #undef ssize_t */
#endif
/* The size of `__int128', as computed by sizeof. */
#define SIZEOF___INT128 16
/* The size of `__int128_t', as computed by sizeof. */
#define SIZEOF___INT128_T 16
/* The size of `__uint128_t', as computed by sizeof. */
#define SIZEOF___UINT128_T 16
#define HAVE___INT128 1
#define HAVE___INT128_T 1
#define HAVE___UINT128_T 1
/* #undef HAVE_HGE */
#ifdef HAVE_HGE
#ifdef HAVE___INT128
typedef __int128 hge;
typedef unsigned __int128 uhge;
#define SIZEOF_HGE SIZEOF___INT128
#elif defined(HAVE___INT128_T) && defined(HAVE___UINT128_T)
typedef __int128_t hge;
typedef __uint128_t uhge;
#define SIZEOF_HGE SIZEOF___INT128_T
#endif
#endif
// End Section: monetdb configure sizes
/* Does your compiler support `__attribute__' extension? */
#if !defined(__GNUC__) && !defined(__clang__) && !defined(__attribute__)
#define __attribute__(a)
#endif
#if !defined(__cplusplus) || __cplusplus < 201103L
#ifndef static_assert
/* static_assert is a C11/C++11 feature, defined in assert.h which also exists
* in many other compilers we ignore it if the compiler doesn't support it
* However in C11 static_assert is a macro, while on C++11 is a keyword */
#define static_assert(expr, mesg) ((void) 0)
#endif
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h> /* strcasecmp */
#endif
#ifdef _MSC_VER
#define strdup(s) _strdup(s)
#ifndef strcasecmp
#define strcasecmp(x,y) _stricmp(x,y)
#endif
/* Define to 1 if you have the `strncasecmp' function. */
#define HAVE_STRNCASECMP 1
#ifndef strncasecmp
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
#include <sys/stat.h>
#ifdef lstat
#undef lstat
#endif
#define lstat _stat64
#ifdef stat
#undef stat
#endif
#define stat _stat64
#ifdef fstat
#undef fstat
#endif
#define fstat _fstat64
static inline char *
stpcpy(char *restrict dst, const char *restrict src)
{
size_t i;
for (i = 0; src[i]; i++)
dst[i] = src[i];
dst[i] = 0;
return dst + i;
}
/* Define to 1 if the system has the type `socklen_t'. */
#define HAVE_SOCKLEN_T 1
/* type used by connect */
#define socklen_t int
#define strtok_r(t,d,c) strtok_s(t,d,c)
#define HAVE_GETOPT_LONG 1
/* there is something very similar to localtime_r on Windows: */
#include <time.h>
#define HAVE_LOCALTIME_R 1
static inline struct tm *
localtime_r(const time_t *restrict timep, struct tm *restrict result)
{
return localtime_s(result, timep) == 0 ? result : NULL;
}
#define HAVE_GMTIME_R 1
static inline struct tm *
gmtime_r(const time_t *restrict timep, struct tm *restrict result)
{
return gmtime_s(result, timep) == 0 ? result : NULL;
}
/* Define if you have ctime_r(time_t*,char *buf,size_t s) */
#define HAVE_CTIME_R 1
#define HAVE_CTIME_R3 1
/* there is something very similar to ctime_r on Windows: */
#define ctime_r(t,b,s) (ctime_s(b,s,t) ? NULL : (b))
#endif /* _MSC_VER */
/* #undef HAVE_SOCKLEN_T */
#ifndef _MSC_VER
#define SOCKET int
#define closesocket close
#endif
#ifndef _In_z_
#define _In_z_
#endif
#ifndef _Printf_format_string_
#define _Printf_format_string_
#endif
#ifdef _MSC_VER
#define _LIB_STARTUP_FUNC_(f,q) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" q #f "_")) \
static void f(void)
#ifdef _WIN64
#define LIB_STARTUP_FUNC(f) _LIB_STARTUP_FUNC_(f,"")
#else
#define LIB_STARTUP_FUNC(f) _LIB_STARTUP_FUNC_(f,"_")
#endif
#else
#define LIB_STARTUP_FUNC(f) \
static void f(void) __attribute__((__constructor__)); \
static void f(void)
#endif
#endif /* MT_SEEN_MONETDB_CONFIG_H */

@ -0,0 +1,190 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V.
*/
#ifndef _MONETDBE_LIB_
#define _MONETDBE_LIB_
#include "monetdb_config.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#ifdef WIN32
#ifndef LIBMONETDBE
#define monetdbe_export extern __declspec(dllimport)
#else
#define monetdbe_export extern __declspec(dllexport)
#endif
#else
#define monetdbe_export extern
#endif
typedef int64_t monetdbe_cnt;
typedef struct {
unsigned char day;
unsigned char month;
short year;
} monetdbe_data_date;
typedef struct {
unsigned int ms;
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
} monetdbe_data_time;
typedef struct {
monetdbe_data_date date;
monetdbe_data_time time;
} monetdbe_data_timestamp;
typedef struct {
size_t size;
char* data;
} monetdbe_data_blob;
typedef enum {
monetdbe_bool, monetdbe_int8_t, monetdbe_int16_t, monetdbe_int32_t, monetdbe_int64_t,
#ifdef HAVE_HGE
monetdbe_int128_t,
#endif
monetdbe_size_t, monetdbe_float, monetdbe_double,
monetdbe_str, monetdbe_blob,
monetdbe_date, monetdbe_time, monetdbe_timestamp,
// should be last:
monetdbe_type_unknown
} monetdbe_types;
typedef struct {
char* name;
unsigned int scale;
unsigned int digits;
} monetdbe_sql_type;
typedef struct {
monetdbe_types type;
monetdbe_sql_type sql_type;
void *data;
size_t count;
char* name;
} monetdbe_column;
typedef struct {
size_t nparam;
monetdbe_types *type;
} monetdbe_statement;
typedef struct {
monetdbe_cnt nrows;
size_t ncols;
char *name;
monetdbe_cnt last_id; /* last auto incremented id */
} monetdbe_result;
typedef void* monetdbe_database;
typedef struct {
const char *host;
int port;
const char *database;
const char *username;
const char *password;
const char *lang;
} monetdbe_remote;
typedef struct {
const char *host;
const char* port;
const char* usock;
} monetdbe_mapi_server;
typedef struct {
int memorylimit; // top off the amount of RAM to be used, in MB
int querytimeout; // graceful terminate query after a few seconds
int sessiontimeout; // graceful terminate the session after a few seconds
int nr_threads; // maximum number of worker treads, limits level of parallelism
monetdbe_remote* remote;
monetdbe_mapi_server* mapi_server;
const char *trace_file; // file to which log output should be written
} monetdbe_options;
#define DEFAULT_STRUCT_DEFINITION(ctype, typename) \
typedef struct \
{ \
monetdbe_types type; \
monetdbe_sql_type sql_type; \
ctype *data; \
size_t count; \
char *name; \
ctype null_value; \
double scale; \
int (*is_null)(ctype *value); \
} monetdbe_column_##typename
DEFAULT_STRUCT_DEFINITION(int8_t, bool);
DEFAULT_STRUCT_DEFINITION(int8_t, int8_t);
DEFAULT_STRUCT_DEFINITION(int16_t, int16_t);
DEFAULT_STRUCT_DEFINITION(int32_t, int32_t);
DEFAULT_STRUCT_DEFINITION(int64_t, int64_t);
#ifdef HAVE_HGE
DEFAULT_STRUCT_DEFINITION(__int128, int128_t);
#endif
DEFAULT_STRUCT_DEFINITION(size_t, size_t);
DEFAULT_STRUCT_DEFINITION(float, float);
DEFAULT_STRUCT_DEFINITION(double, double);
DEFAULT_STRUCT_DEFINITION(char *, str);
DEFAULT_STRUCT_DEFINITION(monetdbe_data_blob, blob);
DEFAULT_STRUCT_DEFINITION(monetdbe_data_date, date);
DEFAULT_STRUCT_DEFINITION(monetdbe_data_time, time);
DEFAULT_STRUCT_DEFINITION(monetdbe_data_timestamp, timestamp);
// UUID, INET, XML ?
monetdbe_export const char *monetdbe_version(void);
monetdbe_export int monetdbe_open(monetdbe_database *db, char *url, monetdbe_options *opts);
/* 0 ok, -1 (allocation failed), -2 error in db */
monetdbe_export int monetdbe_close(monetdbe_database db);
monetdbe_export char* monetdbe_error(monetdbe_database db);
monetdbe_export char* monetdbe_get_autocommit(monetdbe_database dbhdl, int* result);
monetdbe_export char* monetdbe_set_autocommit(monetdbe_database dbhdl, int value);
monetdbe_export int monetdbe_in_transaction(monetdbe_database dbhdl);
monetdbe_export char* monetdbe_query(monetdbe_database dbhdl, char* query, monetdbe_result** result, monetdbe_cnt* affected_rows);
monetdbe_export char* monetdbe_result_fetch(monetdbe_result *mres, monetdbe_column** res, size_t column_index);
monetdbe_export char* monetdbe_cleanup_result(monetdbe_database dbhdl, monetdbe_result* result);
monetdbe_export char* monetdbe_prepare(monetdbe_database dbhdl, char *query, monetdbe_statement **stmt, monetdbe_result** result);
monetdbe_export char* monetdbe_bind(monetdbe_statement *stmt, void *data, size_t parameter_nr);
monetdbe_export char* monetdbe_execute(monetdbe_statement *stmt, monetdbe_result **result, monetdbe_cnt* affected_rows);
monetdbe_export char* monetdbe_cleanup_statement(monetdbe_database dbhdl, monetdbe_statement *stmt);
monetdbe_export char* monetdbe_append(monetdbe_database dbhdl, const char* schema, const char* table, monetdbe_column **input, size_t column_count);
monetdbe_export const void* monetdbe_null(monetdbe_database dbhdl, monetdbe_types t);
monetdbe_export char* monetdbe_get_columns(monetdbe_database dbhdl, const char* schema_name, const char *table_name, size_t *column_count, monetdbe_column **columns);
monetdbe_export char* monetdbe_dump_database(monetdbe_database dbhdl, const char *backupfile);
monetdbe_export char* monetdbe_dump_table(monetdbe_database dbhdl, const char *schema_name, const char *table_name, const char *backupfile);
monetdbe_export const char* monetdbe_get_mapi_port(void);
#ifdef __cplusplus
}
#endif
#endif

@ -1,14 +1,14 @@
CREATE TABLE sale(Month INT, sales INT)
CREATE TABLE sale(Mont INT, sales INT)
LOAD DATA INFILE "moving_avg.csv"
INTO TABLE sale
FIELDS TERMINATED BY "\t"
FIELDS TERMINATED BY ","
SELECT Month,avgs(3,sales)
SELECT Mont,avgs(3,sales)
FROM sale
ASSUMING ASC Month
ASSUMING ASC Mont
INTO OUTFILE "moving_avg_output.csv"
FIELDS TERMINATED BY ";"
select Month, mins(2,sales) from sale assuming desc Month group by sales
select Mont, mins(2,sales) from sale assuming desc Mont group by sales
into outfile "flatten.csv"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,5 +0,0 @@
#pragma once
template <class...T1, class ...T2>
struct lineage {
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -101,12 +101,14 @@
<LanguageStandard>stdcpplatest</LanguageStandard>
<ControlFlowGuard>Guard</ControlFlowGuard>
<EnableModules>true</EnableModules>
<AdditionalIncludeDirectories>$(ProjectDir)\..\monetdb\msvc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
<AssemblyDebug>true</AssemblyDebug>
<AdditionalDependencies>$(ProjectDir)\..\monetdb\msvc\monetdbe.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -118,6 +120,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>$(ProjectDir)\..\monetdb\msvc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -125,6 +128,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
<AdditionalDependencies>$(ProjectDir)\..\monetdb\msvc\monetdbe.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -141,12 +145,14 @@
<OmitFramePointers>false</OmitFramePointers>
<SmallerTypeCheck>true</SmallerTypeCheck>
<SupportJustMyCode>false</SupportJustMyCode>
<AdditionalIncludeDirectories>$(ProjectDir)\..\monetdb\msvc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
<AssemblyDebug>true</AssemblyDebug>
<AdditionalDependencies>$(ProjectDir)\..\monetdb\msvc\monetdbe.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -158,6 +164,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>$(ProjectDir)\..\monetdb\msvc</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -165,10 +172,12 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(ProjectDir)\..\dll.so</OutputFile>
<AdditionalDependencies>$(ProjectDir)\..\monetdb\msvc\monetdbe.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\out.cpp" />
<ClCompile Include="..\server\monetdb_conn.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\csv.h" />

Binary file not shown.

Binary file not shown.

@ -1,57 +1,21 @@
#include "./server/aggregations.h"
#include <unordered_map>
#include "csv.h"
#include "./server/hasher.h"
#include "./server/libaquery.h"
#include "./udf.hpp"
#include "./server/monetdb_conn.h"
#include "./server/aggregations.h"
extern "C" int __DLLEXPORT__ dllmain(Context* cxt) {
using namespace std;
using namespace types;
auto test = new TableInfo<int,int,int,int>("test", 4);
cxt->tables.insert({"test", test});
auto& test_a = *(ColRef<int> *)(&test->colrefs[0]);
auto& test_b = *(ColRef<int> *)(&test->colrefs[1]);
auto& test_c = *(ColRef<int> *)(&test->colrefs[2]);
auto& test_d = *(ColRef<int> *)(&test->colrefs[3]);
test_a.init("a");
test_b.init("b");
test_c.init("c");
test_d.init("d");
io::CSVReader<4> csv_reader_6pX2fy("test.csv");
csv_reader_6pX2fy.read_header(io::ignore_extra_column, "a","b","c","d");
int tmp_1E7DxvaO;
int tmp_5JwTTT4O;
int tmp_3gbplDAu;
int tmp_XK4BgA6z;
while(csv_reader_6pX2fy.read_row(tmp_1E7DxvaO,tmp_5JwTTT4O,tmp_3gbplDAu,tmp_XK4BgA6z)) {
test_a.emplace_back(tmp_1E7DxvaO);
test_b.emplace_back(tmp_5JwTTT4O);
test_c.emplace_back(tmp_3gbplDAu);
test_d.emplace_back(tmp_XK4BgA6z);
}
typedef record<decltype(test_a[0]),decltype(test_b[0]),decltype(test_d[0])> record_type61iBrX3;
unordered_map<record_type61iBrX3, vector_type<uint32_t>, transTypes<record_type61iBrX3, hasher>> g7sUysrP;
for (uint32_t i2I = 0; i2I < test_a.size; ++i2I){
g7sUysrP[forward_as_tuple(test_a[i2I],test_b[i2I],test_d[i2I])].emplace_back(i2I);
}
auto out_1SHu = new TableInfo<decays<decltype(sum(test_c))>,value_type<decays<decltype(test_b)>>,value_type<decays<decltype(test_d)>>>("out_1SHu", 3);
cxt->tables.insert({"out_1SHu", out_1SHu});
auto& out_1SHu_sumtestc = *(ColRef<decays<decltype(sum(test_c))>> *)(&out_1SHu->colrefs[0]);
auto& out_1SHu_b = *(ColRef<value_type<decays<decltype(test_b)>>> *)(&out_1SHu->colrefs[1]);
auto& out_1SHu_d = *(ColRef<value_type<decays<decltype(test_d)>>> *)(&out_1SHu->colrefs[2]);
out_1SHu_sumtestc.init("sumtestc");
out_1SHu_b.init("b");
out_1SHu_d.init("d");
for(auto& i64 : g7sUysrP) {
auto &key_645kbJO = i64.first;
auto &val_1UnUa89 = i64.second;
out_1SHu_sumtestc.emplace_back(sum(test_c[val_1UnUa89]));
out_1SHu_b.emplace_back(get<1>(key_645kbJO));
out_1SHu_d.emplace_back(get<2>(key_645kbJO));
}
auto d6tAcglo = out_1SHu->order_by_view<-3,1>();
print(d6tAcglo);
auto server = static_cast<Server*>(cxt->alt_server);
auto len_6WMRXO = server->cnt;
auto suma_6BP = ColRef<int64_t>(len_6WMRXO, server->getCol(0));
auto b_5Yb = ColRef<int>(len_6WMRXO, server->getCol(1));
auto c_2Vh = ColRef<int>(len_6WMRXO, server->getCol(2));
auto d_1Ma = ColRef<int>(len_6WMRXO, server->getCol(3));
auto out_2URo7p = new TableInfo<value_type<decays<decltype((paircorr(c_2Vh, b_5Yb) * d_1Ma))>>,int64_t,int>("out_2URo7p");
out_2URo7p->get_col<0>() = (paircorr(c_2Vh, b_5Yb) * d_1Ma);
out_2URo7p->get_col<1>().initfrom(suma_6BP);
out_2URo7p->get_col<2>().initfrom(b_5Yb);
print(*out_2URo7p);
return 0;
}

@ -1,11 +1,13 @@
import enum
import re
import time
import dbconn
# import dbconn
from mo_parsing import ParseException
import aquery_parser as parser
import engine
import engine.projection
import engine.ddl
import reconstruct as xengine
import subprocess
import mmap
@ -17,10 +19,17 @@ import atexit
import threading
import ctypes
import aquery_config
class RunType(enum.Enum):
Threaded = 0
IPC = 1
class Backend_Type(enum.Enum):
BACKEND_AQuery = 0
BACKEND_MonetDB = 1
BACKEND_MariaDB = 2
server_mode = RunType.Threaded
server_bin = 'server.bin' if server_mode == RunType.IPC else 'server.so'
@ -31,7 +40,6 @@ except Exception as e:
print(type(e), e)
nullstream = open(os.devnull, 'w')
subprocess.call(['make', server_bin], stdout=nullstream)
cleanup = True
@ -88,27 +96,20 @@ c = lambda _ba: ctypes.cast((ctypes.c_char * len(_ba)).from_buffer(_ba), ctypes.
class Config:
def __init__(self, nq = 0, mode = server_mode, n_bufs = 0, bf_szs = []) -> None:
self.int_size = 4
self.n_attrib = 4
self.n_attrib = 6
self.buf = bytearray((self.n_attrib + n_bufs) * self.int_size)
self.np_buf = np.ndarray(shape=(self.n_attrib), buffer=self.buf, dtype=np.int32)
self.new_query = nq
self.server_mode = mode.value
self.running = 1
self.backend_type = Backend_Type.BACKEND_AQuery.value
self.has_dll = 0
self.n_buffers = n_bufs
def __getter (self, *, i):
def getter (self, *, i):
return self.np_buf[i]
def __setter(self, v, *, i):
def setter(self, v, *, i):
self.np_buf[i] = v
def binder(_i):
from functools import partial
return property(partial(Config.__getter, i = _i), partial(Config.__setter, i = _i))
running = binder(0)
new_query = binder(1)
server_mode = binder(2)
backend_type = binder(3)
n_buffers = binder(4)
def set_bufszs(self, buf_szs):
for i in range(min(len(buf_szs), self.n_buffers)):
@ -118,14 +119,27 @@ class Config:
def c(self):
return c(self.buf)
def binder(cls, attr, _i):
from functools import partial
setattr(cls, attr, property(partial(cls.getter, i = _i), partial(cls.setter, i = _i)))
binder(Config, 'running', 0)
binder(Config, 'new_query', 1)
binder(Config, 'server_mode', 2)
binder(Config, 'backend_type', 3)
binder(Config, 'has_dll', 4)
binder(Config, 'n_buffers', 5)
cfg = Config()
th = None
send = None
def init_threaded():
if os.name == 'nt':
if os.name == 'nt' and aquery_config.add_path_to_ldpath:
t = os.environ['PATH'].lower().split(';')
vars = re.compile('%.*%')
os.add_dll_directory(os.path.abspath('.'))
os.add_dll_directory(os.path.abspath('./lib'))
for e in t:
if(len(e) != 0):
if '%' in e:
@ -133,13 +147,20 @@ def init_threaded():
m_e = vars.findall(e)
for m in m_e:
e = e.replace(m, os.environ[m[1:-1]])
# print(m, e)
except Exception:
continue
try:
os.add_dll_directory(e)
except Exception:
continue
else:
os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.abspath('.')
os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.abspath('./lib')
server_so = ctypes.CDLL('./'+server_bin)
global cfg, th
global cfg, th, send
send = server_so['receive_args']
th = threading.Thread(target=server_so['main'], args=(-1, ctypes.POINTER(ctypes.c_char_p)(cfg.c)), daemon=True)
th.start()
@ -172,7 +193,7 @@ q = 'SELECT p.Name, v.Name FROM Production.Product p JOIN Purchasing.ProductVend
res = parser.parse(q)
payload = None
keep = True
cxt = engine.initialize()
cxt.Info(res)
@ -184,34 +205,49 @@ while test_parser:
time.sleep(.00001)
print("> ", end="")
q = input().lower()
if q == 'exec':
if not keep or cxt is None:
cxt = engine.initialize()
else:
cxt.new()
stmts_stmts = stmts['stmts']
if type(stmts_stmts) is list:
for s in stmts_stmts:
engine.generate(s, cxt)
else:
engine.generate(stmts_stmts, cxt)
cxt.Info(cxt.ccode)
with open('out.cpp', 'wb') as outfile:
outfile.write((cxt.finalize()).encode('utf-8'))
if q == 'exec': # generate build and run (AQuery Engine)
cfg.backend_type = Backend_Type.BACKEND_AQuery.value
cxt = engine.exec(stmts, cxt, keep)
if subprocess.call(['make', 'snippet'], stdout = nullstream) == 0:
set_ready()
continue
if q == 'xexec':
cxt = xengine.initialize()
stmts_stmts = stmts['stmts']
if type(stmts_stmts) is list:
for s in stmts_stmts:
xengine.generate(s, cxt)
elif q == 'xexec': # generate build and run (MonetDB Engine)
cfg.backend_type = Backend_Type.BACKEND_MonetDB.value
cxt = xengine.exec(stmts, cxt, keep)
if server_mode == RunType.Threaded:
# assignment to avoid auto gc
sqls = [s.strip() for s in cxt.sql.split(';')]
qs = [ctypes.c_char_p(bytes(q, 'utf-8')) for q in sqls if len(q)]
sz = len(qs)
payload = (ctypes.c_char_p*sz)(*qs)
send(sz, payload)
if cxt.udf is not None:
with open('udf.hpp', 'wb') as outfile:
outfile.write(cxt.udf.encode('utf-8'))
if cxt.has_dll:
with open('out.cpp', 'wb') as outfile:
outfile.write((cxt.finalize()).encode('utf-8'))
subprocess.call(['make', 'snippet'], stdout = nullstream)
cfg.has_dll = 1
else:
xengine.generate(stmts_stmts, cxt)
print(cxt.sql)
cfg.has_dll = 0
set_ready()
continue
elif q == 'dbg':
import code
var = globals().copy()
var.update(locals())
sh = code.InteractiveConsole(var)
try:
code.interact()
except BaseException as e:
# don't care about anything happened in interactive console
pass
elif q.startswith('log'):
qs = re.split(' |\t', q)
if len(qs) > 1:
@ -232,11 +268,11 @@ while test_parser:
subprocess.call(['clang-format', 'out.cpp'])
elif q == 'exit':
break
elif q == 'r':
elif q == 'r': # build and run
if subprocess.call(['make', 'snippet']) == 0:
set_ready()
continue
elif q == 'rr':
elif q == 'rr': # run
set_ready()
continue
elif q.startswith('save'):
@ -263,13 +299,10 @@ while test_parser:
print(e)
continue
except (ValueError, FileNotFoundError) as e:
# rm()
# init()
print(e)
except (KeyboardInterrupt):
break
except (Exception) as e:
except:
rm()
raise e
raise
rm()

@ -0,0 +1,32 @@
Exception: STATUS_ACCESS_VIOLATION at rip=005A43E1EE8
rax=000000080016C970 rbx=00000000FFFFC2E0 rcx=0000000000000015
rdx=00000000FFFFCE00 rsi=0000000000000000 rdi=0000000000000002
r8 =00000000000000A8 r9 =000000080016C970 r10=0000000000005150
r11=000000080016C970 r12=00000000FFFFFFFF r13=0000000000000000
r14=00006FFFFFEBA2F8 r15=00000000FFFFC380
rbp=00000000FFFFC210 rsp=00000000FFFFC160
program=C:\msys64\usr\bin\python3.exe, pid 821, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
000FFFFC210 005A43E1EE8 (00000000000, 0057B699D00, 00000000050, 000FFFFC2A0)
000FFFFC210 00487B249A1 (0000000000A, 000FFFFC2F0, 00000000002, 000FFFFC3A0)
000FFFFC2A0 00487B245EE (000FFFC68F0, 00000000002, 6FFFFFEBA2F8, 00000000000)
000FFFFC3A0 00487B247B2 (004484CACEA, 00800187A50, 004484CACDA, 000FFFFC2D0)
000FFFFC3A0 004484CAE74 (0057B4D31A2, 00500001101, 00000000000, 00800187A50)
00000000000 004484C476D (6FFFFFF97DF0, 00000000000, 0057B539C7B, 6FFFFFE9AF40)
004484C4660 0057B509F6F (6FFFFFFC68F0, 6FFFFFEA2330, 0057B547BA7, 00000000000)
00800048F80 0057B6910D9 (0080016ABE0, 6FFF00000000, 0057B68A0EA, 0057B72B2E0)
00000000000 0057B5D0C61 (6FFFFFE9F190, 000FFFFC7F0, 0057B5E3A05, 00000000000)
6FFFFFF30220 0057B5D0FD1 (0080016ABF0, 6FFFFFF93D30, 0057B618338, 6FFFFFF34D00)
6FFFFFF30220 0057B60C6B0 (6FFFFFE9A0B0, 0080004A920, 6FFFFFE9F190, 6FFFFFEE2610)
6FFFFFF30220 0057B60C8B4 (0057B50A49A, 00000000000, 0057B539B2F, 000FFFFCAB8)
6FFFFFF30220 0057B60EE21 (00000000000, 000FFFFCAB8, 00000000001, 0057B731792)
0057B699678 0057B60F0B6 (0057B618804, 000FFFFCD30, 0057B604F54, 00800049350)
000FFFFCD30 0057B60FA20 (00000000000, 000FFFFC968, 000FFFFCD30, 00000000001)
000FFFFCD30 0057B62ABDD (001004016D0, 001004016D0, 00000000000, 000FFFFCD30)
000FFFFCD30 0057B62AE9D (00180049B25, 00180048A40, 00000000002, 00180326FE0)
000FFFFCD30 00180049B91 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0 00180047716 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0 001800477C4 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

@ -1,11 +1,31 @@
from reconstruct.ast import Context, ast_node
saved_cxt = None
def initialize():
return Context()
def initialize(cxt = None, keep = False):
global saved_cxt
if cxt is None or not keep or type(cxt) is not Context:
if saved_cxt is None or not keep:
cxt = Context()
saved_cxt = cxt
else:
cxt = saved_cxt
cxt.new()
return cxt
def generate(ast, cxt):
for k in ast.keys():
if k in ast_node.types.keys():
ast_node.types[k](None, ast, cxt)
__all__ = ["initialize", "generate"]
def exec(stmts, cxt = None, keep = False):
cxt = initialize(cxt, keep)
stmts_stmts = stmts['stmts']
if type(stmts_stmts) is list:
for s in stmts_stmts:
generate(s, cxt)
else:
generate(stmts_stmts, cxt)
cxt.print(cxt.sql)
return cxt
__all__ = ["initialize", "generate", "exec", "saved_cxt"]

@ -1,4 +1,7 @@
from engine.utils import enlist, base62uuid, base62alp
from re import T
from typing import Set, Tuple
from engine.types import *
from engine.utils import enlist, base62uuid, base62alp, get_leagl_name
from reconstruct.storage import Context, TableInfo, ColRef
class ast_node:
@ -76,29 +79,59 @@ class projection(ast_node):
# deal with projections
self.out_table = TableInfo('out_'+base62uuid(4), [], self.context)
cols = []
col_exprs = []
col_ext : Set[ColRef]= set()
col_exprs : List[Tuple[str, Types]] = []
proj_map = dict()
var_table = dict()
for i, proj in enumerate(self.projections):
compound = False
self.datasource.rec = set()
name = ''
this_type = AnyT
if type(proj) is dict:
if 'value' in proj:
e = proj['value']
name = expr(self, e).sql
disp_name = ''.join([a if a in base62alp else '' for a in name])
proj_expr = expr(self, e)
this_type = proj_expr.type
name = proj_expr.sql
compound = True # compound column
if not proj_expr.is_special:
y = lambda x:x
name = eval('f\'' + name + '\'')
if name not in var_table:
var_table[name] = len(col_exprs)
proj_map[i] = [this_type, len(col_exprs)]
col_exprs.append((name, proj_expr.type))
else:
self.context.headers.add('"./server/aggregations.h"')
if self.datasource.rec is not None:
col_ext = col_ext.union(self.datasource.rec)
proj_map[i] = [this_type, proj_expr.sql]
if 'name' in proj: # renaming column by AS keyword
name += ' ' + proj['name']
col_exprs.append(name)
name += ' AS ' + proj['name']
if not proj_expr.is_special:
var_table[proj['name']] = len(col_exprs)
disp_name = get_leagl_name(name)
elif type(proj) is str:
col = self.datasource.get_col(proj)
this_type = col.type
name = col.name
self.datasource.rec = None
# TODO: Type deduction in Python
cols.append(ColRef('unknown', self.out_table, None, disp_name, i, compound=compound))
self.add(', '.join(col_exprs))
cols.append(ColRef(this_type, self.out_table, None, disp_name, i, compound=compound))
col_ext = [c for c in col_ext if c.name not in var_table] # remove duplicates in var_table
col_ext_names = [c.name for c in col_ext]
self.add(', '.join([c[0] for c in col_exprs] + col_ext_names))
_base_offset = len(col_exprs)
for i, col in enumerate(col_ext_names):
if col not in var_table:
var_table[col] = i + _base_offset
def finialize(astnode:ast_node):
if(astnode is not None):
@ -110,13 +143,50 @@ class projection(ast_node):
if 'orderby' in node:
self.add(orderby(self, node['orderby']).sql)
if 'outfile' in node:
self.add(outfile(self, node['outfile']).sql)
self.sql = outfile(self, node['outfile'], sql = self.sql).sql
if self.parent is None:
self.emit(self.sql+';\n')
else:
# TODO: subquery, name create tmp-table from subquery w/ alias as name
pass
# cpp module codegen
self.context.has_dll = True
# extract typed-columns from result-set
vid2cname = [0]*len(var_table)
pyname2cname = dict()
typenames = [c[1] for c in col_exprs] + [c.type for c in col_ext]
length_name = 'len_' + base62uuid(6)
self.context.emitc(f'auto {length_name} = server->cnt;')
for v, idx in var_table.items():
vname = get_leagl_name(v) + '_' + base62uuid(3)
pyname2cname[v] = vname
self.context.emitc(f'auto {vname} = ColRef<{typenames[idx].cname}>({length_name}, server->getCol({idx}));')
vid2cname[idx] = vname
# Create table into context
outtable_name = 'out_' + base62uuid(6)
out_typenames = [None] * len(proj_map)
for key, val in proj_map.items():
if type(val[1]) is str:
x = True
y = lambda t: pyname2cname[t]
val[1] = eval('f\'' + val[1] + '\'')
if val[0] == LazyT:
out_typenames[key] = f'value_type<decays<decltype({val[1]})>>'
else:
out_typenames[key] = val[0].cname
# out_typenames = [v[0].cname for v in proj_map.values()]
self.context.emitc(f'auto {outtable_name} = new TableInfo<{",".join(out_typenames)}>("{outtable_name}");')
for key, val in proj_map.items():
if type(val[1]) is int:
self.context.emitc(f'{outtable_name}->get_col<{key}>().initfrom({vid2cname[val[1]]});')
else:
# for funcs evaluate f_i(x, ...)
self.context.emitc(f'{outtable_name}->get_col<{key}>() = {val[1]};')
# print out col_is
self.context.emitc(f'print(*{outtable_name});')
class orderby(ast_node):
name = 'order by'
@ -147,6 +217,7 @@ class join(ast_node):
self.joins:list = []
self.tables = []
self.tables_dir = dict()
self.rec = None
# self.tmp_name = 'join_' + base62uuid(4)
# self.datasource = TableInfo(self.tmp_name, [], self.context)
def append(self, tbls, __alias = ''):
@ -169,7 +240,7 @@ class join(ast_node):
def produce(self, node):
if type(node) is list:
for d in node:
self.append(join(self, d).__str__())
self.append(join(self, d))
elif type(node) is dict:
alias = ''
@ -205,7 +276,10 @@ class join(ast_node):
def get_cols(self, colExpr: str) -> ColRef:
for t in self.tables:
if colExpr in t.columns_byname:
return t.columns_byname[colExpr]
col = t.columns_byname[colExpr]
if type(self.rec) is set:
self.rec.add(col)
return col
def parse_col_names(self, colExpr:str) -> ColRef:
parsedColExpr = colExpr.split('.')
@ -245,7 +319,7 @@ class create_table(ast_node):
self.sql = f'CREATE TABLE {tbl.table_name}('
columns = []
for c in tbl.columns:
columns.append(f'{c.name} {c.type.upper()}')
columns.append(f'{c.name} {c.type.sqlname}')
self.sql += ', '.join(columns)
self.sql += ')'
if self.context.use_columnstore:
@ -275,7 +349,13 @@ class insert(ast_node):
class load(ast_node):
name="load"
first_order = name
def produce(self, node):
def init(self, _):
if self.context.dialect == 'MonetDB':
self.produce = self.produce_monetdb
else:
self.produce = self.produce_aq
def produce_aq(self, node):
node = node['load']
s1 = 'LOAD DATA INFILE '
s2 = 'INTO TABLE '
@ -284,15 +364,96 @@ class load(ast_node):
if 'term' in node:
self.sql += f' {s3} \"{node["term"]["literal"]}\"'
def produce_monetdb(self, node):
node = node['load']
s1 = f'COPY OFFSET 2 INTO {node["table"]} FROM '
s2 = ' ON SERVER '
s3 = ' USING DELIMITERS '
import os
p = os.path.abspath(node['file']['literal']).replace('\\', '/')
self.sql = f'{s1} \'{p}\' {s2} '
if 'term' in node:
self.sql += f' {s3} \'{node["term"]["literal"]}\''
class outfile(ast_node):
name="_outfile"
def produce(self, node):
def __init__(self, parent, node, context = None, *, sql = None):
super().__init__(parent, node, context)
self.sql = sql
if self.context.dialect == 'MonetDB':
self.produce = self.produce_monetdb
else:
self.produce = self.produce_aq
def produce_aq(self, node):
filename = node['loc']['literal'] if 'loc' in node else node['literal']
self.sql = f'INTO OUTFILE "{filename}"'
self.sql += f'INTO OUTFILE "{filename}"'
if 'term' in node:
self.sql += f' FIELDS TERMINATED BY \"{node["term"]["literal"]}\"'
def produce_monetdb(self, node):
filename = node['loc']['literal'] if 'loc' in node else node['literal']
import os
p = os.path.abspath('.').replace('\\', '/') + '/' + filename
self.sql = f'COPY {self.sql} INTO "{p}"'
d = '\t'
e = '\n'
if 'term' in node:
d = node['term']['literal']
self.sql += f' delimiters \'{d}\', \'{e}\''
class udf(ast_node):
name = 'udf'
first_order = name
def __call__(self, c_code = False, *args):
from engine.types import fn_behavior
return fn_behavior(self, c_code, *args)
def return_type(self, *_ : Types):
return LazyT
def init(self, node):
self.var_table = {}
self.args = []
if self.context.udf is None:
self.context.udf = Context.udf_head
self.context.headers.add('\"./udf.hpp\"')
def produce(self, node):
from engine.utils import get_leagl_name, check_leagl_name
node = node[self.name]
# register udf
self.cname = get_leagl_name(node['fname'])
self.sqlname = self.cname
self.context.udf_map[self.cname] = self
self.ccode = f'auto {self.cname} = []('
def consume(self, node):
from engine.utils import get_leagl_name, check_leagl_name
node = node[self.name]
if 'params' in node:
for args in node['params']:
cname = get_leagl_name(args)
self.var_table[args] = cname
self.args.append(cname)
self.ccode += ', '.join([f'auto {a}' for a in self.args]) + ') {\n'
if 'assignment' in node:
for assign in node['assignment']:
var = assign['var']
ex = expr(self, assign['expr'], c_code=True)
if var in self.var_table:
self.ccode += f'\t{var} = {ex.eval()};\n'
else:
cvar = get_leagl_name(var)
self.var_table[var] = cvar
self.ccode += f'\tauto {cvar} = {ex.eval()};\n'
ret = node['ret']
self.ccode += f'\treturn {expr(self, ret, c_code=True).eval()};'
self.ccode += '\n};\n'
print(self.ccode)
self.context.udf += self.ccode + '\n'
def include(objs):
import inspect

@ -1,56 +1,33 @@
from reconstruct.ast import ast_node
from reconstruct.storage import ColRef, TableInfo
from reconstruct.storage import ColRef
from engine.types import *
class expr(ast_node):
name='expr'
builtin_func_maps = {
'max': 'MAX',
'min': 'MIN',
'avg': 'AVG',
'sum': 'SUM',
'count' : 'COUNT',
'mins': ['mins', 'minw'],
'maxs': ['maxs', 'maxw'],
'avgs': ['avgs', 'avgw'],
'sums': ['sums', 'sumw'],
}
binary_ops = {
'sub':'-',
'add':'+',
'mul':'*',
'div':'/',
'mod':'%',
'and':' AND ',
'or':' OR ',
'xor' : ' XOR ',
'gt':'>',
'lt':'<',
'le':'<=',
'gt':'>='
}
compound_ops = {
}
unary_ops = {
'neg' : '-',
'not' : ' NOT '
}
def __init__(self, parent, node, *, c_code = None):
from reconstruct.ast import projection
coumpound_generating_ops = ['avgs', 'mins', 'maxs', 'sums'] + \
list(binary_ops.keys()) + list(compound_ops.keys()) + list(unary_ops.keys() )
def __init__(self, parent, node):
self.type = None
self.raw_col = None
self.inside_agg = False
self.is_special = False
if(type(parent) is expr):
self.inside_agg = parent.inside_agg
if(type(parent) is not expr):
self.root = self
self.c_code = type(parent) is projection
else:
self.root = parent.root
self.c_code = parent.c_code
if type(c_code) is bool:
self.c_code = c_code
ast_node.__init__(self, parent, node, None)
def init(self, _):
from engine.projection import projection
from reconstruct.ast import projection
parent = self.parent
self.isvector = parent.isvector if type(parent) is expr else False
self.is_compound = parent.is_compound if type(parent) is expr else False
@ -59,70 +36,73 @@ class expr(ast_node):
else:
self.datasource = self.context.datasource
self.udf_map = parent.context.udf_map
self.func_maps = {**self.udf_map, **self.builtin_func_maps}
self.func_maps = {**builtin_func, **self.udf_map}
self.operators = {**builtin_operators, **self.udf_map}
def produce(self, node):
from engine.utils import enlist
if type(node) is dict:
for key, val in node.items():
if key in self.func_maps:
# TODO: distinguish between UDF agg functions and other UDF functions.
self.inside_agg = True
if type(val) is list and len(val) > 1:
cfunc = self.func_maps[key]
cfunc = cfunc[len(val) - 1] if type(cfunc) is list else cfunc
self.sql += f"{cfunc}("
for i, p in enumerate(val):
self.sql += expr(self, p).sql + (',' if i < len(val) - 1 else '')
else:
funcname = self.func_maps[key]
funcname = funcname[0] if type(funcname) is list else funcname
self.sql += f"{funcname}("
self.sql += expr(self, val).sql
self.sql += ')'
self.inside_agg = False
elif key in self.binary_ops:
l = expr(self, val[0]).sql
r = expr(self, val[1]).sql
self.sql += f'({l}{self.binary_ops[key]}{r})'
elif key in self.compound_ops:
x = []
if type(val) is list:
for v in val:
x.append(expr(self, v).sql)
self.sql = self.compound_ops[key][1](x)
elif key in self.unary_ops:
self.sql += f'{self.unary_ops[key]}({expr(self, val).sql})'
else:
print(f'Undefined expr: {key}{val}')
if key in self.coumpound_generating_ops and not self.is_compound:
self.is_compound = True
if key in self.operators:
op = self.operators[key]
val = enlist(val)
exp_vals = [expr(self, v, c_code = self.c_code) for v in val]
str_vals = [e.sql for e in exp_vals]
type_vals = [e.type for e in exp_vals]
self.type = op.return_type(*type_vals)
self.sql = op(self.c_code, *str_vals)
special_func = [*self.context.udf_map.keys(), "maxs", "mins", "avgs", "sums"]
if key in special_func and not self.is_special:
self.is_special = True
p = self.parent
while type(p) is expr and not p.is_compound:
p.is_compound = True
while type(p) is expr and not p.is_special:
p.is_special = True
p = p.parent
else:
print(f'Undefined expr: {key}{val}')
elif type(node) is str:
p = self.parent
while type(p) is expr and not p.isvector:
p.isvector = True
p = p.parent
if self.datasource is not None:
self.raw_col = self.datasource.parse_col_names(node)
self.raw_col = self.raw_col if type(self.raw_col) is ColRef else None
if self.raw_col is not None:
self.sql = self.raw_col.name
self.type = self.raw_col.type
else:
self.sql = node
self.type = StrT
if self.c_code and self.datasource is not None:
self.sql = f'{{y(\"{self.sql}\")}}'
elif type(node) is bool:
self.type = IntT
if self.c_code:
self.sql = '1' if node else '0'
else:
self.sql = 'TRUE' if node else 'FALSE'
else:
self.sql = f'{node}'
if type(node) is int:
self.type = LongT
elif type(node) is float:
self.type = DoubleT
def finalize(self, y):
if self.c_code:
x = self.is_special
self.sql = eval('f\'' + self.sql + '\'')
def __str__(self):
return self.sql
def __repr__(self):
return self.__str__()
def eval(self):
x = self.c_code
y = lambda x: x
return eval('f\'' + self.sql + '\'')
import engine.expr as cexpr

@ -1,5 +1,11 @@
from engine.types import *
class ColRef:
def __init__(self, _ty, cobj, table:'TableInfo', name, id, compound = False):
self.type : Types = AnyT
if type(_ty) is str:
self.type = builtin_types[_ty.lower()]
elif type(_ty) is Types:
self.type = _ty
self.cobj = cobj
self.table = table
@ -19,7 +25,6 @@ class ColRef:
def __setitem__(self, key, value):
self.__arr__[key] = value
class TableInfo:
def __init__(self, table_name, cols, cxt:'Context'):
# statics
@ -39,6 +44,7 @@ class TableInfo:
def add_cols(self, cols, new = True):
for i, c in enumerate(cols):
self.add_col(c, new, i)
def add_col(self, c, new = True, i = 0):
_ty = c['type']
if new:
@ -56,10 +62,14 @@ class TableInfo:
return
self.cxt.tables_byname[alias] = self
self.alias.add(alias)
def parse_col_names(self, colExpr) -> ColRef:
parsedColExpr = colExpr.split('.')
if len(parsedColExpr) <= 1:
return self.columns_byname[colExpr]
col = self.columns_byname[colExpr]
if type(self.rec) is set:
self.rec.add(col)
return col
else:
datasource = self.cxt.tables_byname[parsedColExpr[0]]
if datasource is None:
@ -69,8 +79,15 @@ class TableInfo:
class Context:
def __init__(self):
def new(self):
self.headers = set(['\"./server/libaquery.h\"',
'\"./server/monetdb_conn.h\"'])
self.ccode = ''
self.sql = ''
self.finalized = False
self.udf = None
def __init__(self):
self.tables_byname = dict()
self.col_byname = dict()
self.tables = []
@ -78,13 +95,41 @@ class Context:
self.datasource = None
self.udf_map = dict()
self.use_columnstore = False
self.print = print
self.has_dll = False
self.dialect = 'MonetDB'
self.new()
def emit(self, sql:str):
self.sql += sql + ' '
def emitc(self, c:str):
self.ccode += c + '\n'
def add_table(self, table_name, cols):
tbl = TableInfo(table_name, cols, self)
self.tables.append(tbl)
return tbl
function_head = '''
extern "C" int __DLLEXPORT__ dllmain(Context* cxt) {
using namespace std;
using namespace types;
auto server = static_cast<Server*>(cxt->alt_server);
'''
udf_head = ('#pragma once\n'
'#include \"./server/libaquery.h\"\n'
'#include \"./server/aggregations.h\"\n\n'
)
def finalize(self):
if not self.finalized:
headers = ''
for h in self.headers:
if h[0] != '"':
headers += '#include <' + h + '>\n'
else:
headers += '#include ' + h + '\n'
self.ccode = headers + self.function_head + self.ccode + 'return 0;\n}'
self.headers = set()
return self.ccode

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,2 @@
#TargetFrameworkVersion=:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.19041.0
Release|Win32|d:\gg\AQuery++\server\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -3,6 +3,9 @@
#include <utility>
#include <limits>
#include <deque>
#include <cmath>
#undef max
#undef min
template <class T, template<typename ...> class VT>
size_t count(const VT<T>& v) {
return v.size;
@ -24,6 +27,16 @@ types::GetFPType<T> avg(const VT<T>& v) {
return static_cast<types::GetFPType<T>>(
sum<T>(v) / static_cast<long double>(v.size));
}
template<class T, template<typename ...> class VT>
VT<double> sqrt(const VT<T>& v) {
VT<double> ret {v.size};
for (uint32_t i = 0; i < v.size; ++i){
ret[i] = sqrt(v[i]);
}
return ret;
}
template <class T, template<typename ...> class VT>
T max(const VT<T>& v) {
T max_v = std::numeric_limits<T>::min();
@ -128,8 +141,8 @@ decayed_t<VT, types::GetLongType<T>> sumw(uint32_t w, const VT<T>& arr) {
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> avgw(uint32_t w, const VT<T>& arr) {
typedef types::GetFPType<T> FPType;
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgw(uint32_t w, const VT<T>& arr) {
typedef types::GetFPType<types::GetLongType<T>> FPType;
const uint32_t& len = arr.size;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;

@ -16,7 +16,8 @@ enum Backend_Type {
BACKEND_MariaDB
};
struct Config{
int running, new_query, server_mode, backend_type, n_buffers;
int running, new_query, server_mode,
backend_type, has_dll, n_buffers;
int buffer_sizes[];
};
@ -31,7 +32,7 @@ struct Context{
void **buffers;
void* alt_server;
Log_level log_level = LOG_SILENT;
Log_level log_level = LOG_INFO;
printf_type print = printf;
template <class ...Types>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save