bug fix on select into

This commit is contained in:
2022-09-21 17:23:50 +08:00
parent 48beab441d
commit 34a9fe105c
12 changed files with 305 additions and 111 deletions
+12 -5
View File
@@ -232,9 +232,9 @@ def ext (fx):
# operator call behavior
def binary_op_behavior(op:OperatorBase, c_code, x, y):
def binary_op_behavior(op:OperatorBase, c_code, *xs):
name = op.cname if c_code else op.sqlname
return f'({x} {name} {y})'
return f'({f" {name} ".join(xs)})'
def unary_op_behavior(op:OperatorBase, c_code, x):
name = op.cname if c_code else op.sqlname
@@ -248,10 +248,16 @@ def count_behavior(op:OperatorBase, c_code, x, distinct = False):
if not c_code:
return f'{op.sqlname}({"distinct " if distinct else ""}{x})'
elif distinct:
return '({x}).distinct_size()'
return f'({x}).distinct_size()'
else:
return '{count()}'
def distinct_behavior(op:OperatorBase, c_code, x):
if not c_code:
return f'{op.sqlname}({x})'
else:
return f'({x}).distinct()'
def windowed_fn_behavor(op: OperatorBase, c_code, *x):
if not c_code:
return f'{op.sqlname}({", ".join([f"{xx}" for xx in x])})'
@@ -277,6 +283,7 @@ oplte = OperatorBase('lte', 2, logical, cname = '<=', sqlname = '<=', call = bin
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)
opdistinct = OperatorBase('distinct', 1, as_is, cname = '.distinct()', sqlname = 'distinct', call = distinct_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)
@@ -315,7 +322,7 @@ 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_unary_special = _op_make_dict(spnull, opdistinct)
builtin_cstdlib = _op_make_dict(fnsqrt, fnlog, fnsin, fncos, fntan, fnpow)
builtin_func = _op_make_dict(fnmax, fnmin, fnsum, fnavg, fnmaxs, fnmins, fndeltas, fnlast, fnsums, fnavgs, fncnt)
user_module_func = {}
+47 -1
View File
@@ -1,3 +1,5 @@
from collections import OrderedDict
from collections.abc import MutableMapping, Mapping
import uuid
lower_alp = 'abcdefghijklmnopqrstuvwxyz'
@@ -7,6 +9,50 @@ base62alp = nums + lower_alp + upper_alp
reserved_monet = ['month']
class CaseInsensitiveDict(MutableMapping):
def __init__(self, data=None, **kwargs):
self._store = OrderedDict()
if data is None:
data = {}
self.update(data, **kwargs)
def __setitem__(self, key, value):
# Use the lowercased key for lookups, but store the actual
# key alongside the value.
self._store[key.lower()] = (key, value)
def __getitem__(self, key):
return self._store[key.lower()][1]
def __delitem__(self, key):
del self._store[key.lower()]
def __iter__(self):
return (casedkey for casedkey, mappedvalue in self._store.values())
def __len__(self):
return len(self._store)
def lower_items(self):
"""Like iteritems(), but with all lowercase keys."""
return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
def __eq__(self, other):
if isinstance(other, Mapping):
other = CaseInsensitiveDict(other)
else:
return NotImplemented
# Compare insensitively
return dict(self.lower_items()) == dict(other.lower_items())
# Copy is required
def copy(self):
return CaseInsensitiveDict(self._store.values())
def __repr__(self):
return str(dict(self.items()))
def base62uuid(crop=8):
_id = uuid.uuid4().int
ret = ''
@@ -60,7 +106,7 @@ def defval(val, default):
return default if val is None else val
# escape must be readonly
from typing import Set
from typing import Mapping, Set
def remove_last(pattern : str, string : str, escape : Set[str] = set()) -> str:
idx = string.rfind(pattern)
if idx == -1:
+91 -44
View File
@@ -61,9 +61,16 @@ class projection(ast_node):
pass
def produce(self, node):
p = node['select']
self.projections = p if type(p) is list else [p]
self.add('SELECT')
self.has_postproc = False
if 'select' in node:
p = node['select']
self.distinct = False
elif 'select_distinct' in node:
p = node['select_distinct']
self.distinct = True
self.projections = p if type(p) is list else [p]
if self.parent is None:
self.context.sql_begin()
self.postproc_fname = 'dll_' + base62uuid(6)
@@ -75,8 +82,8 @@ class projection(ast_node):
if 'from' in node:
from_clause = node['from']['table_source']
self.datasource = join(self, from_clause)
if 'assumptions' in from_clause:
self.assumptions = enlist(from_clause['assumptions'])
if 'assumptions' in node['from']:
self.assumptions = enlist(node['from']['assumptions'])
if self.datasource is not None:
self.datasource_changed = True
@@ -109,61 +116,82 @@ class projection(ast_node):
proj_map : Dict[int, List[Union[Types, int, str, expr]]]= dict()
self.var_table = dict()
# self.sp_refs = set()
for i, proj in enumerate(self.projections):
i = 0
for proj in self.projections:
compound = False
self.datasource.rec = set()
name = ''
this_type = AnyT
if type(proj) is dict:
if type(proj) is dict or proj == '*':
if 'value' in proj:
e = proj['value']
proj_expr = expr(self, e)
this_type = proj_expr.type
name = proj_expr.sql
compound = True # compound column
proj_expr.cols_mentioned = self.datasource.rec
alias = ''
if 'name' in proj: # renaming column by AS keyword
alias = proj['name']
if not proj_expr.is_special:
elif proj == '*':
e = '*'
else:
print('unknown projection', proj)
proj_expr = expr(self, e)
sql_expr = expr(self, e, c_code=False)
this_type = proj_expr.type
name = proj_expr.sql
compound = True # compound column
proj_expr.cols_mentioned = self.datasource.rec
alias = ''
if 'name' in proj: # renaming column by AS keyword
alias = proj['name']
if not proj_expr.is_special:
if proj_expr.node == '*':
name = [c.get_full_name() for c in self.datasource.rec]
else:
y = lambda x:x
name = eval('f\'' + name + '\'')
count = lambda : 'count(*)'
name = enlist(sql_expr.eval(False, y, count=count))
for n in name:
offset = len(col_exprs)
if name not in self.var_table:
self.var_table[name] = offset
if n not in self.var_table:
self.var_table[n] = offset
if proj_expr.is_ColExpr and type(proj_expr.raw_col) is ColRef:
for n in (proj_expr.raw_col.table.alias):
self.var_table[f'{n}.'+name] = offset
for _alias in (proj_expr.raw_col.table.alias):
self.var_table[f'{_alias}.'+n] = offset
proj_map[i] = [this_type, offset, proj_expr]
col_expr = name + ' AS ' + alias if alias else name
col_expr = n + ' AS ' + alias if alias else n
if alias:
self.var_table[alias] = offset
col_exprs.append((col_expr, proj_expr.type))
else:
self.context.headers.add('"./server/aggregations.h"')
if self.datasource.rec is not None:
self.col_ext = self.col_ext.union(self.datasource.rec)
proj_map[i] = [this_type, proj_expr.sql, proj_expr]
disp_name = get_legal_name(alias if alias else name)
i += 1
else:
self.context.headers.add('"./server/aggregations.h"')
self.has_postproc = True
if self.datasource.rec is not None:
self.col_ext = self.col_ext.union(self.datasource.rec)
proj_map[i] = [this_type, proj_expr.sql, proj_expr]
i += 1
name = enlist(name)
disp_name = [get_legal_name(alias if alias else n) for n in name]
elif type(proj) is str:
col = self.datasource.get_col(proj)
this_type = col.type
disp_name = proj
print('Unknown behavior:', proj, 'is str')
# name = col.name
self.datasource.rec = None
# TODO: Type deduction in Python
cols.append(ColRef(this_type, self.out_table, None, disp_name, i, compound=compound))
for n in disp_name:
cols.append(ColRef(this_type, self.out_table, None, n, len(cols), compound=compound))
self.out_table.add_cols(cols, new = False)
if 'groupby' in node:
self.group_node = groupby(self, node['groupby'])
if self.group_node.use_sp_gb:
self.has_postproc = True
else:
self.group_node = None
if not self.has_postproc and self.distinct:
self.add('DISTINCT')
self.col_ext = [c for c in self.col_ext if c.name not in self.var_table] # remove duplicates in self.var_table
col_ext_names = [c.name for c in self.col_ext]
self.add(', '.join([c[0] for c in col_exprs] + col_ext_names))
@@ -249,7 +277,7 @@ class projection(ast_node):
self.group_node and
(self.group_node.use_sp_gb and
val[2].cols_mentioned.intersection(
self.datasource.all_cols.difference(self.group_node.refs))
self.datasource.all_cols().difference(self.group_node.refs))
) and val[2].is_compound # compound val not in key
# or
# (not self.group_node and val[2].is_compound)
@@ -282,25 +310,37 @@ class projection(ast_node):
# for funcs evaluate f_i(x, ...)
self.context.emitc(f'{self.out_table.contextname_cpp}->get_col<{key}>() = {val[1]};')
# print out col_is
self.context.emitc(f'print(*{self.out_table.contextname_cpp});')
if 'into' not in node:
self.context.emitc(f'print(*{self.out_table.contextname_cpp});')
if self.outfile:
self.outfile.finalize()
if 'into' in node:
self.context.emitc(select_into(self, node['into']).ccode)
if not self.distinct:
self.finalize()
def finalize(self):
self.context.emitc(f'puts("done.");')
if self.parent is None:
self.context.sql_end()
self.context.postproc_end(self.postproc_fname)
class select_distinct(projection):
first_order = 'select_distinct'
def consume(self, node):
super().consume(node)
if self.has_postproc:
self.context.emitc(
f'{self.out_table.table_name}->distinct();'
)
self.finalize()
class select_into(ast_node):
def init(self, node):
if type(self.parent) is projection:
if isinstance(self.parent, projection):
if self.context.has_dll:
# has postproc put back to monetdb
self.produce = self.produce_cpp
@@ -308,8 +348,8 @@ class select_into(ast_node):
self.produce = self.produce_sql
else:
raise ValueError('parent must be projection')
def produce_cpp(self, node):
assert(type(self.parent) is projection)
if not hasattr(self.parent, 'out_table'):
raise Exception('No out_table found.')
else:
@@ -508,7 +548,7 @@ class groupby(ast_node):
return False
def produce(self, node):
if type(self.parent) is not projection:
if not isinstance(self.parent, projection):
raise ValueError('groupby can only be used in projection')
node = enlist(node)
@@ -554,7 +594,7 @@ class join(ast_node):
self.tables : List[TableInfo] = []
self.tables_dir = dict()
self.rec = None
self.top_level = self.parent and type(self.parent) is projection
self.top_level = self.parent and isinstance(self.parent, projection)
self.have_sep = False
# self.tmp_name = 'join_' + base62uuid(4)
# self.datasource = TableInfo(self.tmp_name, [], self.context)
@@ -636,9 +676,16 @@ class join(ast_node):
datasource.rec = None
return ret
@property
# @property
def all_cols(self):
return set([c for t in self.tables for c in t.columns])
ret = set()
for table in self.tables:
rec = table.rec
table.rec = self.rec
ret.update(table.all_cols())
table.rec = rec
return ret
def consume(self, node):
self.sql = ''
for j in self.joins:
@@ -787,7 +834,7 @@ class outfile(ast_node):
self.sql = sql if sql else ''
def init(self, _):
assert(type(self.parent) is projection)
assert(isinstance(self.parent, projection))
if not self.parent.use_postproc:
if self.context.dialect == 'MonetDB':
self.produce = self.produce_monetdb
+17 -9
View File
@@ -1,4 +1,4 @@
from typing import Optional
from typing import Optional, Set
from reconstruct.ast import ast_node
from reconstruct.storage import ColRef, Context
from engine.types import *
@@ -199,11 +199,8 @@ class expr(ast_node):
self.udf_decltypecall = ex_vname.sql
else:
print(f'Undefined expr: {key}{val}')
if 'distinct' in val and key != count:
if self.c_code:
self.sql = 'distinct ' + self.sql
elif self.is_compound:
self.sql = '(' + self.sql + ').distinct()'
if type(node) is str:
if self.is_udfexpr:
curr_udf : udf = self.root.udf
@@ -235,8 +232,13 @@ class expr(ast_node):
# get the column from the datasource in SQL context
else:
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 (node == '*' and
not (type(self.parent) is expr
and 'count' in self.parent.node)):
self.datasource.all_cols()
else:
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.is_ColExpr = True
table_name = ''
@@ -259,10 +261,16 @@ class expr(ast_node):
self.is_compound = True
self.opname = self.raw_col
else:
self.sql = '\'' + node + '\''
self.sql = '\'' + node + '\'' if node != '*' else '*'
self.type = StrT
self.opname = self.sql
if self.c_code and self.datasource is not None:
if (type(self.parent) is expr and
'distinct' in self.parent.node and
not self.is_special):
# this node is executed by monetdb
# gb condition, not special
self.sql = f'distinct({self.sql})'
self.sql = f'{{y(\"{self.sql}\")}}'
elif type(node) is bool:
self.type = BoolT
+19 -3
View File
@@ -1,5 +1,5 @@
from engine.types import *
from engine.utils import base62uuid, enlist
from engine.utils import CaseInsensitiveDict, base62uuid, enlist
from typing import List, Dict, Set
class ColRef:
@@ -20,6 +20,18 @@ class ColRef:
# e.g. order by, group by, filter by expressions
self.__arr__ = (_ty, cobj, table, name, id)
def get_full_name(self):
table_name = self.table.table_name
it_alias = iter(self.table.alias)
alias = next(it_alias, table_name)
try:
while alias == table_name:
alias = next(it_alias)
except StopIteration:
alias = table_name
return f'{alias}.{self.name}'
def __getitem__(self, key):
if type(key) is str:
return getattr(self, key)
@@ -35,7 +47,7 @@ class TableInfo:
self.table_name : str = table_name
self.contextname_cpp : str = ''
self.alias : Set[str] = set([table_name])
self.columns_byname : Dict[str, ColRef] = dict() # column_name, type
self.columns_byname : Dict[str, ColRef] = CaseInsensitiveDict() # column_name, type
self.columns : List[ColRef] = []
self.cxt = cxt
# keep track of temp vars
@@ -85,7 +97,11 @@ class TableInfo:
raise ValueError(f'Table name/alias not defined{parsedColExpr[0]}')
else:
return datasource.parse_col_names(parsedColExpr[1])
def all_cols(self):
if type(self.rec) is set:
self.rec.update(self.columns)
return set(self.columns)
class Context:
def new(self):
+1 -1
View File
@@ -1,4 +1,4 @@
example:
g++-9 -shared -fPIC example.cpp aquery_mem.cpp -fno-semantic-interposition -Ofast -march=native -flto --std=c++1z -o ../test.so
$(CXX) -shared -fPIC example.cpp aquery_mem.cpp -fno-semantic-interposition -Ofast -march=native -flto --std=c++1z -o ../test.so
all: example
+2 -2
View File
@@ -75,7 +75,7 @@ extern void register_memory(void* ptr, deallocator_t deallocator);
__AQEXPORT__(void) init_session(Context* cxt);
#define __AQ_NO_SESSION__ __AQEXPORT__(void) init_session(Context*) {}
void* memcpy(void*, void*, unsigned long long);
void* memcpy(void*, const void*, unsigned long long);
struct ColRef_storage {
void* container;
unsigned int capacity, size;
@@ -86,4 +86,4 @@ struct ColRef_storage {
memcpy(this, &vt, sizeof(ColRef_storage));
}
};
#endif
#endif
+2 -2
View File
@@ -117,9 +117,9 @@ decayed_t<VT, types::GetLongType<T>> sums(const VT<T>& arr) {
return ret;
}
template<class T, template<typename ...> class VT>
decayed_t<VT, types::GetFPType<T>> avgs(const VT<T>& arr) {
decayed_t<VT, types::GetFPType<types::GetLongType<T>>> avgs(const VT<T>& arr) {
const uint32_t& len = arr.size;
typedef types::GetFPType<T> FPType;
typedef types::GetFPType<types::GetLongType<T>> FPType;
decayed_t<VT, FPType> ret(len);
uint32_t i = 0;
types::GetLongType<T> s;
+67 -14
View File
@@ -26,6 +26,21 @@ namespace types {
struct Coercion;
}
#endif
template <template <class...> class VT, class T>
std::ostream& operator<<(std::ostream& os, const VT<T>& v)
{
v.out();
return os;
}
#ifdef __AQ__HAS__INT128__
std::ostream& operator<<(std::ostream& os, __int128 & v);
std::ostream& operator<<(std::ostream& os, __uint128_t & v);
#endif
std::ostream& operator<<(std::ostream& os, types::date_t & v);
std::ostream& operator<<(std::ostream& os, types::time_t & v);
std::ostream& operator<<(std::ostream& os, types::timestamp_t & v);
template<typename _Ty>
class ColView;
template<typename _Ty>
@@ -200,19 +215,7 @@ public:
}
inline ColRef<_Ty> subvec(uint32_t start = 0) { return subvec_deep(start, size); }
};
template <template <class...> class VT, class T>
std::ostream& operator<<(std::ostream& os, const VT<T>& v)
{
v.out();
return os;
}
std::ostream& operator<<(std::ostream& os, types::date_t & v);
std::ostream& operator<<(std::ostream& os, types::time_t & v);
std::ostream& operator<<(std::ostream& os, types::timestamp_t & v);
#ifdef __AQ__HAS__INT128__
std::ostream& operator<<(std::ostream& os, __int128 & v);
std::ostream& operator<<(std::ostream& os, __uint128_t & v);
#endif
template <class Type>
struct decayed_impl<ColView, Type> { typedef ColRef<Type> type; };
@@ -433,7 +436,10 @@ struct TableInfo {
template <size_t ...Is>
void inline
reserve(std::index_sequence<Is...>, uint32_t size) {
const auto& assign_sz = [&size](auto& col){ col.size = size;};
const auto& assign_sz = [&size](auto& col){
col.size = size;
col.grow();
};
(assign_sz(get_col<Is>()), ...);
}
template <size_t ...Is>
@@ -481,6 +487,53 @@ struct TableView {
template <size_t j = 0>
typename std::enable_if < j < sizeof...(Types) - 1, void>::type print_impl(const uint32_t& i, const char* __restrict sep = " ") const;
template <size_t ...Is>
decltype(auto) inline
get_record(std::index_sequence<Is...>, uint32_t i) {
return std::forward_as_tuple(info.template get_col<Is>()[idxs[i]] ...);
}
TableInfo<Types ...>* get_tableinfo(const char* name = nullptr, const char** names = nullptr) {
if (name == nullptr)
name = info.name;
const char* info_names[sizeof...(Types)];
if (name == nullptr) {
for(uint32_t i = 0; i < sizeof...(Types); ++i)
info_names[i] = info.colrefs[i].name;
names = info_names;
}
return new TableInfo<Types ...>(name, names);
}
TableInfo<Types ...>* materialize(const char* name = nullptr, const char** names = nullptr) {
std::make_index_sequence<sizeof...(Types)> seq;
auto table = get_tableinfo(name, names);
table->reserve(seq, idxs->size);
for (uint32_t i = 0; i < idxs->size; ++i) {
table->set_record(get_record(i));
}
return table;
}
TableInfo<Types ...>* distinct(const char* name = nullptr, const char** names = nullptr) {
std::unordered_set<tuple_type> d_records;
std::make_index_sequence<sizeof...(Types)> seq;
for (uint32_t j = 0; j < idxs->size; ++j) {
d_records.insert(get_record(seq, j));
}
TableInfo<Types ...>* ret = get_tableinfo(name, names);
ret->reserve(seq, d_records.size());
uint32_t i = 0;
for (const auto& dr : d_records) {
ret->set_record(seq, dr, i++);
}
return ret;
}
~TableView() {
delete idxs;
}
+18 -7
View File
@@ -9,7 +9,7 @@
#include "monetdbe.h"
inline constexpr monetdbe_types AQType_2_monetdbe[] = {
monetdbe_int32_t, monetdbe_float, monetdbe_str, monetdbe_double, monetdbe_int64_t,
monetdbe_int32_t, monetdbe_float, monetdbe_str, monetdbe_double, monetdbe_double, monetdbe_int64_t,
#ifdef HAVE_HGE
monetdbe_int128_t,
#else
@@ -22,7 +22,8 @@ inline constexpr monetdbe_types AQType_2_monetdbe[] = {
#else
monetdbe_int64_t,
#endif
monetdbe_int16_t, monetdbe_int8_t, monetdbe_bool, monetdbe_int64_t, monetdbe_int64_t, monetdbe_int64_t
monetdbe_int16_t, monetdbe_int8_t, monetdbe_bool, monetdbe_int64_t,
monetdbe_timestamp, monetdbe_int64_t, monetdbe_int64_t
};
template<class ...Ts>
@@ -34,23 +35,33 @@ void TableInfo<Ts ...>::monetdb_append_table(void* srv, const char* alt_name) {
monetdbe_column** monetdbe_cols = new monetdbe_column * [sizeof...(Ts)];
uint32_t i = 0;
const auto get_col = [&monetdbe_cols, &i](auto v) {
puts("getcols...");
const auto get_col = [&monetdbe_cols, &i, *this](auto v) {
printf("%d %d\n", i, (ColRef<void>*)v - colrefs);
monetdbe_cols[i++] = (monetdbe_column*)v->monetdb_get_col();
};
(get_col((ColRef<Ts>*)(colrefs + i)), ...);
puts("getcols done");
for(int i = 0; i < sizeof...(Ts); ++i)
{
printf("no:%d name: %s count:%d data: %p \n",
i, monetdbe_cols[i]->name, monetdbe_cols[i]->count, monetdbe_cols[i]->data);
}
std::string create_table_str = "CREATE TABLE ";
create_table_str += alt_name;
create_table_str += " (";
i = 0;
const auto get_name_type = [&i, *this]() {
return std::string(colrefs[i++].name) + ' ';
const auto get_name_type = [&i, *this, &create_table_str](auto v) {
create_table_str+= std::string(colrefs[i++].name) + ' ' +
std::string(types::SQL_Type[types::Types<std::remove_pointer_t<decltype(v)>>::getType()]) + ", ";
};
create_table_str += ((get_name_type() + types::SQL_Type[types::Types<Ts>::getType()] + ", ") + ... + std::string(""));
(get_name_type((Ts*)(0)), ...);
auto last_comma = create_table_str.find_last_of(',');
if (last_comma != static_cast<decltype(last_comma)>(-1)) {
create_table_str[last_comma] = ')';
Server* server = (Server*)srv;
puts("create table...");
puts(create_table_str.c_str());
server->exec(create_table_str.c_str());
if (!server->last_error) {
auto err = monetdbe_append(*((monetdbe_database*)server->server), "sys", alt_name, monetdbe_cols, sizeof...(Ts));
+1 -1
View File
@@ -28,7 +28,7 @@ namespace types {
};
static constexpr const char* printf_str[] = { "%d", "%f", "%s", "%lf", "%Lf", "%ld", "%d", "%hi", "%s", "%s", "%c",
"%u", "%lu", "%s", "%hu", "%hhu", "%s", "%s", "Vector<%s>", "%s", "NULL", "ERROR" };
static constexpr const char* SQL_Type[] = { "INT", "REAL", "TEXT", "DOUBLE", "DOUBLE", "BIGINT", "HUGEINT", "SMALLINT", "DATE", "TIME", "TINYINT",
static constexpr const char* SQL_Type[] = { "INT", "REAL", "VARCHAR(15)", "DOUBLE", "DOUBLE", "BIGINT", "HUGEINT", "SMALLINT", "DATE", "TIME", "TINYINT",
"INT", "BIGINT", "HUGEINT", "SMALLINT", "TINYINT", "BIGINT", "BOOL", "BIGINT", "TIMESTAMP", "NULL", "ERROR"};
+28 -22
View File
@@ -1,27 +1,27 @@
-- please run datagen.get_stock_data() to generate data/stock.csv first
-- create table ticks(ID varchar(10), timestamp int, tradeDate date, price int);
create table ticks(ID varchar(10), timestamp int, tradeDate date, price int);
-- LOAD DATA INFILE "data/stock.csv"
-- INTO TABLE ticks
-- FIELDS TERMINATED BY ","
LOAD DATA INFILE "data/stock.csv"
INTO TABLE ticks
FIELDS TERMINATED BY ","
-- SELECT max(price-mins(price))
-- FROM ticks ASSUMING ASC timestamp
-- WHERE ID="S"
-- AND tradeDate='2003-01-10'
SELECT max(price-mins(price))
FROM ticks ASSUMING ASC timestamp
WHERE ID="S"
AND tradeDate='2003-01-10'
-- create table base(ID varchar(10), name varchar(10));
create table base(ID varchar(10), name varchar(10));
-- LOAD DATA INFILE "data/base.csv"
-- INTO TABLE base
-- FIELDS TERMINATED BY ","
LOAD DATA INFILE "data/base.csv"
INTO TABLE base
FIELDS TERMINATED BY ","
-- SELECT last(price)
-- FROM ticks t, base b
-- ASSUMING ASC name, ASC timestamp
-- WHERE t.ID=b.ID
-- AND name="x"
SELECT last(price)
FROM ticks t, base b
ASSUMING ASC name, ASC timestamp
WHERE t.ID=b.ID
AND name="x"
create table TradedStocks(ID varchar(15), SeqNo int, TradeDate date, TimeStamp time, Type varchar(5));
create table HistoricQuotes(ID varchar(15), TradeDate date, HighPrice real, LowPrice real, ClosePrice real, OpenPrice real, volume bigint);
@@ -33,9 +33,15 @@ LOAD DATA INFILE "data/hist-price-file.csv"
INTO TABLE HistoricQuotes
FIELDS TERMINATED BY "|"
select distinct ID, TradeDate
into td
from TradedStocks
-- -- Monetdb wont recognize right table when
-- -- doing a natural join
SELECT ts.ID, avgs(10, hq.ClosePrice)
FROM TradedStocks AS ts NATURAL JOIN
HistoricQuotes AS hq
ASSUMING ASC hq.TradeDate
GROUP BY ts.ID
SELECT ID, avgs(10, ClosePrice)
FROM td NATURAL JOIN
HistoricQuotes
ASSUMING ASC TradeDate
GROUP BY ID
ORDER BY ID