diff --git a/dbms/include/DB/Common/HashTable/HashTable.h b/dbms/include/DB/Common/HashTable/HashTable.h index dba467c83e8..1fdee83c54b 100644 --- a/dbms/include/DB/Common/HashTable/HashTable.h +++ b/dbms/include/DB/Common/HashTable/HashTable.h @@ -811,6 +811,11 @@ public: return grower.bufSize() * sizeof(Cell); } + size_t getBufferSizeInCells() const + { + return grower.bufSize(); + } + #ifdef DBMS_HASH_MAP_COUNT_COLLISIONS size_t getCollisions() const { diff --git a/dbms/include/DB/Dictionaries/CacheDictionary.h b/dbms/include/DB/Dictionaries/CacheDictionary.h index 300bd1d7060..6712afe1869 100644 --- a/dbms/include/DB/Dictionaries/CacheDictionary.h +++ b/dbms/include/DB/Dictionaries/CacheDictionary.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,19 @@ public: std::size_t getBytesAllocated() const override { return bytes_allocated; } + double getHitRate() const override + { + return static_cast(hit_count.load(std::memory_order_acquire)) / + query_count.load(std::memory_order_relaxed); + } + + std::size_t getElementCount() const override { return element_count.load(std::memory_order_relaxed); } + + double getLoadFactor() const override + { + return static_cast(element_count.load(std::memory_order_relaxed)) / size; + } + bool isCached() const override { return true; } DictionaryPtr clone() const override { return std::make_unique(*this); } @@ -55,6 +69,13 @@ public: const DictionaryLifetime & getLifetime() const override { return dict_lifetime; } + const DictionaryStructure & getStructure() const override { return dict_struct; } + + std::chrono::time_point getCreationTime() const override + { + return creation_time; + } + bool hasHierarchy() const override { return hierarchical_attribute; } id_t toParent(const id_t id) const override @@ -179,6 +200,7 @@ private: const auto size = dict_struct.attributes.size(); attributes.reserve(size); + bytes_allocated += size * sizeof(cell_metadata_t); bytes_allocated += size * sizeof(attributes.front()); for (const auto & attribute : dict_struct.attributes) @@ -298,6 +320,9 @@ private: } } + query_count.fetch_add(ids.size(), std::memory_order_relaxed); + hit_count.fetch_add(ids.size() - outdated_ids.size(), std::memory_order_release); + if (outdated_ids.empty()) return; @@ -351,7 +376,11 @@ private: /// optimistic code completed successfully if (!found_outdated_values) + { + query_count.fetch_add(ids.size(), std::memory_order_relaxed); + hit_count.fetch_add(ids.size(), std::memory_order_release); return; + } /// now onto the pessimistic one, discard possibly partial results from the optimistic path out->getChars().resize_assume_reserved(0); @@ -384,6 +413,9 @@ private: } } + query_count.fetch_add(ids.size(), std::memory_order_relaxed); + hit_count.fetch_add(ids.size() - outdated_ids.size(), std::memory_order_release); + /// request new values if (!outdated_ids.empty()) { @@ -456,6 +488,10 @@ private: setAttributeValue(attribute, cell_idx, attribute_column[i]); } + /// if cell id is zero and zero does not map to this cell, then the cell is unused + if (cell.id == 0 && cell_idx != zero_cell_idx) + element_count.fetch_add(1, std::memory_order_relaxed); + cell.id = id; if (dict_lifetime.min_sec != 0 && dict_lifetime.max_sec != 0) cell.expires_at = std::chrono::system_clock::now() + std::chrono::seconds{distribution(rnd_engine)}; @@ -481,6 +517,9 @@ private: for (auto & attribute : attributes) setDefaultAttributeValue(attribute, cell_idx); + if (cell.id == 0 && cell_idx != zero_cell_idx) + element_count.fetch_add(1, std::memory_order_relaxed); + cell.id = id; if (dict_lifetime.min_sec != 0 && dict_lifetime.max_sec != 0) cell.expires_at = std::chrono::system_clock::now() + std::chrono::seconds{distribution(rnd_engine)}; @@ -613,6 +652,7 @@ private: mutable Poco::RWLock rw_lock; const std::size_t size; + const std::uint64_t zero_cell_idx{getCellIdx(0)}; std::map attribute_index_by_name; mutable std::vector attributes; mutable std::vector cells; @@ -620,7 +660,12 @@ private: mutable std::mt19937_64 rnd_engine{getSeed()}; - mutable std::size_t bytes_allocated; + mutable std::size_t bytes_allocated = 0; + mutable std::atomic element_count{}; + mutable std::atomic hit_count{}; + mutable std::atomic query_count{}; + + const std::chrono::time_point creation_time = std::chrono::system_clock::now(); }; } diff --git a/dbms/include/DB/Dictionaries/ClickHouseDictionarySource.h b/dbms/include/DB/Dictionaries/ClickHouseDictionarySource.h index 7be319a79cb..0d08a70ea10 100644 --- a/dbms/include/DB/Dictionaries/ClickHouseDictionarySource.h +++ b/dbms/include/DB/Dictionaries/ClickHouseDictionarySource.h @@ -74,6 +74,8 @@ public: DictionarySourcePtr clone() const override { return std::make_unique(*this); } + std::string toString() const override { return "ClickHouse: " + db + '.' + table; } + private: static std::string composeLoadAllQuery(const Block & block, const std::string & db, const std::string & table) { @@ -94,8 +96,11 @@ private: } writeString(" FROM ", out); - writeProbablyBackQuotedString(db, out); - writeChar('.', out); + if (!db.empty()) + { + writeProbablyBackQuotedString(db, out); + writeChar('.', out); + } writeProbablyBackQuotedString(table, out); writeChar(';', out); } @@ -123,8 +128,11 @@ private: const auto & id_column_name = sample_block.getByPosition(0).name; writeString(" FROM ", out); - writeProbablyBackQuotedString(db, out); - writeChar('.', out); + if (!db.empty()) + { + writeProbablyBackQuotedString(db, out); + writeChar('.', out); + } writeProbablyBackQuotedString(table, out); writeString(" WHERE ", out); writeProbablyBackQuotedString(id_column_name, out); @@ -137,7 +145,7 @@ private: writeString(", ", out); first = false; - writeString(toString(id), out); + writeString(DB::toString(id), out); } writeString(");", out); diff --git a/dbms/include/DB/Dictionaries/FileDictionarySource.h b/dbms/include/DB/Dictionaries/FileDictionarySource.h index bcf42210cbb..5f8f5430ec5 100644 --- a/dbms/include/DB/Dictionaries/FileDictionarySource.h +++ b/dbms/include/DB/Dictionaries/FileDictionarySource.h @@ -51,6 +51,8 @@ public: DictionarySourcePtr clone() const override { return std::make_unique(*this); } + std::string toString() const override { return "File: " + filename + ' ' + format; } + private: Poco::Timestamp getLastModification() const { return Poco::File{filename}.getLastModified(); } diff --git a/dbms/include/DB/Dictionaries/FlatDictionary.h b/dbms/include/DB/Dictionaries/FlatDictionary.h index 65d39eb8558..6ce9a5ae1ef 100644 --- a/dbms/include/DB/Dictionaries/FlatDictionary.h +++ b/dbms/include/DB/Dictionaries/FlatDictionary.h @@ -25,6 +25,7 @@ public: createAttributes(); loadData(); calculateBytesAllocated(); + creation_time = std::chrono::system_clock::now(); } FlatDictionary(const FlatDictionary & other) @@ -37,6 +38,12 @@ public: std::size_t getBytesAllocated() const override { return bytes_allocated; } + double getHitRate() const override { return 1.0; } + + std::size_t getElementCount() const override { return element_count; } + + double getLoadFactor() const override { return static_cast(element_count) / bucket_count; } + bool isCached() const override { return false; } DictionaryPtr clone() const override { return std::make_unique(*this); } @@ -45,6 +52,13 @@ public: const DictionaryLifetime & getLifetime() const override { return dict_lifetime; } + const DictionaryStructure & getStructure() const override { return dict_struct; } + + std::chrono::time_point getCreationTime() const override + { + return creation_time; + } + bool hasHierarchy() const override { return hierarchical_attribute; } id_t toParent(const id_t id) const override @@ -196,6 +210,8 @@ private: { const auto & id_column = *block.getByPosition(0).column; + element_count += id_column.size(); + for (const auto attribute_idx : ext::range(0, attributes.size())) { const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column; @@ -214,6 +230,7 @@ private: { const auto & array_ref = std::get>>(attribute.arrays); bytes_allocated += sizeof(PODArray) + array_ref->storage_size(); + bucket_count = array_ref->capacity(); } void calculateBytesAllocated() @@ -360,6 +377,10 @@ private: const attribute_t * hierarchical_attribute = nullptr; std::size_t bytes_allocated = 0; + std::size_t element_count = 0; + std::size_t bucket_count = 0; + + std::chrono::time_point creation_time; }; } diff --git a/dbms/include/DB/Dictionaries/HashedDictionary.h b/dbms/include/DB/Dictionaries/HashedDictionary.h index 8c317034bf6..0404cbac8cd 100644 --- a/dbms/include/DB/Dictionaries/HashedDictionary.h +++ b/dbms/include/DB/Dictionaries/HashedDictionary.h @@ -23,6 +23,7 @@ public: createAttributes(); loadData(); calculateBytesAllocated(); + creation_time = std::chrono::system_clock::now(); } HashedDictionary(const HashedDictionary & other) @@ -35,6 +36,12 @@ public: std::size_t getBytesAllocated() const override { return bytes_allocated; } + double getHitRate() const override { return 1.0; } + + std::size_t getElementCount() const override { return element_count; } + + double getLoadFactor() const override { return static_cast(element_count) / bucket_count; } + bool isCached() const override { return false; } DictionaryPtr clone() const override { return std::make_unique(*this); } @@ -43,6 +50,13 @@ public: const DictionaryLifetime & getLifetime() const override { return dict_lifetime; } + const DictionaryStructure & getStructure() const override { return dict_struct; } + + std::chrono::time_point getCreationTime() const override + { + return creation_time; + } + bool hasHierarchy() const override { return hierarchical_attribute; } id_t toParent(const id_t id) const override @@ -197,6 +211,8 @@ private: { const auto & id_column = *block.getByPosition(0).column; + element_count += id_column.size(); + for (const auto attribute_idx : ext::range(0, attributes.size())) { const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column; @@ -215,6 +231,7 @@ private: { const auto & map_ref = std::get>>(attribute.maps); bytes_allocated += sizeof(HashMap) + map_ref->getBufferSizeInBytes(); + bucket_count = map_ref->getBufferSizeInCells(); } void calculateBytesAllocated() @@ -349,6 +366,10 @@ private: const attribute_t * hierarchical_attribute = nullptr; std::size_t bytes_allocated = 0; + std::size_t element_count = 0; + std::size_t bucket_count = 0; + + std::chrono::time_point creation_time; }; } diff --git a/dbms/include/DB/Dictionaries/IDictionary.h b/dbms/include/DB/Dictionaries/IDictionary.h index 387b4e044e0..689e2b59c0d 100644 --- a/dbms/include/DB/Dictionaries/IDictionary.h +++ b/dbms/include/DB/Dictionaries/IDictionary.h @@ -2,9 +2,10 @@ #include #include -#include #include #include +#include +#include namespace DB { @@ -15,6 +16,7 @@ class IDictionary; using DictionaryPtr = std::unique_ptr; class DictionaryLifetime; +class DictionaryStructure; class ColumnString; class IDictionary @@ -28,6 +30,12 @@ public: virtual std::size_t getBytesAllocated() const = 0; + virtual double getHitRate() const = 0; + + virtual std::size_t getElementCount() const = 0; + + virtual double getLoadFactor() const = 0; + virtual bool isCached() const = 0; virtual DictionaryPtr clone() const = 0; @@ -35,6 +43,10 @@ public: virtual const DictionaryLifetime & getLifetime() const = 0; + virtual const DictionaryStructure & getStructure() const = 0; + + virtual std::chrono::time_point getCreationTime() const = 0; + virtual bool hasHierarchy() const = 0; /// do not call unless you ensure that hasHierarchy() returns true diff --git a/dbms/include/DB/Dictionaries/IDictionarySource.h b/dbms/include/DB/Dictionaries/IDictionarySource.h index 9e98c6ce0ae..1a528e50bb3 100644 --- a/dbms/include/DB/Dictionaries/IDictionarySource.h +++ b/dbms/include/DB/Dictionaries/IDictionarySource.h @@ -32,6 +32,9 @@ public: virtual DictionarySourcePtr clone() const = 0; + /// returns an informal string describing the source + virtual std::string toString() const = 0; + virtual ~IDictionarySource() = default; }; diff --git a/dbms/include/DB/Dictionaries/MySQLDictionarySource.h b/dbms/include/DB/Dictionaries/MySQLDictionarySource.h index 3818ddd6605..f74105b8ea3 100644 --- a/dbms/include/DB/Dictionaries/MySQLDictionarySource.h +++ b/dbms/include/DB/Dictionaries/MySQLDictionarySource.h @@ -18,16 +18,18 @@ class MySQLDictionarySource final : public IDictionarySource public: MySQLDictionarySource(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, Block & sample_block) - : table{config.getString(config_prefix + ".table")}, + : db{config.getString(config_prefix + ".db", "")}, + table{config.getString(config_prefix + ".table")}, sample_block{sample_block}, pool{config, config_prefix}, - load_all_query{composeLoadAllQuery(sample_block, table)}, + load_all_query{composeLoadAllQuery(sample_block, db, table)}, last_modification{getLastModification()} {} /// copy-constructor is provided in order to support cloneability MySQLDictionarySource(const MySQLDictionarySource & other) - : table{other.table}, + : db{other.db}, + table{other.table}, sample_block{other.sample_block}, pool{other.pool}, load_all_query{other.load_all_query}, last_modification{other.last_modification} @@ -52,6 +54,8 @@ public: DictionarySourcePtr clone() const override { return std::make_unique(*this); } + std::string toString() const override { return "MySQL: " + db + '.' + table; } + private: mysqlxx::DateTime getLastModification() const { @@ -84,7 +88,7 @@ private: return update_time; } - static std::string composeLoadAllQuery(const Block & block, const std::string & table) + static std::string composeLoadAllQuery(const Block & block, const std::string & db, const std::string & table) { std::string query; @@ -103,6 +107,11 @@ private: } writeString(" FROM ", out); + if (!db.empty()) + { + writeProbablyBackQuotedString(db, out); + writeChar('.', out); + } writeProbablyBackQuotedString(table, out); writeChar(';', out); } @@ -130,6 +139,11 @@ private: const auto & id_column_name = sample_block.getByPosition(0).name; writeString(" FROM ", out); + if (!db.empty()) + { + writeProbablyBackQuotedString(db, out); + writeChar('.', out); + } writeProbablyBackQuotedString(table, out); writeString(" WHERE ", out); writeProbablyBackQuotedString(id_column_name, out); @@ -142,7 +156,7 @@ private: writeString(", ", out); first = false; - writeString(toString(id), out); + writeString(DB::toString(id), out); } writeString(");", out); @@ -151,6 +165,7 @@ private: return query; } + const std::string db; const std::string table; Block sample_block; mutable mysqlxx::PoolWithFailover pool; diff --git a/dbms/include/DB/Interpreters/ExpressionActions.h b/dbms/include/DB/Interpreters/ExpressionActions.h index 1ed28fb565d..8fb3163aef8 100644 --- a/dbms/include/DB/Interpreters/ExpressionActions.h +++ b/dbms/include/DB/Interpreters/ExpressionActions.h @@ -177,7 +177,7 @@ public: { for (ColumnsWithNameAndType::const_iterator it = input_columns_.begin(); it != input_columns_.end(); ++it) { - input_columns.push_back(NameAndTypePair(it->name, it->type)); + input_columns.emplace_back(it->name, it->type); sample_block.insert(*it); } } diff --git a/dbms/include/DB/Storages/StorageSystemDictionaries.h b/dbms/include/DB/Storages/StorageSystemDictionaries.h index 12a3f2fe50d..e65da014d9d 100644 --- a/dbms/include/DB/Storages/StorageSystemDictionaries.h +++ b/dbms/include/DB/Storages/StorageSystemDictionaries.h @@ -24,7 +24,7 @@ public: private: const std::string name; - NamesAndTypesList columns; + const NamesAndTypesList columns; StorageSystemDictionaries(const std::string & name); diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 295e0e75fe1..6e663ed480f 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -437,7 +437,7 @@ void ExpressionActions::checkLimits(Block & block) const void ExpressionActions::addInput(const ColumnWithNameAndType & column) { - input_columns.push_back(NameAndTypePair(column.name, column.type)); + input_columns.emplace_back(column.name, column.type); sample_block.insert(column); } @@ -505,7 +505,7 @@ void ExpressionActions::prependArrayJoin(const ExpressionAction & action, const } for (const std::string & name : array_join_set) { - input_columns.push_back(NameAndTypePair(name, sample_block.getByName(name).type)); + input_columns.emplace_back(name, sample_block.getByName(name).type); actions.insert(actions.begin(), ExpressionAction::removeColumn(name)); } diff --git a/dbms/src/Interpreters/tests/expression.cpp b/dbms/src/Interpreters/tests/expression.cpp index 38647836c9d..35446a6b039 100644 --- a/dbms/src/Interpreters/tests/expression.cpp +++ b/dbms/src/Interpreters/tests/expression.cpp @@ -60,9 +60,9 @@ int main(int argc, char ** argv) Context context; NamesAndTypesList columns; - columns.push_back(NameAndTypePair("x", new DataTypeInt16)); - columns.push_back(NameAndTypePair("s1", new DataTypeString)); - columns.push_back(NameAndTypePair("s2", new DataTypeString)); + columns.emplace_back("x", new DataTypeInt16); + columns.emplace_back("s1", new DataTypeString); + columns.emplace_back("s2", new DataTypeString); context.setColumns(columns); ExpressionAnalyzer analyzer(ast, context, context.getColumns()); diff --git a/dbms/src/Parsers/ParserJoin.cpp b/dbms/src/Parsers/ParserJoin.cpp index a8d2d839915..7f60a8499de 100644 --- a/dbms/src/Parsers/ParserJoin.cpp +++ b/dbms/src/Parsers/ParserJoin.cpp @@ -73,6 +73,10 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte ws.ignore(pos, end); + /// Может быть указан алиас. На данный момент, он ничего не значит и не используется. + ParserAlias().ignore(pos, end); + ws.ignore(pos, end); + if (!s_using.ignore(pos, end, expected)) return false; diff --git a/dbms/src/Parsers/ParserSelectQuery.cpp b/dbms/src/Parsers/ParserSelectQuery.cpp index ed7f2f94fa7..5e6e99cf106 100644 --- a/dbms/src/Parsers/ParserSelectQuery.cpp +++ b/dbms/src/Parsers/ParserSelectQuery.cpp @@ -125,6 +125,10 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & } else return false; + + /// Может быть указан алиас. На данный момент, он ничего не значит и не используется. + ParserAlias().ignore(pos, end); + ws.ignore(pos, end); } /** FINAL и SAMPLE может быть здесь или после всех JOIN-ов diff --git a/dbms/src/Storages/StorageSystemDatabases.cpp b/dbms/src/Storages/StorageSystemDatabases.cpp index 3576c1a5b04..c9f3d02d37c 100644 --- a/dbms/src/Storages/StorageSystemDatabases.cpp +++ b/dbms/src/Storages/StorageSystemDatabases.cpp @@ -11,7 +11,7 @@ namespace DB StorageSystemDatabases::StorageSystemDatabases(const std::string & name_) : name(name_) { - columns.push_back(NameAndTypePair("name", new DataTypeString)); + columns.emplace_back("name", new DataTypeString); } StoragePtr StorageSystemDatabases::create(const std::string & name_) diff --git a/dbms/src/Storages/StorageSystemDictionaries.cpp b/dbms/src/Storages/StorageSystemDictionaries.cpp index c9cbf417893..47819fcd1e7 100644 --- a/dbms/src/Storages/StorageSystemDictionaries.cpp +++ b/dbms/src/Storages/StorageSystemDictionaries.cpp @@ -1,10 +1,15 @@ #include #include #include +#include +#include #include +#include #include #include #include +#include +#include #include namespace DB @@ -13,10 +18,19 @@ namespace DB StorageSystemDictionaries::StorageSystemDictionaries(const std::string & name) : name{name}, columns{ - { "name", new DataTypeString }, - { "type", new DataTypeString }, - { "origin", new DataTypeString }, - { "bytes_allocated", new DataTypeUInt64 }, + { "name", new DataTypeString }, + { "type", new DataTypeString }, + { "origin", new DataTypeString }, + { "attribute.names", new DataTypeArray{new DataTypeString} }, + { "attribute.types", new DataTypeArray{new DataTypeString} }, + { "has_hierarchy", new DataTypeUInt8 }, + { "bytes_allocated", new DataTypeUInt64 }, + { "hit_rate", new DataTypeFloat64 }, + { "element_count", new DataTypeUInt64 }, + { "load_factor", new DataTypeFloat64 }, + { "creation_time", new DataTypeDateTime }, + { "last_exception", new DataTypeString }, + { "source", new DataTypeString } } { } @@ -41,25 +55,98 @@ BlockInputStreams StorageSystemDictionaries::read( ColumnWithNameAndType col_name{new ColumnString, new DataTypeString, "name"}; ColumnWithNameAndType col_type{new ColumnString, new DataTypeString, "type"}; ColumnWithNameAndType col_origin{new ColumnString, new DataTypeString, "origin"}; + ColumnWithNameAndType col_attribute_names{ + new ColumnArray{new ColumnString}, + new DataTypeArray{new DataTypeString}, + "attribute.names" + }; + ColumnWithNameAndType col_attribute_types{ + new ColumnArray{new ColumnString}, + new DataTypeArray{new DataTypeString}, + "attribute.types" + }; + ColumnWithNameAndType col_has_hierarchy{new ColumnUInt8, new DataTypeUInt8, "has_hierarchy"}; ColumnWithNameAndType col_bytes_allocated{new ColumnUInt64, new DataTypeUInt64, "bytes_allocated"}; + ColumnWithNameAndType col_hit_rate{new ColumnFloat64, new DataTypeFloat64, "hit_rate"}; + ColumnWithNameAndType col_element_count{new ColumnUInt64, new DataTypeUInt64, "element_count"}; + ColumnWithNameAndType col_load_factor{new ColumnFloat64, new DataTypeFloat64, "load_factor"}; + ColumnWithNameAndType col_creation_time{new ColumnUInt32, new DataTypeDateTime, "creation_time"}; + ColumnWithNameAndType col_last_exception{new ColumnString, new DataTypeString, "last_exception"}; + ColumnWithNameAndType col_source{new ColumnString, new DataTypeString, "source"}; const auto & external_dictionaries = context.getExternalDictionaries(); const std::lock_guard lock{external_dictionaries.dictionaries_mutex}; for (const auto & dict_info : external_dictionaries.dictionaries) { + const auto & name = dict_info.first; const auto dict_ptr = dict_info.second.first->get(); - col_name.column->insert(dict_info.first); + + col_name.column->insert(name); col_type.column->insert(dict_ptr->getTypeName()); col_origin.column->insert(dict_info.second.second); + + const auto & dict_struct = dict_ptr->getStructure(); + Array attribute_names; + Array attribute_types; + for (const auto & attribute : dict_struct.attributes) + { + attribute_names.push_back(attribute.name); + attribute_types.push_back(attribute.type->getName()); + } + col_attribute_names.column->insert(attribute_names); + col_attribute_types.column->insert(attribute_types); + col_has_hierarchy.column->insert(UInt64{dict_ptr->hasHierarchy()}); col_bytes_allocated.column->insert(dict_ptr->getBytesAllocated()); + col_hit_rate.column->insert(dict_ptr->getHitRate()); + col_element_count.column->insert(dict_ptr->getElementCount()); + col_load_factor.column->insert(dict_ptr->getLoadFactor()); + col_creation_time.column->insert(std::chrono::system_clock::to_time_t(dict_ptr->getCreationTime())); + + const auto exception_it = external_dictionaries.stored_exceptions.find(name); + if (exception_it != std::end(external_dictionaries.stored_exceptions)) + { + try + { + std::rethrow_exception(exception_it->second); + } + catch (const Exception & e) + { + col_last_exception.column->insert("DB::Exception. Code " + toString(e.code()) + ". " + e.message()); + } + catch (const Poco::Exception & e) + { + col_last_exception.column->insert("Poco::Exception. " + e.message()); + } + catch (const std::exception & e) + { + col_last_exception.column->insert("std::exception. " + std::string{e.what()}); + } + catch (...) + { + col_last_exception.column->insert(std::string{""}); + } + } + else + col_last_exception.column->insert(std::string{}); + + col_source.column->insert(dict_ptr->getSource()->toString()); } Block block{ col_name, col_type, col_origin, - col_bytes_allocated + col_attribute_names, + col_attribute_types, + col_has_hierarchy, + col_bytes_allocated, + col_hit_rate, + col_element_count, + col_load_factor, + col_creation_time, + col_last_exception, + col_source }; return BlockInputStreams{1, new OneBlockInputStream{block}}; diff --git a/dbms/src/Storages/StorageSystemEvents.cpp b/dbms/src/Storages/StorageSystemEvents.cpp index 4b90e3ae4bc..a2532340fe3 100644 --- a/dbms/src/Storages/StorageSystemEvents.cpp +++ b/dbms/src/Storages/StorageSystemEvents.cpp @@ -13,8 +13,8 @@ namespace DB StorageSystemEvents::StorageSystemEvents(const std::string & name_) : name(name_) { - columns.push_back(NameAndTypePair("event", new DataTypeString)); - columns.push_back(NameAndTypePair("value", new DataTypeUInt64)); + columns.emplace_back("event", new DataTypeString); + columns.emplace_back("value", new DataTypeUInt64); } StoragePtr StorageSystemEvents::create(const std::string & name_) diff --git a/dbms/src/Storages/StorageSystemNumbers.cpp b/dbms/src/Storages/StorageSystemNumbers.cpp index ae370669c46..26ed58b9ba7 100644 --- a/dbms/src/Storages/StorageSystemNumbers.cpp +++ b/dbms/src/Storages/StorageSystemNumbers.cpp @@ -56,7 +56,7 @@ private: StorageSystemNumbers::StorageSystemNumbers(const std::string & name_, bool multithreaded_) : name(name_), multithreaded(multithreaded_) { - columns.push_back(NameAndTypePair("number", new DataTypeUInt64)); + columns.emplace_back("number", new DataTypeUInt64); } StoragePtr StorageSystemNumbers::create(const std::string & name_, bool multithreaded_) diff --git a/dbms/src/Storages/StorageSystemOne.cpp b/dbms/src/Storages/StorageSystemOne.cpp index c5f0459d71b..27052985ba4 100644 --- a/dbms/src/Storages/StorageSystemOne.cpp +++ b/dbms/src/Storages/StorageSystemOne.cpp @@ -14,7 +14,7 @@ namespace DB StorageSystemOne::StorageSystemOne(const std::string & name_) : name(name_) { - columns.push_back(NameAndTypePair("dummy", new DataTypeUInt8)); + columns.emplace_back("dummy", new DataTypeUInt8); } StoragePtr StorageSystemOne::create(const std::string & name_) diff --git a/dbms/src/Storages/StorageSystemParts.cpp b/dbms/src/Storages/StorageSystemParts.cpp index 3bb45f2b8e9..5606dfbeff6 100644 --- a/dbms/src/Storages/StorageSystemParts.cpp +++ b/dbms/src/Storages/StorageSystemParts.cpp @@ -16,19 +16,19 @@ namespace DB StorageSystemParts::StorageSystemParts(const std::string & name_) : name(name_) { - columns.push_back(NameAndTypePair("partition", new DataTypeString)); - columns.push_back(NameAndTypePair("name", new DataTypeString)); - columns.push_back(NameAndTypePair("replicated", new DataTypeUInt8)); - columns.push_back(NameAndTypePair("active", new DataTypeUInt8)); - columns.push_back(NameAndTypePair("marks", new DataTypeUInt64)); - columns.push_back(NameAndTypePair("bytes", new DataTypeUInt64)); - columns.push_back(NameAndTypePair("modification_time", new DataTypeDateTime)); - columns.push_back(NameAndTypePair("remove_time", new DataTypeDateTime)); - columns.push_back(NameAndTypePair("refcount", new DataTypeUInt32)); + columns.emplace_back("partition", new DataTypeString); + columns.emplace_back("name", new DataTypeString); + columns.emplace_back("replicated", new DataTypeUInt8); + columns.emplace_back("active", new DataTypeUInt8); + columns.emplace_back("marks", new DataTypeUInt64); + columns.emplace_back("bytes", new DataTypeUInt64); + columns.emplace_back("modification_time", new DataTypeDateTime); + columns.emplace_back("remove_time", new DataTypeDateTime); + columns.emplace_back("refcount", new DataTypeUInt32); - columns.push_back(NameAndTypePair("database", new DataTypeString)); - columns.push_back(NameAndTypePair("table", new DataTypeString)); - columns.push_back(NameAndTypePair("engine", new DataTypeString)); + columns.emplace_back("database", new DataTypeString); + columns.emplace_back("table", new DataTypeString); + columns.emplace_back("engine", new DataTypeString); } StoragePtr StorageSystemParts::create(const std::string & name_) diff --git a/dbms/src/Storages/StorageSystemTables.cpp b/dbms/src/Storages/StorageSystemTables.cpp index 906c4057d8d..f0b2bc65407 100644 --- a/dbms/src/Storages/StorageSystemTables.cpp +++ b/dbms/src/Storages/StorageSystemTables.cpp @@ -12,9 +12,9 @@ namespace DB StorageSystemTables::StorageSystemTables(const std::string & name_) : name(name_) { - columns.push_back(NameAndTypePair("database", new DataTypeString)); - columns.push_back(NameAndTypePair("name", new DataTypeString)); - columns.push_back(NameAndTypePair("engine", new DataTypeString)); + columns.emplace_back("database", new DataTypeString); + columns.emplace_back("name", new DataTypeString); + columns.emplace_back("engine", new DataTypeString); } StoragePtr StorageSystemTables::create(const std::string & name_) diff --git a/dbms/src/Storages/tests/pk_condition.cpp b/dbms/src/Storages/tests/pk_condition.cpp index e42f5bd482b..b67b41d2484 100644 --- a/dbms/src/Storages/tests/pk_condition.cpp +++ b/dbms/src/Storages/tests/pk_condition.cpp @@ -32,7 +32,7 @@ int main(int argc, const char ** argv) } Context context; NamesAndTypesList columns; - columns.push_back(NameAndTypePair("key", new DataTypeUInt64)); + columns.emplace_back("key", new DataTypeUInt64); SortDescription sort_descr; sort_descr.push_back(SortColumnDescription("key", 1)); diff --git a/dbms/tests/queries/0_stateless/00138_table_aliases.reference b/dbms/tests/queries/0_stateless/00138_table_aliases.reference new file mode 100644 index 00000000000..738256fa6ec --- /dev/null +++ b/dbms/tests/queries/0_stateless/00138_table_aliases.reference @@ -0,0 +1,2 @@ +0 +1 Hello diff --git a/dbms/tests/queries/0_stateless/00138_table_aliases.sql b/dbms/tests/queries/0_stateless/00138_table_aliases.sql new file mode 100644 index 00000000000..58fe2ac65e9 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00138_table_aliases.sql @@ -0,0 +1,2 @@ +SELECT * FROM `system`.`one` AS `xxx`; +SELECT 1 AS k, s FROM `system`.`one` AS `xxx` ANY LEFT JOIN (SELECT 1 AS k, 'Hello' AS s) AS `yyy` USING k; diff --git a/libs/libmysqlxx/include/mysqlxx/Date.h b/libs/libmysqlxx/include/mysqlxx/Date.h index aee23f2ef89..d78f74ea266 100644 --- a/libs/libmysqlxx/include/mysqlxx/Date.h +++ b/libs/libmysqlxx/include/mysqlxx/Date.h @@ -185,3 +185,12 @@ inline std::ostream & operator<< (std::ostream & ostr, const Date & date) } } + + +namespace std +{ +inline string to_string(const mysqlxx::Date & date) +{ + return date.toString(); +} +} diff --git a/libs/libmysqlxx/include/mysqlxx/DateTime.h b/libs/libmysqlxx/include/mysqlxx/DateTime.h index 8e22084d166..1c122b6cc7e 100644 --- a/libs/libmysqlxx/include/mysqlxx/DateTime.h +++ b/libs/libmysqlxx/include/mysqlxx/DateTime.h @@ -28,7 +28,7 @@ private: unsigned char m_hour; unsigned char m_minute; unsigned char m_second; - + void init(time_t time) { if (unlikely(time > DATE_LUT_MAX || time == 0)) @@ -39,10 +39,10 @@ private: m_hour = 0; m_minute = 0; m_second = 0; - + return; } - + DateLUT & date_lut = DateLUT::instance(); const DateLUT::Values & values = date_lut.getValues(time); @@ -190,3 +190,14 @@ inline std::ostream & operator<< (std::ostream & ostr, const DateTime & datetime } } + + +namespace std +{ +inline string to_string(const mysqlxx::DateTime & datetime) +{ + stringstream str; + str << datetime; + return str.str(); +} +}