another bit of refactoring
This commit is contained in:
parent
5e4480c767
commit
eebfaacde4
|
|
@ -8,7 +8,7 @@
|
||||||
"name": "(lldb) Launch",
|
"name": "(lldb) Launch",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/build/msql",
|
"program": "${workspaceFolder}/build/usql",
|
||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${fileDirname}",
|
"cwd": "${fileDirname}",
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ project(usql)
|
||||||
set(PROJECT_NAME usql)
|
set(PROJECT_NAME usql)
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
exception.cpp lexer.cpp parser.cpp executor.cpp main.cpp table.cpp table.h row.cpp row.h csvreader.cpp csvreader.h)
|
exception.cpp lexer.cpp parser.cpp usql.cpp main.cpp table.cpp table.h row.cpp row.h csvreader.cpp csvreader.h)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCE})
|
add_executable(${PROJECT_NAME} ${SOURCE})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
#include "csvreader.h"
|
#include "csvreader.h"
|
||||||
#include <climits>
|
|
||||||
|
|
||||||
namespace usql {
|
namespace usql {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
|
||||||
11
main.cpp
11
main.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "executor.h"
|
#include "usql.h"
|
||||||
|
|
||||||
// https://dev.to/joaoh82/what-would-sqlite-look-like-if-written-in-rust-part-1-2np4
|
// https://dev.to/joaoh82/what-would-sqlite-look-like-if-written-in-rust-part-1-2np4
|
||||||
|
|
||||||
|
|
@ -8,9 +8,6 @@
|
||||||
// drop table
|
// drop table
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
usql::Parser parser{};
|
|
||||||
usql::Executor executor{};
|
|
||||||
|
|
||||||
std::vector<std::string> sql_commands{
|
std::vector<std::string> sql_commands{
|
||||||
"create table a (i integer not null, s varchar(64), f float null)",
|
"create table a (i integer not null, s varchar(64), f float null)",
|
||||||
"insert into a (i, s) values(1, 'one')",
|
"insert into a (i, s) values(1, 'one')",
|
||||||
|
|
@ -35,13 +32,13 @@ int main(int argc, char *argv[]) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
usql::uSQL uSql{};
|
||||||
|
|
||||||
for (auto command : sql_commands) {
|
for (auto command : sql_commands) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
auto node = parser.parse(command);
|
auto result = uSql.execute(command);
|
||||||
auto result = executor.execute(*node);
|
|
||||||
|
|
||||||
result->print();
|
result->print();
|
||||||
// std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
1
parser.h
1
parser.h
|
|
@ -33,7 +33,6 @@ namespace usql {
|
||||||
column_name,
|
column_name,
|
||||||
column_value,
|
column_value,
|
||||||
column_def,
|
column_def,
|
||||||
not_implemented_yet,
|
|
||||||
error
|
error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
2
row.cpp
2
row.cpp
|
|
@ -43,7 +43,7 @@ namespace usql {
|
||||||
m_columns[col_index] = std::make_unique<ColFloatValue>(value);
|
m_columns[col_index] = std::make_unique<ColFloatValue>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::setColumnValue(int col_index, std::string value) {
|
void Row::setColumnValue(int col_index, const std::string &value) {
|
||||||
m_columns[col_index] = std::make_unique<ColStringValue>(value);
|
m_columns[col_index] = std::make_unique<ColStringValue>(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
30
row.h
30
row.h
|
|
@ -7,28 +7,10 @@
|
||||||
|
|
||||||
namespace usql {
|
namespace usql {
|
||||||
|
|
||||||
class ColumnValue {
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
ColumnType m_type;
|
|
||||||
union {
|
|
||||||
int int_value;
|
|
||||||
double float_value;
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ColValue {
|
struct ColValue {
|
||||||
|
|
||||||
virtual bool isNull() { return false; };
|
virtual bool isNull() { return false; };;;;
|
||||||
|
|
||||||
virtual bool isInteger() { return false; };
|
|
||||||
|
|
||||||
virtual bool isFloat() { return false; };
|
|
||||||
|
|
||||||
virtual bool isString() { return false; };
|
|
||||||
|
|
||||||
virtual int integerValue() { throw Exception("Not supported"); };
|
virtual int integerValue() { throw Exception("Not supported"); };
|
||||||
|
|
||||||
|
|
@ -50,9 +32,7 @@ namespace usql {
|
||||||
|
|
||||||
ColIntegerValue(int value) : m_integer(value) {};
|
ColIntegerValue(int value) : m_integer(value) {};
|
||||||
|
|
||||||
ColIntegerValue(const ColIntegerValue &other) : m_integer(other.m_integer) {}
|
ColIntegerValue(const ColIntegerValue &other) : m_integer(other.m_integer) {};
|
||||||
|
|
||||||
virtual bool isInteger() { return true; };
|
|
||||||
|
|
||||||
virtual int integerValue() { return m_integer; };
|
virtual int integerValue() { return m_integer; };
|
||||||
|
|
||||||
|
|
@ -70,8 +50,6 @@ namespace usql {
|
||||||
|
|
||||||
ColFloatValue(const ColFloatValue &other) : m_float(other.m_float) {}
|
ColFloatValue(const ColFloatValue &other) : m_float(other.m_float) {}
|
||||||
|
|
||||||
virtual bool isFloat() { return true; }
|
|
||||||
|
|
||||||
virtual int integerValue() { return (int) m_float; };
|
virtual int integerValue() { return (int) m_float; };
|
||||||
|
|
||||||
virtual double floatValue() { return m_float; };
|
virtual double floatValue() { return m_float; };
|
||||||
|
|
@ -88,8 +66,6 @@ namespace usql {
|
||||||
|
|
||||||
ColStringValue(const ColStringValue &other) : m_string(other.m_string) {};
|
ColStringValue(const ColStringValue &other) : m_string(other.m_string) {};
|
||||||
|
|
||||||
virtual bool isString() { return true; }
|
|
||||||
|
|
||||||
virtual int integerValue() { return std::stoi(m_string); };
|
virtual int integerValue() { return std::stoi(m_string); };
|
||||||
|
|
||||||
virtual double floatValue() { return std::stod(m_string); };
|
virtual double floatValue() { return std::stod(m_string); };
|
||||||
|
|
@ -113,7 +89,7 @@ namespace usql {
|
||||||
|
|
||||||
void setColumnValue(int col_index, double value);
|
void setColumnValue(int col_index, double value);
|
||||||
|
|
||||||
void setColumnValue(int col_index, std::string value);
|
void setColumnValue(int col_index, const std::string &value);
|
||||||
|
|
||||||
ColValue &operator[](int i) {
|
ColValue &operator[](int i) {
|
||||||
return *m_columns[i];
|
return *m_columns[i];
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "executor.h"
|
#include "usql.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "csvreader.h"
|
#include "csvreader.h"
|
||||||
|
|
||||||
|
|
@ -7,39 +7,14 @@
|
||||||
|
|
||||||
namespace usql {
|
namespace usql {
|
||||||
|
|
||||||
Executor::Executor() {
|
std::unique_ptr<Table> uSQL::execute(const std::string &command) {
|
||||||
m_tables.clear();
|
auto node = m_parser.parse(command);
|
||||||
|
|
||||||
|
return execute(*node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Table *Executor::find_table(const std::string name) {
|
std::unique_ptr<Table> uSQL::execute(Node &node) {
|
||||||
auto name_cmp = [name](Table t) { return t.m_name == name; };
|
|
||||||
auto table_def = std::find_if(begin(m_tables), end(m_tables), name_cmp);
|
|
||||||
if (table_def != std::end(m_tables)) {
|
|
||||||
return table_def.operator->();
|
|
||||||
} else {
|
|
||||||
throw Exception("table not found (" + name + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::create_stmt_result_table(int code, std::string text) {
|
|
||||||
std::vector<ColDefNode> result_tbl_col_defs{};
|
|
||||||
result_tbl_col_defs.push_back(ColDefNode("code", ColumnType::integer_type, 0, 1, false));
|
|
||||||
result_tbl_col_defs.push_back(ColDefNode("desc", ColumnType::varchar_type, 1, 255, false));
|
|
||||||
|
|
||||||
auto table_def = std::make_unique<Table>("result", result_tbl_col_defs);
|
|
||||||
|
|
||||||
Row new_row = table_def->createEmptyRow();
|
|
||||||
new_row.setColumnValue(0, code);
|
|
||||||
new_row.setColumnValue(1, text);
|
|
||||||
table_def->addRow(new_row);
|
|
||||||
|
|
||||||
return std::move(table_def);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute(Node &node) {
|
|
||||||
// TODO optimize execution nodes here
|
// TODO optimize execution nodes here
|
||||||
switch (node.node_type) {
|
switch (node.node_type) {
|
||||||
case NodeType::create_table:
|
case NodeType::create_table:
|
||||||
|
|
@ -57,11 +32,10 @@ namespace usql {
|
||||||
default:
|
default:
|
||||||
return create_stmt_result_table(-1, "unknown statement");
|
return create_stmt_result_table(-1, "unknown statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_create_table(CreateTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_create_table(CreateTableNode &node) {
|
||||||
// TODO check table does not exists
|
// TODO check table does not exists
|
||||||
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);
|
||||||
|
|
@ -70,7 +44,7 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_insert_into_table(InsertIntoTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_insert_into_table(InsertIntoTableNode &node) {
|
||||||
// TODO check column names.size = values.size
|
// TODO check column names.size = values.size
|
||||||
|
|
||||||
// find table
|
// find table
|
||||||
|
|
@ -101,7 +75,7 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_select(SelectFromTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_select(SelectFromTableNode &node) {
|
||||||
// TODO create plan for accessing rows
|
// TODO create plan for accessing rows
|
||||||
|
|
||||||
// find source table
|
// find source table
|
||||||
|
|
@ -111,7 +85,7 @@ namespace usql {
|
||||||
std::vector<ColDefNode> result_tbl_col_defs{};
|
std::vector<ColDefNode> result_tbl_col_defs{};
|
||||||
std::vector<int> source_table_col_index{};
|
std::vector<int> source_table_col_index{};
|
||||||
int i = 0; // new column order
|
int i = 0; // new column order
|
||||||
for (ColNameNode rc : node.cols_names) {
|
for (auto rc : node.cols_names) {
|
||||||
ColDefNode cdef = table->get_column_def(rc.name);
|
ColDefNode cdef = table->get_column_def(rc.name);
|
||||||
source_table_col_index.push_back(cdef.order);
|
source_table_col_index.push_back(cdef.order);
|
||||||
|
|
||||||
|
|
@ -151,7 +125,7 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_delete(DeleteFromTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_delete(DeleteFromTableNode &node) {
|
||||||
// TODO create plan for accessing rows
|
// TODO create plan for accessing rows
|
||||||
|
|
||||||
// find source table
|
// find source table
|
||||||
|
|
@ -172,7 +146,7 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_update(UpdateTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_update(UpdateTableNode &node) {
|
||||||
// TODO create plan for accessing rows
|
// TODO create plan for accessing rows
|
||||||
|
|
||||||
// find source table
|
// find source table
|
||||||
|
|
@ -209,7 +183,7 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Table> Executor::execute_load(LoadIntoTableNode &node) {
|
std::unique_ptr<Table> uSQL::execute_load(LoadIntoTableNode &node) {
|
||||||
// find source table
|
// find source table
|
||||||
Table *table_def = find_table(node.table_name);
|
Table *table_def = find_table(node.table_name);
|
||||||
|
|
||||||
|
|
@ -251,8 +225,8 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Executor::evalWhere(Node *where, Table *table,
|
bool uSQL::evalWhere(Node *where, Table *table,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
||||||
switch (where->node_type) { // no where clause
|
switch (where->node_type) { // no where clause
|
||||||
case NodeType::true_node:
|
case NodeType::true_node:
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -268,8 +242,8 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Executor::evalRelationalOperator(const RelationalOperatorNode &filter, Table *table,
|
bool uSQL::evalRelationalOperator(const RelationalOperatorNode &filter, Table *table,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
||||||
std::unique_ptr<ValueNode> left_value = evalNode(table, row, filter.left.get());
|
std::unique_ptr<ValueNode> left_value = evalNode(table, row, filter.left.get());
|
||||||
std::unique_ptr<ValueNode> right_value = evalNode(table, row, filter.right.get());
|
std::unique_ptr<ValueNode> right_value = evalNode(table, row, filter.right.get());
|
||||||
|
|
||||||
|
|
@ -313,7 +287,7 @@ namespace usql {
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<ValueNode>
|
std::unique_ptr<ValueNode>
|
||||||
Executor::evalNode(Table *table, std::vector<Row, std::allocator<Row>>::iterator &row, Node *node) const {
|
uSQL::evalNode(Table *table, std::vector<Row, std::allocator<Row>>::iterator &row, Node *node) const {
|
||||||
if (node->node_type == NodeType::database_value) {
|
if (node->node_type == NodeType::database_value) {
|
||||||
DatabaseValueNode *dvl = static_cast<DatabaseValueNode *>(node);
|
DatabaseValueNode *dvl = static_cast<DatabaseValueNode *>(node);
|
||||||
ColDefNode col_def = table->get_column_def(
|
ColDefNode col_def = table->get_column_def(
|
||||||
|
|
@ -347,8 +321,8 @@ namespace usql {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Executor::evalLogicalOperator(LogicalOperatorNode &node, Table *pTable,
|
bool uSQL::evalLogicalOperator(LogicalOperatorNode &node, Table *pTable,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &iter) const {
|
std::vector<Row, std::allocator<Row>>::iterator &iter) const {
|
||||||
bool left = evalRelationalOperator(static_cast<const RelationalOperatorNode &>(*node.left), pTable, iter);
|
bool left = evalRelationalOperator(static_cast<const RelationalOperatorNode &>(*node.left), pTable, iter);
|
||||||
|
|
||||||
if ((node.op == LogicalOperatorType::and_operator && !left) ||
|
if ((node.op == LogicalOperatorType::and_operator && !left) ||
|
||||||
|
|
@ -361,8 +335,8 @@ namespace usql {
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<ValueNode>
|
std::unique_ptr<ValueNode>
|
||||||
Executor::evalArithmetic(ColumnType outType, ArithmeticalOperatorNode &node, Table *table,
|
uSQL::evalArithmetic(ColumnType outType, ArithmeticalOperatorNode &node, Table *table,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
std::vector<Row, std::allocator<Row>>::iterator &row) const {
|
||||||
if (node.op == ArithmeticalOperatorType::copy_value) {
|
if (node.op == ArithmeticalOperatorType::copy_value) {
|
||||||
return evalNode(table, row, node.left.get());
|
return evalNode(table, row, node.left.get());
|
||||||
}
|
}
|
||||||
|
|
@ -416,4 +390,32 @@ namespace usql {
|
||||||
throw Exception("implement me!!");
|
throw Exception("implement me!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Table *uSQL::find_table(const std::string name) {
|
||||||
|
auto name_cmp = [name](const Table& t) { return t.m_name == name; };
|
||||||
|
auto table_def = std::find_if(begin(m_tables), end(m_tables), name_cmp);
|
||||||
|
if (table_def != std::end(m_tables)) {
|
||||||
|
return table_def.operator->();
|
||||||
|
} else {
|
||||||
|
throw Exception("table not found (" + name + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<Table> uSQL::create_stmt_result_table(int code, std::string text) {
|
||||||
|
std::vector<ColDefNode> result_tbl_col_defs{};
|
||||||
|
result_tbl_col_defs.push_back(ColDefNode("code", ColumnType::integer_type, 0, 1, false));
|
||||||
|
result_tbl_col_defs.push_back(ColDefNode("desc", ColumnType::varchar_type, 1, 255, false));
|
||||||
|
|
||||||
|
auto table_def = std::make_unique<Table>("result", result_tbl_col_defs);
|
||||||
|
|
||||||
|
Row new_row = table_def->createEmptyRow();
|
||||||
|
new_row.setColumnValue(0, code);
|
||||||
|
new_row.setColumnValue(1, text);
|
||||||
|
table_def->addRow(new_row);
|
||||||
|
|
||||||
|
return std::move(table_def);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -7,34 +7,26 @@
|
||||||
|
|
||||||
namespace usql {
|
namespace usql {
|
||||||
|
|
||||||
class Executor {
|
class uSQL {
|
||||||
private:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Executor();
|
std::unique_ptr<Table> execute(const std::string &command);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute(Node &node);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<Table> execute(Node &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_create_table(CreateTableNode &node);
|
std::unique_ptr<Table> execute_create_table(CreateTableNode &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_insert_into_table(InsertIntoTableNode &node);
|
std::unique_ptr<Table> execute_insert_into_table(InsertIntoTableNode &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_select(SelectFromTableNode &node);
|
std::unique_ptr<Table> execute_select(SelectFromTableNode &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_delete(DeleteFromTableNode &node);
|
std::unique_ptr<Table> execute_delete(DeleteFromTableNode &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_update(UpdateTableNode &node);
|
std::unique_ptr<Table> execute_update(UpdateTableNode &node);
|
||||||
|
|
||||||
std::unique_ptr<Table> execute_load(LoadIntoTableNode &node);
|
std::unique_ptr<Table> execute_load(LoadIntoTableNode &node);
|
||||||
|
|
||||||
Table *find_table(const std::string name);
|
Table *find_table(const std::string name);
|
||||||
|
|
||||||
std::unique_ptr<Table> create_stmt_result_table(int code, std::string text);
|
std::unique_ptr<Table> create_stmt_result_table(int code, std::string text);
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<Table> m_tables;
|
|
||||||
|
|
||||||
|
private:
|
||||||
bool evalWhere(Node *where, Table *table,
|
bool evalWhere(Node *where, Table *table,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &row) const;
|
std::vector<Row, std::allocator<Row>>::iterator &row) const;
|
||||||
|
|
||||||
|
|
@ -49,6 +41,10 @@ namespace usql {
|
||||||
|
|
||||||
std::unique_ptr<ValueNode> evalArithmetic(ColumnType outType, ArithmeticalOperatorNode &node, Table *table,
|
std::unique_ptr<ValueNode> evalArithmetic(ColumnType outType, ArithmeticalOperatorNode &node, Table *table,
|
||||||
std::vector<Row, std::allocator<Row>>::iterator &row) const;
|
std::vector<Row, std::allocator<Row>>::iterator &row) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Parser m_parser;
|
||||||
|
std::vector<Table> m_tables;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue