diff --git a/main.cpp b/main.cpp index 2346ac9..530b274 100644 --- a/main.cpp +++ b/main.cpp @@ -126,7 +126,7 @@ void repl() { } void debug() { - std::__1::vector sql_commands{ + std::vector sql_commands{ // "create table ticker ( tablee varchar(5) not null, permaticker integer, ticker varchar(10) not null, name varchar(256) not null, exchange varchar(32), isdelisted boolean, category varchar(32), cusips varchar(256), siccode integer, sicsector varchar(256), sicindustry varchar(256), famasector varchar(256), famaindustry varchar(256), sector varchar(128), industry varchar(128), scalemarketcap varchar(64), scalerevenue varchar(64), relatedtickers varchar(128), currency varchar(3), location varchar(64), lastupdated date, firstadded date, firstpricedate date, lastpricedate date, firstquarter date, lastquarter date, secfilings varchar(256), companysite varchar(256))", // "load ticker from '/Users/vaclavt/Library/Mobile Documents/com~apple~CloudDocs/Development/usql/tickers.csv')", // "select * from ticker where ticker = 'WFC' and tablee = 'SF1'", @@ -136,8 +136,7 @@ void debug() { "load sf1 from '/tmp/sf1.csv'", // "select ticker, calendar_date from sf1 where calendar_date > to_date('2019-01-01', '%Y-%m-%d') limit 1", // "select ticker, dimension, calendar_date, eps, dps, roa*100 as roa, roe*100 as roe, pp(revenue), netinc from sf1 where (ticker = 'AIG' or ticker = 'WFC') and dimension = 'MRY' and calendar_date > to_date('2019-01-01', '%Y-%m-%d') order by 3 desc - "select ticker, dimension, calendar_date, eps, dps, roa*100 as roa, roe*100 as roe, pp(revenue) as revenue, pp(netinc) as netinc from sf1 where (ticker != 'AIG' and ticker != 'WFC') and dimension = 'MRY' and calendar_date > to_date('2019-01-01', '%Y-%m-%d') order by 3 desc", -// "select ticker, dimension, calendar_date, eps, dps from sf1 where (ticker = 'AIG' or ticker = 'AI') and (dimension = 'MRY' or dimension = 'MRQ') order by 3 desc", + "select ticker, dimension, calendar_date, eps, dps, roa*100 as roa, roe*100 as roe, pp(revenue) as revenue, pp(netinc) as netinc from sf1 where (ticker = 'AIG' or ticker = 'WFC') and dimension = 'MRY' and calendar_date > to_date('2019-01-01', '%Y-%m-%d') order by 3 desc", // "create table a (i integer not null, s varchar(64), f float null, d date null, b boolean)", // "insert into a (i, s, b) values(1, upper('one'), 'Y')", // "insert into a (i, s, b, f) values(1 + 10000, upper('one'), 'Y', 3.1415)", diff --git a/row.cpp b/row.cpp index f453255..9be181f 100644 --- a/row.cpp +++ b/row.cpp @@ -20,8 +20,13 @@ int ColDoubleValue::compare(ColValue &other) { return c < 0 ? -1 : c == 0.0 ? 0 : 1; } +ColStringValue & ColStringValue::operator=(ColStringValue other) { + std::swap(m_string, other.m_string); + return *this; +} + int ColStringValue::compare(ColValue &other) { - return other.isNull() ? 1 : m_string.compare(other.getStringValue()); // null goes to end + return other.isNull() ? 1 : m_string->compare(other.getStringValue()); // null goes to end } int ColDateValue::compare(ColValue &other) { @@ -35,20 +40,8 @@ int ColBooleanValue::compare(ColValue &other) { return m_bool == other.getBoolValue() ? 0 : m_bool && !other.getBoolValue() ? -1 : 1; // true first } -Row::Row(int cols_count) { - m_columns.reserve(cols_count); - for (int i = 0; i < cols_count; i++) { - m_columns.emplace_back(ColNullValue()); - } -} - -Row::Row(const Row &other) { - m_columns.reserve(other.m_columns.size()); +Row::Row(const Row &other) : m_columns(other.m_columns.size(), ColNullValue()) { // PERF here we first set cols null and then immediately replace it - for (int i = 0; i < other.m_columns.size(); i++) { - m_columns.emplace_back(ColNullValue()); - } - for (int i = 0; i < other.m_columns.size(); i++) { if (other[i].isNull()) continue; // for null NOP diff --git a/row.h b/row.h index 0109303..0455482 100644 --- a/row.h +++ b/row.h @@ -73,19 +73,21 @@ namespace usql { struct ColStringValue : ColValue { - explicit ColStringValue(const std::string &value) : m_string(value) {}; - ColStringValue(const ColStringValue &other) : m_string(other.m_string) {}; + explicit ColStringValue(const std::string &value) : m_string(std::make_unique(value)) {}; + ColStringValue(const ColStringValue &other) : m_string(std::make_unique(*other.m_string)) {}; + + ColStringValue & operator=(ColStringValue other); ColumnType getColType() override { return ColumnType::varchar_type; }; - long getIntValue() override { return std::stoi(m_string); }; - double getDoubleValue() override { return std::stod(m_string); }; - std::string getStringValue() override { return m_string; }; - long getDateValue() override { return std::stoi(m_string); }; + long getIntValue() override { return std::stoi(*m_string); }; + double getDoubleValue() override { return std::stod(*m_string); }; + std::string getStringValue() override { return *m_string; }; + long getDateValue() override { return std::stoi(*m_string); }; bool getBoolValue() override { throw Exception("Not supported on ColStringValue"); }; int compare(ColValue &other) override; - std::string m_string; + std::unique_ptr m_string; }; struct ColDateValue : ColValue { @@ -125,7 +127,7 @@ namespace usql { class Row { public: - explicit Row(int cols_count); + explicit Row(int cols_count) : m_columns(cols_count, ColNullValue()) {}; Row(const Row &other); Row &operator=(Row other); diff --git a/table.cpp b/table.cpp index 24e9cc3..02334d1 100644 --- a/table.cpp +++ b/table.cpp @@ -98,7 +98,8 @@ int Table::load_csv_file(const std::string &filename) { infile.close(); if (file_size > 0) { - m_rows.reserve(m_rows.size() + int(file_size / line_size * 1.1)); + auto new_size = m_rows.size() + int(file_size / line_size * 1.20); + m_rows.reserve(new_size); } // load rows diff --git a/usql.cpp b/usql.cpp index 493cebd..8a4cfb9 100644 --- a/usql.cpp +++ b/usql.cpp @@ -504,6 +504,10 @@ std::unique_ptr USql::eval_function_value_node(Table *table, Row &row evaluatedPars.push_back(eval_value_node(table, row, param.get())); } + // at this moment no functions without parameter(s) or first param can be null + if (evaluatedPars.empty() || evaluatedPars[0]->isNull()) + return std::make_unique(); + // TODO use some enum if (fnc->function == "lower") { std::string str = evaluatedPars[0]->getStringValue(); @@ -533,7 +537,7 @@ std::unique_ptr USql::eval_function_value_node(Table *table, Row &row if (parsed_value->node_type == NodeType::int_value || parsed_value->node_type == NodeType::float_value) { std::string format = evaluatedPars.size() > 1 ? evaluatedPars[1]->getStringValue() : ""; - char buf[20] {0}; + char buf[16] {0}; double value = parsed_value->getDoubleValue(); if (format == "100%") @@ -557,8 +561,8 @@ std::unique_ptr USql::eval_function_value_node(Table *table, Row &row else if (value == 0) buf[0]='0'; else - return std::make_unique(parsed_value->getStringValue()); - + return std::make_unique(parsed_value->getStringValue().substr(0, 10)); + // TODO introduce constant for 10 std::string s {buf}; return std::make_unique(string_padd(s.erase(s.find_last_not_of(" ")+1), 10, ' ', false)); }