#pragma once #include #include #include "clickhouse/columns/itemview.h" #include "clickhouse/query.h" #include "utils_meta.h" #include "utils_comparison.h" #include #include #include #include #include #include #include #include #include #include #include namespace clickhouse { class Client; class Block; class Type; struct ServerInfo; struct Profile; struct QuerySettingsField; struct Progress; } template auto getEnvOrDefault(const std::string& env, const char * default_val) { const char* v = std::getenv(env.c_str()); if (!v && !default_val) throw std::runtime_error("Environment var '" + env + "' is not set."); const std::string value = v ? v : default_val; if constexpr (std::is_same_v) { return value; } else if constexpr (std::is_integral_v) { // since std::from_chars is not available on GCC-7 on linux if constexpr (std::is_signed_v) { if constexpr (sizeof(ResultType) <= sizeof(int)) return std::stoi(value); else if constexpr (sizeof(ResultType) <= sizeof(long)) return std::stol(value); else if constexpr (sizeof(ResultType) <= sizeof(long long)) return std::stoll(value); } else if constexpr (std::is_unsigned_v) { if constexpr (sizeof(ResultType) <= sizeof(unsigned long)) // For cases when ResultType is unsigned int. return static_cast(std::stoul(value)); else if constexpr (sizeof(ResultType) <= sizeof(unsigned long long)) return std::stoull(value); } } } template inline const char * getPrefix() { const char * prefix = "?"; if constexpr (std::ratio_equal_v) { prefix = "n"; } else if constexpr (std::ratio_equal_v) { prefix = "u"; } else if constexpr (std::ratio_equal_v) { prefix = "m"; } else if constexpr (std::ratio_equal_v) { prefix = "c"; } else if constexpr (std::ratio_equal_v) { prefix = "d"; } else if constexpr (std::ratio_equal_v>) { prefix = ""; } else { static_assert("Unsupported ratio"); } return prefix; } template > inline std::ostream & printTuple(std::ostream & ostr, [[maybe_unused]] const T & t) { static_assert(index <= std::tuple_size_v); if constexpr (index == 0) { return ostr << "( "; } else { printTuple(ostr, t); using ElementType = std::tuple_element_t; if constexpr (is_container_v) { ostr << PrintContainer{std::get(t)}; } else { ostr << std::get<0>(t); } if constexpr (index == std::tuple_size_v) { return ostr << " )"; } else { return ostr << ", "; } } } namespace std { template inline ostream & operator<<(ostream & ostr, const chrono::duration & d) { return ostr << d.count() << ::getPrefix

() << "s"; } template inline ostream & operator<<(ostream & ostr, const pair & t) { return ostr << "{ " << t.first << ", " << t.second << " }"; } template inline ostream & operator<<(ostream & ostr, const tuple & t) { return printTuple(ostr, t); } template inline ostream & operator<<(ostream & ostr, const optional & t) { if (t.has_value()) { return ostr << *t; } else { return ostr << "NULL"; } } } struct in_addr; struct in6_addr; // Helper for pretty-printing of the Block struct PrettyPrintBlock { const clickhouse::Block & block; }; namespace clickhouse { std::ostream& operator<<(std::ostream & ostr, const Block & block); std::ostream& operator<<(std::ostream & ostr, const Type & type); std::ostream & operator<<(std::ostream & ostr, const ServerInfo & server_info); std::ostream & operator<<(std::ostream & ostr, const Profile & profile); std::ostream & operator<<(std::ostream & ostr, const Progress & progress); std::ostream & operator<<(std::ostream& ostr, const ItemView& item_view); } std::ostream& operator<<(std::ostream & ostr, const PrettyPrintBlock & block); std::ostream& operator<<(std::ostream& ostr, const in_addr& addr); std::ostream& operator<<(std::ostream& ostr, const in6_addr& addr); template struct PrintContainer { const Container & container_; explicit PrintContainer(const Container& container) : container_(container) {} }; template std::ostream& operator<<(std::ostream & ostr, const PrintContainer& print_container) { ostr << "["; const auto & container = print_container.container_; for (auto i = std::begin(container); i != std::end(container); /*intentionally no ++i*/) { const auto & elem = *i; if constexpr (is_string_v) { ostr << '"' << elem << '"'; } else if constexpr (is_container_v>) { ostr << PrintContainer{elem}; } else { ostr << elem; } if (++i != std::end(container)) { ostr << ", "; } } return ostr << "] (" << std::size(container) << " items)"; } inline uint64_t versionNumber( uint64_t version_major, uint64_t version_minor, uint64_t version_patch = 0, uint64_t revision = 0) { // in this case version_major can be up to 1000 static auto revision_decimal_places = 8; static auto patch_decimal_places = 4; static auto minor_decimal_places = 4; auto const result = version_major * static_cast(std::pow(10, minor_decimal_places + patch_decimal_places + revision_decimal_places)) + version_minor * static_cast(std::pow(10, patch_decimal_places + revision_decimal_places)) + version_patch * static_cast(std::pow(10, revision_decimal_places)) + revision; return result; } uint64_t versionNumber(const clickhouse::ServerInfo & server_info); std::string ToString(const clickhouse::UUID& v);