usql function to_string renamed to to_char
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
(include "/usr/local/var/mlisp/ut.lsp")
|
(include "/usr/local/var/mlisp/ut.lsp")
|
||||||
|
|
||||||
(def local_time_offset 3600)
|
(def local_time_offset 7200)
|
||||||
|
|
||||||
;; prepare some code to be used in tests
|
;; prepare some code to be used in tests
|
||||||
(defn fact (n)
|
(defn fact (n)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace usql {
|
namespace usql {
|
||||||
|
|
||||||
// TOOD handle premature eof
|
// TOOD handle premature eof
|
||||||
|
|
||||||
std::string column_type_name(const ColumnType type) {
|
std::string column_type_name(const ColumnType type) {
|
||||||
if (type == ColumnType::integer_type) return "integer_type";
|
if (type == ColumnType::integer_type) return "integer_type";
|
||||||
@@ -64,11 +64,11 @@ namespace usql {
|
|||||||
|
|
||||||
// create as select
|
// create as select
|
||||||
if (m_lexer.tokenType() == TokenType::keyword_as) {
|
if (m_lexer.tokenType() == TokenType::keyword_as) {
|
||||||
m_lexer.skipToken(TokenType::keyword_as);
|
m_lexer.skipToken(TokenType::keyword_as);
|
||||||
|
|
||||||
std::unique_ptr<Node> select = parse_select_from_table();
|
std::unique_ptr<Node> select = parse_select_from_table();
|
||||||
|
|
||||||
return std::make_unique<CreateTableAsSelectNode>(table_name, std::move(select));
|
return std::make_unique<CreateTableAsSelectNode>(table_name, std::move(select));
|
||||||
} else {
|
} else {
|
||||||
m_lexer.skipToken(TokenType::open_paren);
|
m_lexer.skipToken(TokenType::open_paren);
|
||||||
int column_order = 0;
|
int column_order = 0;
|
||||||
@@ -80,30 +80,30 @@ namespace usql {
|
|||||||
|
|
||||||
// column name
|
// column name
|
||||||
if (m_lexer.tokenType() != TokenType::identifier) {
|
if (m_lexer.tokenType() != TokenType::identifier) {
|
||||||
throw Exception("syntax error, expected identifier");
|
throw Exception("syntax error, expected identifier");
|
||||||
}
|
}
|
||||||
database_value = m_lexer.consumeToken().token_string;
|
database_value = m_lexer.consumeToken().token_string;
|
||||||
|
|
||||||
// column type and optionally len
|
// column type and optionally len
|
||||||
if (m_lexer.tokenType() == TokenType::keyword_integer) {
|
if (m_lexer.tokenType() == TokenType::keyword_integer) {
|
||||||
column_type = ColumnType::integer_type;
|
column_type = ColumnType::integer_type;
|
||||||
m_lexer.nextToken();
|
m_lexer.nextToken();
|
||||||
} else if (m_lexer.tokenType() == TokenType::keyword_float) {
|
} else if (m_lexer.tokenType() == TokenType::keyword_float) {
|
||||||
column_type = ColumnType::float_type;
|
column_type = ColumnType::float_type;
|
||||||
m_lexer.nextToken();
|
m_lexer.nextToken();
|
||||||
} else if (m_lexer.tokenType() == TokenType::keyword_varchar) {
|
} else if (m_lexer.tokenType() == TokenType::keyword_varchar) {
|
||||||
column_type = ColumnType::varchar_type;
|
column_type = ColumnType::varchar_type;
|
||||||
m_lexer.nextToken();
|
m_lexer.nextToken();
|
||||||
m_lexer.skipToken(TokenType::open_paren);
|
m_lexer.skipToken(TokenType::open_paren);
|
||||||
column_len = std::stoi(m_lexer.consumeToken(TokenType::int_number).token_string);
|
column_len = std::stoi(m_lexer.consumeToken(TokenType::int_number).token_string);
|
||||||
m_lexer.skipToken(TokenType::close_paren);
|
m_lexer.skipToken(TokenType::close_paren);
|
||||||
} else if (m_lexer.tokenType() == TokenType::keyword_date) {
|
} else if (m_lexer.tokenType() == TokenType::keyword_date) {
|
||||||
column_type = ColumnType::date_type;
|
column_type = ColumnType::date_type;
|
||||||
m_lexer.nextToken();
|
m_lexer.nextToken();
|
||||||
} else if (m_lexer.tokenType() == TokenType::keyword_bool) {
|
} else if (m_lexer.tokenType() == TokenType::keyword_bool) {
|
||||||
column_type = ColumnType::bool_type;
|
column_type = ColumnType::bool_type;
|
||||||
m_lexer.nextToken();
|
m_lexer.nextToken();
|
||||||
} else {
|
} else {
|
||||||
throw Exception("syntax error, column type expected, found " + m_lexer.currentToken().token_string);
|
throw Exception("syntax error, column type expected, found " + m_lexer.currentToken().token_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ namespace usql {
|
|||||||
m_lexer.skipTokenOptional(TokenType::comma);
|
m_lexer.skipTokenOptional(TokenType::comma);
|
||||||
|
|
||||||
//constraints
|
//constraints
|
||||||
//defaults
|
//defaults
|
||||||
} while (m_lexer.tokenType() != TokenType::close_paren);
|
} while (m_lexer.tokenType() != TokenType::close_paren);
|
||||||
|
|
||||||
return std::make_unique<CreateTableNode>(table_name, cols_def);
|
return std::make_unique<CreateTableNode>(table_name, cols_def);
|
||||||
@@ -502,7 +502,7 @@ namespace usql {
|
|||||||
return RelationalOperatorType::lesser_equal;
|
return RelationalOperatorType::lesser_equal;
|
||||||
case TokenType::is:
|
case TokenType::is:
|
||||||
if (m_lexer.tokenType() == TokenType::keyword_not) {
|
if (m_lexer.tokenType() == TokenType::keyword_not) {
|
||||||
m_lexer.skipToken(TokenType::keyword_not);
|
m_lexer.skipToken(TokenType::keyword_not);
|
||||||
return RelationalOperatorType::is_not;
|
return RelationalOperatorType::is_not;
|
||||||
}
|
}
|
||||||
return RelationalOperatorType::is;
|
return RelationalOperatorType::is;
|
||||||
|
|||||||
@@ -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,8 +141,10 @@ 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;
|
||||||
@@ -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,7 +175,7 @@ struct FunctionNode : Node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Type function;
|
Type function;
|
||||||
std::vector<std::unique_ptr<Node>> params;
|
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) :
|
||||||
|
|||||||
@@ -182,7 +182,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);
|
||||||
|
|||||||
@@ -75,7 +75,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);
|
||||||
|
|
||||||
|
|||||||
@@ -217,7 +217,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 +226,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 +249,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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user