Compare commits

...

9 Commits

Author SHA1 Message Date
vaclavt
4faaf38986 WIP on indexes cat 2022-07-03 07:23:15 +02:00
vaclavt
17445d0bd6 index scan is default on 2022-06-02 14:21:43 +02:00
vaclavt
525694fbae double is alias for float 2022-05-31 19:26:07 +02:00
vaclavt
a063e14f3e crash fix in distinct (strict weak ordering) 2022-05-31 19:25:47 +02:00
vaclavt
33f7cba493 memory crash here 2022-05-23 21:17:21 +02:00
vaclavt
f3a43fdafc better error message 2022-05-23 19:28:33 +02:00
vaclavt
4074c541c3 formating 2022-05-23 19:28:15 +02:00
vaclavt
a51be01072 init version of sys cat 2022-05-23 19:27:48 +02:00
vaclavt
dadad69958 a bit of work on conversion functions 2022-04-03 16:46:39 +02:00
12 changed files with 186 additions and 57 deletions

View File

@@ -1,11 +1,18 @@
### WIP ### WIP
compare in row.cpp shoud take into account m_visible
### TODO ### TODO
- create local_install.sh - create local_install.sh
- change float type keyword to double and in code functions too
- add functions:
- coalesce
- now
- rtrim, ltrim, rpad, lpad
- round
- set xxx - without value to reset to default value - set xxx - without value to reset to default value
- coalesce, date functions now; string functions rtrim, ltrim, rpad, lpad; math function round
- add pipe | concatenation - add pipe | concatenation
- add support for 1_000_000 numbers - add support for 1_000_000 numbers
- expand_asterix_char should support multiple and everywhere * - expand_asterix_char should support multiple and everywhere *

42
debug.h
View File

@@ -10,27 +10,30 @@ std::vector<std::string> k_debug_sql_commands {
// "delete from history_earnings_dates where symbol='BABA' and datetime=to_date('2021-11-04', '%Y-%m-%d')", // "delete from history_earnings_dates where symbol='BABA' and datetime=to_date('2021-11-04', '%Y-%m-%d')",
// "select * from history_earnings_dates" // "select * from history_earnings_dates"
// "create table sf1 (symbol varchar(8) not null, dimension varchar(3), calendar_date date, date_key date, report_period date, last_updated date, accoci float, assets float, assetsavg float, assetsc float, assetsnc float, assetturnover float, bvps float, capex float, cashneq float, cashnequsd float, cor float, consolinc float, currentratio float, de float, debt float, debtc float, debtnc float, debtusd float, deferredrev float, depamor float, deposits float, divyield float, dps float, ebit float, ebitda float, ebitdamargin float, ebitdausd float, ebitusd float, ebt float, eps float, epsdil float, epsusd float, equity float, equityavg float, equityusd float, ev float, evebit float, evebitda float, fcf float, fcfps float, fxusd float, gp float, grossmargin float, intangibles float, intexp float, invcap float, invcapavg float, inventory float, investments float, investmentsc float, investmentsnc float, liabilities float, liabilitiesc float, liabilitiesnc float, marketcap float, ncf float, ncfbus float, ncfcommon float, ncfdebt float, ncfdiv float, ncff float, ncfi float, ncfinv float, ncfo float, ncfx float, netinc float, netinccmn float, netinccmnusd float, netincdis float, netincnci float, netmargin float, opex float, opinc float, payables float, payoutratio float, pb float, pe float, pe1 float, ppnenet float, prefdivis float, price float, ps float, ps1 float, receivables float, retearn float, revenue float, revenueusd float, rnd float, roa float, roe float, roic float, ros float, sbcomp float, sgna float, sharefactor float, sharesbas float, shareswa float, shareswadil float, sps float, tangibles float, taxassets float, taxexp float, taxliabilities float, tbvps float, workingcapital float)", "create table sf1 (symbol varchar(8) not null, dimension varchar(3), calendar_date date, date_key date, report_period date, last_updated date, accoci float, assets float, assetsavg float, assetsc float, assetsnc float, assetturnover float, bvps float, capex float, cashneq float, cashnequsd float, cor float, consolinc float, currentratio float, de float, debt float, debtc float, debtnc float, debtusd float, deferredrev float, depamor float, deposits float, divyield float, dps float, ebit float, ebitda float, ebitdamargin float, ebitdausd float, ebitusd float, ebt float, eps float, epsdil float, epsusd float, equity float, equityavg float, equityusd float, ev float, evebit float, evebitda float, fcf float, fcfps float, fxusd float, gp float, grossmargin float, intangibles float, intexp float, invcap float, invcapavg float, inventory float, investments float, investmentsc float, investmentsnc float, liabilities float, liabilitiesc float, liabilitiesnc float, marketcap float, ncf float, ncfbus float, ncfcommon float, ncfdebt float, ncfdiv float, ncff float, ncfi float, ncfinv float, ncfo float, ncfx float, netinc float, netinccmn float, netinccmnusd float, netincdis float, netincnci float, netmargin float, opex float, opinc float, payables float, payoutratio float, pb float, pe float, pe1 float, ppnenet float, prefdivis float, price float, ps float, ps1 float, receivables float, retearn float, revenue float, revenueusd float, rnd float, roa float, roe float, roic float, ros float, sbcomp float, sgna float, sharefactor float, sharesbas float, shareswa float, shareswadil float, sps float, tangibles float, taxassets float, taxexp float, taxliabilities float, tbvps float, workingcapital float)",
// "set 'DATE_FORMAT' = '%Y-%m-%d'", "set 'DATE_FORMAT' = '%Y-%m-%d'",
// "create index sf1_symbol on sf1(symbol)", "create index sf1_symbol on sf1(symbol)",
// "load into sf1 '/srv/SHARADAR_SF1.csv'", "load into sf1 '/srv/SHARADAR_SF1.csv'",
// "set 'USE_INDEXSCAN' = 'true'",
"select distinct dimension from sf1 where symbol = 'ALLY'",
"select calendar_date, calendar_date, dimension from sf1 where symbol = 'ALLY' and dimension = 'MRQ' and calendar_date <= 1653487723 order by calendar_date desc limit 10",
// "set 'USE_INDEXSCAN' = 'false'", // "set 'USE_INDEXSCAN' = 'false'",
// "select dimension, to_string(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5", // "select dimension, to_char(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "set 'USE_INDEXSCAN' = 'true'", // "set 'USE_INDEXSCAN' = 'true'",
// "select dimension, to_string(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5", // "select dimension, to_char(calendar_date, '%d.%m.%Y'), pp(eps, \"%.2f\"), pp(shareswadil), pp(revenue), pp(netinc), pp(cashneq), pp(assets), pp(debt), pp(ncfdebt), pp(roe*100), pp(intangibles), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ' order by dimension, calendar_date desc limit 5",
// "select max(calendar_date), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ'", // "select max(calendar_date), calendar_date from sf1 where symbol = 'MU' and dimension = 'ARQ'",
// "select max(calendar_date), min(calendar_date) from sf1 where symbol = 'MU' and dimension = 'ARQ'" // "select max(calendar_date), min(calendar_date) from sf1 where symbol = 'MU' and dimension = 'ARQ'"
"create table a (i integer not null, s varchar(64))", // "create table a (i integer not null, s varchar(64))",
"create index a_i on a(i)", // "create index a_i on a(i)",
// "insert into a (i, s) values(1, 'one')", // "insert into a (i, s) values(1, 'one')",
// "insert into a (i, s) values(2, 'two')", // "insert into a (i, s) values(2, 'two')",
// "insert into a (i, s) values(2, 'second two')", // "insert into a (i, s) values(2, 'second two')",
// "insert into a (i, s) values(3, 'three')", // "insert into a (i, s) values(3, 'three')",
// "insert into a (i, s) values(4, 'four')", // "insert into a (i, s) values(4, 'four')",
"insert into a (i) values(5)", // "insert into a (i) values(5)",
"save a into '/tmp/a.csv'", // "save a into '/tmp/a.csv'",
"set 'USE_INDEXSCAN' = 'true'", // "set 'USE_INDEXSCAN' = 'true'",
// "select * from a where 1 = i", // "select * from a where 1 = i",
// "delete from a where i = 2 and s ='two'", // "delete from a where i = 2 and s ='two'",
// "select * from a where i = 2", // "select * from a where i = 2",
@@ -40,6 +43,21 @@ std::vector<std::string> k_debug_sql_commands {
// "select min(i), max(i), count(i) from a", // "select min(i), max(i), count(i) from a",
// "select i + 1000 from a", // "select i + 1000 from a",
// "select i, s from a where i = 5", // "select i, s from a where i = 5",
"select i, s, coalesce(s, i) from a where i = 5" // "select i, s, coalesce(s, i) from a where i = 5",
// "create table a (i float, j float)",
// "insert into a (i, j) values(null, 123456789.12345)",
// "select pp(coalesce(i, j)) from a",
// "create table d (datetime date)",
// "insert into d (datetime) values(1648634993)",
// "select to_char(datetime, '%Y%m%d') from d",
// "select to_int(datetime) from d",
// "select max(to_char(datetime, '%Y%m%d')) from d",
// "select max(to_int(to_float(to_char(datetime, '%Y%m%d')))) from d",
// "select * from usql_tables",
// "select * from usql_columns",
// "select * from usql_indexes",
}; };

View File

@@ -162,7 +162,7 @@ TokenType Lexer::type(const std::string &token) {
if (token == "not") return TokenType::keyword_not; if (token == "not") return TokenType::keyword_not;
if (token == "null") return TokenType::keyword_null; if (token == "null") return TokenType::keyword_null;
if (token == "integer") return TokenType::keyword_integer; if (token == "integer") return TokenType::keyword_integer;
if (token == "float") return TokenType::keyword_float; if (token == "float" || token == "double") return TokenType::keyword_float;
if (token == "varchar") return TokenType::keyword_varchar; if (token == "varchar") return TokenType::keyword_varchar;
if (token == "date") return TokenType::keyword_date; if (token == "date") return TokenType::keyword_date;
if (token == "boolean") return TokenType::keyword_bool; if (token == "boolean") return TokenType::keyword_bool;

View File

@@ -385,19 +385,18 @@ namespace usql {
std::unique_ptr<Node> Parser::parse_where_clause() { std::unique_ptr<Node> Parser::parse_where_clause() {
if (m_lexer.tokenType() != TokenType::keyword_where) { if (m_lexer.tokenType() != TokenType::keyword_where) {
return std::make_unique<TrueNode>(); return std::make_unique<TrueNode>();
} }
m_lexer.skipToken(TokenType::keyword_where); m_lexer.skipToken(TokenType::keyword_where);
std::unique_ptr<Node> left = parse_expression(); std::unique_ptr<Node> left = parse_expression();
do { do {
left = parse_expression(std::move(left)); left = parse_expression(std::move(left));
} while (m_lexer.tokenType() != TokenType::eof && m_lexer.tokenType() != TokenType::keyword_order && m_lexer.tokenType() != TokenType::keyword_offset && m_lexer.tokenType() != TokenType::keyword_limit && m_lexer.tokenType() != TokenType::semicolon);
} while (m_lexer.tokenType() != TokenType::eof && m_lexer.tokenType() != TokenType::keyword_order && m_lexer.tokenType() != TokenType::keyword_offset && m_lexer.tokenType() != TokenType::keyword_limit);
return left; return left;
} }
std::unique_ptr<Node> Parser::parse_expression() { std::unique_ptr<Node> Parser::parse_expression() {

View File

@@ -126,8 +126,10 @@ struct ColDefNode : Node {
struct FunctionNode : Node { struct FunctionNode : Node {
enum class Type { enum class Type {
to_string, to_char,
to_date, to_date,
to_int,
to_float,
date_add, date_add,
pp, pp,
lower, lower,
@@ -139,13 +141,15 @@ struct FunctionNode : Node {
}; };
static Type get_function(const std::string &str) { static Type get_function(const std::string &str) {
if (str=="to_string") return Type::to_string; if (str=="to_char") return Type::to_char;
if (str=="to_date") return Type::to_date; if (str=="to_date") return Type::to_date;
if (str=="to_int") return Type::to_int;
if (str=="to_float") return Type::to_float;
if (str=="date_add") return Type::date_add; if (str=="date_add") return Type::date_add;
if (str=="pp") return Type::pp; if (str=="pp") return Type::pp;
if (str=="lower") return Type::lower; if (str=="lower") return Type::lower;
if (str=="upper") return Type::upper; if (str=="upper") return Type::upper;
if (str=="coalesce") return Type::coalesce; if (str=="coalesce") return Type::coalesce;
if (str=="min") return Type::min; if (str=="min") return Type::min;
if (str=="max") return Type::max; if (str=="max") return Type::max;
if (str=="count") return Type::count; if (str=="count") return Type::count;
@@ -154,8 +158,10 @@ struct FunctionNode : Node {
}; };
static std::string function_name(const Type type) { static std::string function_name(const Type type) {
if (type == Type::to_string) return "to_string"; if (type == Type::to_char) return "to_char";
if (type == Type::to_date) return "to_date"; if (type == Type::to_date) return "to_date";
if (type == Type::to_int) return "to_int";
if (type == Type::to_float) return "to_float";
if (type == Type::date_add) return "date_add"; if (type == Type::date_add) return "date_add";
if (type == Type::pp) return "pp"; if (type == Type::pp) return "pp";
if (type == Type::lower) return "lower"; if (type == Type::lower) return "lower";
@@ -169,9 +175,6 @@ struct FunctionNode : Node {
}; };
Type function;
std::vector<std::unique_ptr<Node>> params;
FunctionNode(std::string func_name, std::vector<std::unique_ptr<Node>> pars) : FunctionNode(std::string func_name, std::vector<std::unique_ptr<Node>> pars) :
Node(NodeType::function), function(get_function(func_name)), params(std::move(pars)) {} Node(NodeType::function), function(get_function(func_name)), params(std::move(pars)) {}
@@ -193,6 +196,9 @@ struct FunctionNode : Node {
} }
std::cout << ")" << std::endl; std::cout << ")" << std::endl;
} }
Type function;
std::vector<std::unique_ptr<Node>> params;
}; };
struct TrueNode : Node { struct TrueNode : Node {
@@ -575,7 +581,6 @@ struct CreateIndexNode : Node {
}; };
class Parser { class Parser {
private:
public: public:
Parser(); Parser();

2
row.h
View File

@@ -171,7 +171,7 @@ public:
case 5: case 5:
return (ColValue &) *std::get_if<ColBooleanValue>(&m_columns[i]); return (ColValue &) *std::get_if<ColBooleanValue>(&m_columns[i]);
default: default:
throw Exception("should not happen"); throw Exception("ColValue &operator[](int i), type index invalid :" + std::to_string(type_index));
} }
} }

View File

@@ -12,7 +12,7 @@ std::vector<std::pair<std::string, std::string>> Settings::m_settings =
std::make_pair("BOOL_TRUE_LITERAL", "Y"), std::make_pair("BOOL_TRUE_LITERAL", "Y"),
std::make_pair("BOOL_FALSE_LITERAL", "N"), std::make_pair("BOOL_FALSE_LITERAL", "N"),
std::make_pair("DOUBLE_FORMAT", "%.2f"), std::make_pair("DOUBLE_FORMAT", "%.2f"),
std::make_pair("USE_INDEXSCAN", "N"), std::make_pair("USE_INDEXSCAN", "Y"),
std::make_pair("MAX_PARALLELISM", "1") }; // values "AUTO" or number of workers; when number negative means std::thread::hardware_concurrency() - number std::make_pair("MAX_PARALLELISM", "1") }; // values "AUTO" or number of workers; when number negative means std::thread::hardware_concurrency() - number

View File

@@ -6,9 +6,37 @@
namespace usql { namespace usql {
USql::USql() {
// create catalogue tables first
std::vector<std::string> k_debug_sql_commands {
"create table usql_tables(name varchar(32) not null, modified boolean not null)",
"create table usql_columns(table_name varchar(32) not null, column_name varchar(32) not null, column_type varchar(16) not null, column_length integer not null, nullable boolean not null, column_order integer not null)",
"create table usql_indexes(index_name varchar(32) not null, table_name varchar(32), column_name varchar(32) not null)"
};
// create cataloque tables
for (const auto &command : k_debug_sql_commands) {
std::unique_ptr<Node> create_table_node = m_parser.parse(command);
const CreateTableNode &node = static_cast<CreateTableNode &>(*create_table_node);
Table table{node.table_name, node.cols_defs};
m_tables.push_back(table);
}
// insert data into cataloque tables
for (const auto &command : k_debug_sql_commands) {
std::unique_ptr<Node> create_table_node = m_parser.parse(command);
const CreateTableNode &node = static_cast<CreateTableNode &>(*create_table_node);
execute_create_table_sys_catalogue(node);
}
}
std::unique_ptr<Table> USql::execute(const std::string &command) { std::unique_ptr<Table> USql::execute(const std::string &command) {
try { try {
std::unique_ptr<Node> node = m_parser.parse(command); std::unique_ptr<Node> node = m_parser.parse(command);
// node->dump();
return execute(*node); return execute(*node);
} catch (const std::exception &e) { } catch (const std::exception &e) {
@@ -182,7 +210,9 @@ std::unique_ptr<ValueNode> USql::eval_function_value_node(Table *table, Row &row
if (fnc->function == FunctionNode::Type::lower) return lower_function(evaluatedPars); if (fnc->function == FunctionNode::Type::lower) return lower_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::upper) return upper_function(evaluatedPars); if (fnc->function == FunctionNode::Type::upper) return upper_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_date) return to_date_function(evaluatedPars); if (fnc->function == FunctionNode::Type::to_date) return to_date_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_string) return to_string_function(evaluatedPars); if (fnc->function == FunctionNode::Type::to_char) return to_char_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_int) return to_int_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::to_float) return to_float_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::date_add) return date_add_function(evaluatedPars); if (fnc->function == FunctionNode::Type::date_add) return date_add_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::pp) return pp_function(evaluatedPars); if (fnc->function == FunctionNode::Type::pp) return pp_function(evaluatedPars);
if (fnc->function == FunctionNode::Type::count) return count_function(agg_func_value, evaluatedPars); if (fnc->function == FunctionNode::Type::count) return count_function(agg_func_value, evaluatedPars);

19
usql.h
View File

@@ -11,17 +11,18 @@
namespace usql { namespace usql {
class USql { class USql {
public: public:
USql() = default; USql();
std::unique_ptr<Table> execute(const std::string &command); std::unique_ptr<Table> execute(const std::string &command);
private: private:
std::unique_ptr<Table> execute(Node &node); std::unique_ptr<Table> execute(Node &node);
std::unique_ptr<Table> execute_create_table(const CreateTableNode &node); std::unique_ptr<Table> execute_create_table(const CreateTableNode &node);
bool execute_create_table_sys_catalogue(const CreateTableNode &node);
std::unique_ptr<Table> execute_create_index(const CreateIndexNode &node); std::unique_ptr<Table> execute_create_index(const CreateIndexNode &node);
bool execute_create_index_sys_catalogue(const CreateIndexNode &node);
std::unique_ptr<Table> execute_create_table_as_table(const CreateTableAsSelectNode &node); std::unique_ptr<Table> execute_create_table_as_table(const CreateTableAsSelectNode &node);
std::unique_ptr<Table> execute_load(const LoadIntoTableNode &node); std::unique_ptr<Table> execute_load(const LoadIntoTableNode &node);
std::unique_ptr<Table> execute_save(const SaveTableNode &node); std::unique_ptr<Table> execute_save(const SaveTableNode &node);
@@ -59,9 +60,6 @@ private:
void check_index_not_exists(const std::string &index_name); void check_index_not_exists(const std::string &index_name);
private: private:
Parser m_parser;
std::list<Table> m_tables;
static void execute_distinct(SelectFromTableNode &node, Table *result); static void execute_distinct(SelectFromTableNode &node, Table *result);
static void execute_order_by(SelectFromTableNode &node, Table *result); static void execute_order_by(SelectFromTableNode &node, Table *result);
static void execute_offset_limit(OffsetLimitNode &node, Table *result); static void execute_offset_limit(OffsetLimitNode &node, Table *result);
@@ -75,7 +73,9 @@ private:
static std::unique_ptr<ValueNode> upper_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> upper_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> coalesce_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> coalesce_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_string_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> to_char_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_int_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> to_float_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> date_add_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> date_add_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
static std::unique_ptr<ValueNode> pp_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars); static std::unique_ptr<ValueNode> pp_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars);
@@ -95,6 +95,11 @@ private:
bool normalize_where(const Node *node) const; bool normalize_where(const Node *node) const;
Table::rows_scanner get_iterator(Table *table, const Node *where) const; Table::rows_scanner get_iterator(Table *table, const Node *where) const;
private:
Parser m_parser;
std::list<Table> m_tables;
}; };

View File

@@ -8,17 +8,41 @@
namespace usql { namespace usql {
std::unique_ptr<Table> USql::execute_create_table(const CreateTableNode &node) { std::unique_ptr<Table> USql::execute_create_table(const CreateTableNode &node) {
check_table_not_exists(node.table_name); check_table_not_exists(node.table_name);
Table table{node.table_name, node.cols_defs}; Table table{node.table_name, node.cols_defs};
m_tables.push_back(table); m_tables.push_back(table);
execute_create_table_sys_catalogue(node);
return create_stmt_result_table(0, "table created", 0); return create_stmt_result_table(0, "table created", 0);
} }
bool USql::execute_create_table_sys_catalogue(const CreateTableNode &node) {
// usql_tables
auto r = execute("insert into usql_tables(name, modified) values('" + node.table_name + "', false)");
// usql_columns
for(const ColDefNode & col_def : node.cols_defs) {
std::string i {"insert into usql_columns(table_name, column_name, column_type, column_length, nullable, column_order) values("};
i += "'" + node.table_name + "', ";
i += "'" + col_def.name + "', ";
i += "'" + column_type_name(col_def.type) + "', ";
i += std::to_string(col_def.length) + ", ";
i += (col_def.null ? "true, " : "false, ");
i += std::to_string(col_def.order);
i += ")";
auto r = execute(i);
// r->print();
}
return true;
}
std::unique_ptr<Table> USql::execute_create_index(const CreateIndexNode &node) { std::unique_ptr<Table> USql::execute_create_index(const CreateIndexNode &node) {
Table *table_def = find_table(node.table_name); // throws exception if not found Table *table_def = find_table(node.table_name); // throws exception if not found
ColDefNode col_def = table_def->get_column_def(node.column_name); // throws exception if not found ColDefNode col_def = table_def->get_column_def(node.column_name); // throws exception if not found
@@ -31,10 +55,25 @@ std::unique_ptr<Table> USql::execute_create_index(const CreateIndexNode &node) {
table_def->index_rows(node.index_name); table_def->index_rows(node.index_name);
execute_create_index_sys_catalogue(node);
return create_stmt_result_table(0, "index created", 0); return create_stmt_result_table(0, "index created", 0);
} }
bool USql::execute_create_index_sys_catalogue(const CreateIndexNode &node) {
std::string i {"insert into usql_indexes(index_name, table_name, column_name) values("};
i += "'" + node.index_name + "', ";
i += "'" + node.table_name + "', ";
i += "'" + node.column_name + "')";
auto r = execute(i);
// r->print();
return true;
}
std::unique_ptr<Table> USql::execute_create_table_as_table(const CreateTableAsSelectNode &node) { std::unique_ptr<Table> USql::execute_create_table_as_table(const CreateTableAsSelectNode &node) {
check_table_not_exists(node.table_name); check_table_not_exists(node.table_name);
@@ -57,7 +96,6 @@ std::unique_ptr<Table> USql::execute_create_table_as_table(const CreateTableAsSe
} }
std::unique_ptr<Table> USql::execute_drop(const DropTableNode &node) { std::unique_ptr<Table> USql::execute_drop(const DropTableNode &node) {
auto name_cmp = [node](const Table& t) { return t.m_name == node.table_name; }; auto name_cmp = [node](const Table& t) { return t.m_name == node.table_name; };
@@ -70,11 +108,13 @@ std::unique_ptr<Table> USql::execute_drop(const DropTableNode &node) {
throw Exception("table not found (" + node.table_name + ")"); throw Exception("table not found (" + node.table_name + ")");
} }
std::unique_ptr<Table> USql::execute_set(const SetNode &node) { std::unique_ptr<Table> USql::execute_set(const SetNode &node) {
Settings::set_setting(node.name, node.value); Settings::set_setting(node.name, node.value);
return create_stmt_result_table(0, "set succeeded", 1); return create_stmt_result_table(0, "set succeeded", 1);
} }
std::unique_ptr<Table> USql::execute_show(const ShowNode &node) { std::unique_ptr<Table> USql::execute_show(const ShowNode &node) {
std::string value = Settings::get_setting(node.name); std::string value = Settings::get_setting(node.name);
return create_stmt_result_table(0, "show succeeded: " + value, 1); return create_stmt_result_table(0, "show succeeded: " + value, 1);

View File

@@ -35,7 +35,7 @@ std::pair<bool, std::vector<rowid_t>> USql::look_for_usable_index(const Node *wh
if (used_index != nullptr) { if (used_index != nullptr) {
std::vector<rowid_t> rowids = used_index->search((ValueNode *)ron->right.get()); std::vector<rowid_t> rowids = used_index->search((ValueNode *)ron->right.get());
#ifndef NDEBUG #ifndef NDEBUG
std::cout << "using index " << table->m_name << "(" << used_index->get_column_name() << "), " << rowids.size() << "/" << table->rows_count() << std::endl; std::cerr << "using index " << table->m_name << "(" << used_index->get_column_name() << "), " << rowids.size() << "/" << table->rows_count() << std::endl;
#endif #endif
return std::make_pair(true, rowids); return std::make_pair(true, rowids);
} }
@@ -155,8 +155,7 @@ void USql::setup_order_columns(std::vector<ColOrderNode> &node, Table *table) {
void USql::execute_distinct(SelectFromTableNode &node, Table *result) { void USql::execute_distinct(SelectFromTableNode &node, Table *result) {
if (!node.distinct) return; if (!node.distinct) return;
auto compare_rows = [](const Row &a, const Row &b) { return a.compare(b) >= 0; }; std::sort(result->m_rows.begin(), result->m_rows.end(), [](const Row &a, const Row &b) { return a.compare(b) > 0; });
std::sort(result->m_rows.begin(), result->m_rows.end(), compare_rows);
result->m_rows.erase(std::unique(result->m_rows.begin(), result->m_rows.end()), result->m_rows.end()); result->m_rows.erase(std::unique(result->m_rows.begin(), result->m_rows.end()), result->m_rows.end());
} }
@@ -217,7 +216,7 @@ ColDefNode USql::get_db_column_definition(Table *table, Node *node) {
throw Exception("Undefined table node - get_db_column_definition"); throw Exception("Undefined table node - get_db_column_definition");
} }
std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node, const std::string & col_name, int col_order ) { std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node, const std::string &col_name, int col_order ) {
if (node->node_type == NodeType::database_value) { if (node->node_type == NodeType::database_value) {
ColDefNode src_col_def = get_db_column_definition(table, node); ColDefNode src_col_def = get_db_column_definition(table, node);
ColDefNode col_def = ColDefNode{col_name, src_col_def.type, col_order, src_col_def.length, src_col_def.null}; ColDefNode col_def = ColDefNode{col_name, src_col_def.type, col_order, src_col_def.length, src_col_def.null};
@@ -226,9 +225,15 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
} else if (node->node_type == NodeType::function) { } else if (node->node_type == NodeType::function) {
auto func_node = static_cast<FunctionNode *>(node); auto func_node = static_cast<FunctionNode *>(node);
if (func_node->function == FunctionNode::Type::to_string) { if (func_node->function == FunctionNode::Type::to_char) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true}; ColDefNode col_def = ColDefNode{col_name, ColumnType::varchar_type, col_order, 32, true};
return std::make_tuple(FUNCTION_CALL, col_def); return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_int) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_float) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::float_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::to_date) { } else if (func_node->function == FunctionNode::Type::to_date) {
ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true}; ColDefNode col_def = ColDefNode{col_name, ColumnType::integer_type, col_order, 1, true};
return std::make_tuple(FUNCTION_CALL, col_def); return std::make_tuple(FUNCTION_CALL, col_def);
@@ -243,18 +248,26 @@ std::tuple<int, ColDefNode> USql::get_node_definition(Table *table, Node * node,
// TODO handle cases here // TODO handle cases here
if (func_node->params.empty()) throw Exception("Coalesce without parameters"); if (func_node->params.empty()) throw Exception("Coalesce without parameters");
if (func_node->params[0]->node_type != NodeType::database_value) throw Exception("Coalesce first parameter must be database column"); if (func_node->params[0]->node_type != NodeType::database_value) throw Exception("Coalesce first parameter must be database column");
ColDefNode tbl_col_def = get_db_column_definition(table, func_node->params[0].get()); ColDefNode tbl_col_def = get_db_column_definition(table, func_node->params[0].get());
ColDefNode col_def = ColDefNode{col_name, tbl_col_def.type, col_order, tbl_col_def.length, true}; ColDefNode col_def = ColDefNode{col_name, tbl_col_def.type, col_order, tbl_col_def.length, true};
return std::make_tuple(FUNCTION_CALL, col_def); return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::min || func_node->function == FunctionNode::Type::max) { } else if (func_node->function == FunctionNode::Type::min || func_node->function == FunctionNode::Type::max) {
auto col_type= ColumnType::float_type; auto col_type = ColumnType::float_type;
size_t col_len = 1; size_t col_len = 1;
auto & v = func_node->params[0]; auto &v = func_node->params[0];
if (v->node_type == NodeType::database_value) { if (v->node_type == NodeType::database_value) {
ColDefNode src_col_def = get_db_column_definition(table, v.get()); ColDefNode src_col_def = get_db_column_definition(table, v.get());
col_type = src_col_def.type; col_type = src_col_def.type;
col_len = src_col_def.length; col_len = src_col_def.length;
} else if (node->node_type == NodeType::function) {
std::tuple<int, ColDefNode> fun_type = get_node_definition(table, static_cast<Node*>(& *v), "", 0);
col_type = std::get<1>(fun_type).type;
col_len = std::get<1>(fun_type).length;
} }
ColDefNode col_def = ColDefNode{col_name, col_type, col_order, col_len, true}; ColDefNode col_def = ColDefNode{col_name, col_type, col_order, col_len, true};
return std::make_tuple(FUNCTION_CALL, col_def); return std::make_tuple(FUNCTION_CALL, col_def);
} else if (func_node->function == FunctionNode::Type::count) { } else if (func_node->function == FunctionNode::Type::count) {

View File

@@ -7,12 +7,24 @@
namespace usql { namespace usql {
std::unique_ptr<ValueNode> USql::to_string_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) { std::unique_ptr<ValueNode> USql::to_char_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
long date = evaluatedPars[0]->getDateValue(); if (evaluatedPars[0]->node_type == NodeType::int_value && evaluatedPars.size()==2) { // TODO when propper date is introduced
std::string format = evaluatedPars[1]->getStringValue(); long date = evaluatedPars[0]->getDateValue();
std::string formatted_date = date_to_string(date, format); std::string format = evaluatedPars[1]->getStringValue();
std::string formatted_date = date_to_string(date, format);
return std::make_unique<StringValueNode>(formatted_date); return std::make_unique<StringValueNode>(formatted_date);
} else {
return std::make_unique<StringValueNode>(evaluatedPars[0]->getStringValue());
}
}
std::unique_ptr<ValueNode> USql::to_int_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
return std::make_unique<IntValueNode>(evaluatedPars[0]->getIntegerValue());
}
std::unique_ptr<ValueNode> USql::to_float_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {
return std::make_unique<DoubleValueNode>(evaluatedPars[0]->getDoubleValue());
} }
std::unique_ptr<ValueNode> USql::to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) { std::unique_ptr<ValueNode> USql::to_date_function(const std::vector<std::unique_ptr<ValueNode>> &evaluatedPars) {