mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-21 07:50:49 +00:00
Merge
This commit is contained in:
commit
259c37fd58
@ -811,6 +811,11 @@ public:
|
|||||||
return grower.bufSize() * sizeof(Cell);
|
return grower.bufSize() * sizeof(Cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getBufferSizeInCells() const
|
||||||
|
{
|
||||||
|
return grower.bufSize();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DBMS_HASH_MAP_COUNT_COLLISIONS
|
#ifdef DBMS_HASH_MAP_COUNT_COLLISIONS
|
||||||
size_t getCollisions() const
|
size_t getCollisions() const
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <statdaemons/ext/scope_guard.hpp>
|
#include <statdaemons/ext/scope_guard.hpp>
|
||||||
#include <Poco/RWLock.h>
|
#include <Poco/RWLock.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -47,6 +48,19 @@ public:
|
|||||||
|
|
||||||
std::size_t getBytesAllocated() const override { return bytes_allocated; }
|
std::size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||||
|
|
||||||
|
double getHitRate() const override
|
||||||
|
{
|
||||||
|
return static_cast<double>(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<double>(element_count.load(std::memory_order_relaxed)) / size;
|
||||||
|
}
|
||||||
|
|
||||||
bool isCached() const override { return true; }
|
bool isCached() const override { return true; }
|
||||||
|
|
||||||
DictionaryPtr clone() const override { return std::make_unique<CacheDictionary>(*this); }
|
DictionaryPtr clone() const override { return std::make_unique<CacheDictionary>(*this); }
|
||||||
@ -55,6 +69,13 @@ public:
|
|||||||
|
|
||||||
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
||||||
|
|
||||||
|
const DictionaryStructure & getStructure() const override { return dict_struct; }
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> getCreationTime() const override
|
||||||
|
{
|
||||||
|
return creation_time;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
id_t toParent(const id_t id) const override
|
||||||
@ -179,6 +200,7 @@ private:
|
|||||||
const auto size = dict_struct.attributes.size();
|
const auto size = dict_struct.attributes.size();
|
||||||
attributes.reserve(size);
|
attributes.reserve(size);
|
||||||
|
|
||||||
|
bytes_allocated += size * sizeof(cell_metadata_t);
|
||||||
bytes_allocated += size * sizeof(attributes.front());
|
bytes_allocated += size * sizeof(attributes.front());
|
||||||
|
|
||||||
for (const auto & attribute : dict_struct.attributes)
|
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())
|
if (outdated_ids.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -351,7 +376,11 @@ private:
|
|||||||
|
|
||||||
/// optimistic code completed successfully
|
/// optimistic code completed successfully
|
||||||
if (!found_outdated_values)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/// now onto the pessimistic one, discard possibly partial results from the optimistic path
|
/// now onto the pessimistic one, discard possibly partial results from the optimistic path
|
||||||
out->getChars().resize_assume_reserved(0);
|
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
|
/// request new values
|
||||||
if (!outdated_ids.empty())
|
if (!outdated_ids.empty())
|
||||||
{
|
{
|
||||||
@ -456,6 +488,10 @@ private:
|
|||||||
setAttributeValue(attribute, cell_idx, attribute_column[i]);
|
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;
|
cell.id = id;
|
||||||
if (dict_lifetime.min_sec != 0 && dict_lifetime.max_sec != 0)
|
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)};
|
cell.expires_at = std::chrono::system_clock::now() + std::chrono::seconds{distribution(rnd_engine)};
|
||||||
@ -481,6 +517,9 @@ private:
|
|||||||
for (auto & attribute : attributes)
|
for (auto & attribute : attributes)
|
||||||
setDefaultAttributeValue(attribute, cell_idx);
|
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;
|
cell.id = id;
|
||||||
if (dict_lifetime.min_sec != 0 && dict_lifetime.max_sec != 0)
|
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)};
|
cell.expires_at = std::chrono::system_clock::now() + std::chrono::seconds{distribution(rnd_engine)};
|
||||||
@ -613,6 +652,7 @@ private:
|
|||||||
|
|
||||||
mutable Poco::RWLock rw_lock;
|
mutable Poco::RWLock rw_lock;
|
||||||
const std::size_t size;
|
const std::size_t size;
|
||||||
|
const std::uint64_t zero_cell_idx{getCellIdx(0)};
|
||||||
std::map<std::string, std::size_t> attribute_index_by_name;
|
std::map<std::string, std::size_t> attribute_index_by_name;
|
||||||
mutable std::vector<attribute_t> attributes;
|
mutable std::vector<attribute_t> attributes;
|
||||||
mutable std::vector<cell_metadata_t> cells;
|
mutable std::vector<cell_metadata_t> cells;
|
||||||
@ -620,7 +660,12 @@ private:
|
|||||||
|
|
||||||
mutable std::mt19937_64 rnd_engine{getSeed()};
|
mutable std::mt19937_64 rnd_engine{getSeed()};
|
||||||
|
|
||||||
mutable std::size_t bytes_allocated;
|
mutable std::size_t bytes_allocated = 0;
|
||||||
|
mutable std::atomic<std::size_t> element_count{};
|
||||||
|
mutable std::atomic<std::size_t> hit_count{};
|
||||||
|
mutable std::atomic<std::size_t> query_count{};
|
||||||
|
|
||||||
|
const std::chrono::time_point<std::chrono::system_clock> creation_time = std::chrono::system_clock::now();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,8 @@ public:
|
|||||||
|
|
||||||
DictionarySourcePtr clone() const override { return std::make_unique<ClickHouseDictionarySource>(*this); }
|
DictionarySourcePtr clone() const override { return std::make_unique<ClickHouseDictionarySource>(*this); }
|
||||||
|
|
||||||
|
std::string toString() const override { return "ClickHouse: " + db + '.' + table; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string composeLoadAllQuery(const Block & block, const std::string & db, const std::string & table)
|
static std::string composeLoadAllQuery(const Block & block, const std::string & db, const std::string & table)
|
||||||
{
|
{
|
||||||
@ -94,8 +96,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeString(" FROM ", out);
|
writeString(" FROM ", out);
|
||||||
writeProbablyBackQuotedString(db, out);
|
if (!db.empty())
|
||||||
writeChar('.', out);
|
{
|
||||||
|
writeProbablyBackQuotedString(db, out);
|
||||||
|
writeChar('.', out);
|
||||||
|
}
|
||||||
writeProbablyBackQuotedString(table, out);
|
writeProbablyBackQuotedString(table, out);
|
||||||
writeChar(';', out);
|
writeChar(';', out);
|
||||||
}
|
}
|
||||||
@ -123,8 +128,11 @@ private:
|
|||||||
|
|
||||||
const auto & id_column_name = sample_block.getByPosition(0).name;
|
const auto & id_column_name = sample_block.getByPosition(0).name;
|
||||||
writeString(" FROM ", out);
|
writeString(" FROM ", out);
|
||||||
writeProbablyBackQuotedString(db, out);
|
if (!db.empty())
|
||||||
writeChar('.', out);
|
{
|
||||||
|
writeProbablyBackQuotedString(db, out);
|
||||||
|
writeChar('.', out);
|
||||||
|
}
|
||||||
writeProbablyBackQuotedString(table, out);
|
writeProbablyBackQuotedString(table, out);
|
||||||
writeString(" WHERE ", out);
|
writeString(" WHERE ", out);
|
||||||
writeProbablyBackQuotedString(id_column_name, out);
|
writeProbablyBackQuotedString(id_column_name, out);
|
||||||
@ -137,7 +145,7 @@ private:
|
|||||||
writeString(", ", out);
|
writeString(", ", out);
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
writeString(toString(id), out);
|
writeString(DB::toString(id), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeString(");", out);
|
writeString(");", out);
|
||||||
|
@ -51,6 +51,8 @@ public:
|
|||||||
|
|
||||||
DictionarySourcePtr clone() const override { return std::make_unique<FileDictionarySource>(*this); }
|
DictionarySourcePtr clone() const override { return std::make_unique<FileDictionarySource>(*this); }
|
||||||
|
|
||||||
|
std::string toString() const override { return "File: " + filename + ' ' + format; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Timestamp getLastModification() const { return Poco::File{filename}.getLastModified(); }
|
Poco::Timestamp getLastModification() const { return Poco::File{filename}.getLastModified(); }
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ public:
|
|||||||
createAttributes();
|
createAttributes();
|
||||||
loadData();
|
loadData();
|
||||||
calculateBytesAllocated();
|
calculateBytesAllocated();
|
||||||
|
creation_time = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatDictionary(const FlatDictionary & other)
|
FlatDictionary(const FlatDictionary & other)
|
||||||
@ -37,6 +38,12 @@ public:
|
|||||||
|
|
||||||
std::size_t getBytesAllocated() const override { return bytes_allocated; }
|
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<double>(element_count) / bucket_count; }
|
||||||
|
|
||||||
bool isCached() const override { return false; }
|
bool isCached() const override { return false; }
|
||||||
|
|
||||||
DictionaryPtr clone() const override { return std::make_unique<FlatDictionary>(*this); }
|
DictionaryPtr clone() const override { return std::make_unique<FlatDictionary>(*this); }
|
||||||
@ -45,6 +52,13 @@ public:
|
|||||||
|
|
||||||
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
||||||
|
|
||||||
|
const DictionaryStructure & getStructure() const override { return dict_struct; }
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> getCreationTime() const override
|
||||||
|
{
|
||||||
|
return creation_time;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
id_t toParent(const id_t id) const override
|
||||||
@ -196,6 +210,8 @@ private:
|
|||||||
{
|
{
|
||||||
const auto & id_column = *block.getByPosition(0).column;
|
const auto & id_column = *block.getByPosition(0).column;
|
||||||
|
|
||||||
|
element_count += id_column.size();
|
||||||
|
|
||||||
for (const auto attribute_idx : ext::range(0, attributes.size()))
|
for (const auto attribute_idx : ext::range(0, attributes.size()))
|
||||||
{
|
{
|
||||||
const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column;
|
const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column;
|
||||||
@ -214,6 +230,7 @@ private:
|
|||||||
{
|
{
|
||||||
const auto & array_ref = std::get<std::unique_ptr<PODArray<T>>>(attribute.arrays);
|
const auto & array_ref = std::get<std::unique_ptr<PODArray<T>>>(attribute.arrays);
|
||||||
bytes_allocated += sizeof(PODArray<T>) + array_ref->storage_size();
|
bytes_allocated += sizeof(PODArray<T>) + array_ref->storage_size();
|
||||||
|
bucket_count = array_ref->capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateBytesAllocated()
|
void calculateBytesAllocated()
|
||||||
@ -360,6 +377,10 @@ private:
|
|||||||
const attribute_t * hierarchical_attribute = nullptr;
|
const attribute_t * hierarchical_attribute = nullptr;
|
||||||
|
|
||||||
std::size_t bytes_allocated = 0;
|
std::size_t bytes_allocated = 0;
|
||||||
|
std::size_t element_count = 0;
|
||||||
|
std::size_t bucket_count = 0;
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> creation_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ public:
|
|||||||
createAttributes();
|
createAttributes();
|
||||||
loadData();
|
loadData();
|
||||||
calculateBytesAllocated();
|
calculateBytesAllocated();
|
||||||
|
creation_time = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
HashedDictionary(const HashedDictionary & other)
|
HashedDictionary(const HashedDictionary & other)
|
||||||
@ -35,6 +36,12 @@ public:
|
|||||||
|
|
||||||
std::size_t getBytesAllocated() const override { return bytes_allocated; }
|
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<double>(element_count) / bucket_count; }
|
||||||
|
|
||||||
bool isCached() const override { return false; }
|
bool isCached() const override { return false; }
|
||||||
|
|
||||||
DictionaryPtr clone() const override { return std::make_unique<HashedDictionary>(*this); }
|
DictionaryPtr clone() const override { return std::make_unique<HashedDictionary>(*this); }
|
||||||
@ -43,6 +50,13 @@ public:
|
|||||||
|
|
||||||
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
const DictionaryLifetime & getLifetime() const override { return dict_lifetime; }
|
||||||
|
|
||||||
|
const DictionaryStructure & getStructure() const override { return dict_struct; }
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> getCreationTime() const override
|
||||||
|
{
|
||||||
|
return creation_time;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasHierarchy() const override { return hierarchical_attribute; }
|
bool hasHierarchy() const override { return hierarchical_attribute; }
|
||||||
|
|
||||||
id_t toParent(const id_t id) const override
|
id_t toParent(const id_t id) const override
|
||||||
@ -197,6 +211,8 @@ private:
|
|||||||
{
|
{
|
||||||
const auto & id_column = *block.getByPosition(0).column;
|
const auto & id_column = *block.getByPosition(0).column;
|
||||||
|
|
||||||
|
element_count += id_column.size();
|
||||||
|
|
||||||
for (const auto attribute_idx : ext::range(0, attributes.size()))
|
for (const auto attribute_idx : ext::range(0, attributes.size()))
|
||||||
{
|
{
|
||||||
const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column;
|
const auto & attribute_column = *block.getByPosition(attribute_idx + 1).column;
|
||||||
@ -215,6 +231,7 @@ private:
|
|||||||
{
|
{
|
||||||
const auto & map_ref = std::get<std::unique_ptr<HashMap<UInt64, T>>>(attribute.maps);
|
const auto & map_ref = std::get<std::unique_ptr<HashMap<UInt64, T>>>(attribute.maps);
|
||||||
bytes_allocated += sizeof(HashMap<UInt64, T>) + map_ref->getBufferSizeInBytes();
|
bytes_allocated += sizeof(HashMap<UInt64, T>) + map_ref->getBufferSizeInBytes();
|
||||||
|
bucket_count = map_ref->getBufferSizeInCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateBytesAllocated()
|
void calculateBytesAllocated()
|
||||||
@ -349,6 +366,10 @@ private:
|
|||||||
const attribute_t * hierarchical_attribute = nullptr;
|
const attribute_t * hierarchical_attribute = nullptr;
|
||||||
|
|
||||||
std::size_t bytes_allocated = 0;
|
std::size_t bytes_allocated = 0;
|
||||||
|
std::size_t element_count = 0;
|
||||||
|
std::size_t bucket_count = 0;
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> creation_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
#include <DB/Core/StringRef.h>
|
#include <DB/Core/StringRef.h>
|
||||||
#include <memory>
|
|
||||||
#include <Poco/Util/XMLConfiguration.h>
|
#include <Poco/Util/XMLConfiguration.h>
|
||||||
#include <DB/Common/PODArray.h>
|
#include <DB/Common/PODArray.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -15,6 +16,7 @@ class IDictionary;
|
|||||||
using DictionaryPtr = std::unique_ptr<IDictionary>;
|
using DictionaryPtr = std::unique_ptr<IDictionary>;
|
||||||
|
|
||||||
class DictionaryLifetime;
|
class DictionaryLifetime;
|
||||||
|
class DictionaryStructure;
|
||||||
class ColumnString;
|
class ColumnString;
|
||||||
|
|
||||||
class IDictionary
|
class IDictionary
|
||||||
@ -28,6 +30,12 @@ public:
|
|||||||
|
|
||||||
virtual std::size_t getBytesAllocated() const = 0;
|
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 bool isCached() const = 0;
|
||||||
virtual DictionaryPtr clone() const = 0;
|
virtual DictionaryPtr clone() const = 0;
|
||||||
|
|
||||||
@ -35,6 +43,10 @@ public:
|
|||||||
|
|
||||||
virtual const DictionaryLifetime & getLifetime() const = 0;
|
virtual const DictionaryLifetime & getLifetime() const = 0;
|
||||||
|
|
||||||
|
virtual const DictionaryStructure & getStructure() const = 0;
|
||||||
|
|
||||||
|
virtual std::chrono::time_point<std::chrono::system_clock> getCreationTime() const = 0;
|
||||||
|
|
||||||
virtual bool hasHierarchy() const = 0;
|
virtual bool hasHierarchy() const = 0;
|
||||||
|
|
||||||
/// do not call unless you ensure that hasHierarchy() returns true
|
/// do not call unless you ensure that hasHierarchy() returns true
|
||||||
|
@ -32,6 +32,9 @@ public:
|
|||||||
|
|
||||||
virtual DictionarySourcePtr clone() const = 0;
|
virtual DictionarySourcePtr clone() const = 0;
|
||||||
|
|
||||||
|
/// returns an informal string describing the source
|
||||||
|
virtual std::string toString() const = 0;
|
||||||
|
|
||||||
virtual ~IDictionarySource() = default;
|
virtual ~IDictionarySource() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,16 +18,18 @@ class MySQLDictionarySource final : public IDictionarySource
|
|||||||
public:
|
public:
|
||||||
MySQLDictionarySource(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix,
|
MySQLDictionarySource(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix,
|
||||||
Block & sample_block)
|
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},
|
sample_block{sample_block},
|
||||||
pool{config, config_prefix},
|
pool{config, config_prefix},
|
||||||
load_all_query{composeLoadAllQuery(sample_block, table)},
|
load_all_query{composeLoadAllQuery(sample_block, db, table)},
|
||||||
last_modification{getLastModification()}
|
last_modification{getLastModification()}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// copy-constructor is provided in order to support cloneability
|
/// copy-constructor is provided in order to support cloneability
|
||||||
MySQLDictionarySource(const MySQLDictionarySource & other)
|
MySQLDictionarySource(const MySQLDictionarySource & other)
|
||||||
: table{other.table},
|
: db{other.db},
|
||||||
|
table{other.table},
|
||||||
sample_block{other.sample_block},
|
sample_block{other.sample_block},
|
||||||
pool{other.pool},
|
pool{other.pool},
|
||||||
load_all_query{other.load_all_query}, last_modification{other.last_modification}
|
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<MySQLDictionarySource>(*this); }
|
DictionarySourcePtr clone() const override { return std::make_unique<MySQLDictionarySource>(*this); }
|
||||||
|
|
||||||
|
std::string toString() const override { return "MySQL: " + db + '.' + table; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mysqlxx::DateTime getLastModification() const
|
mysqlxx::DateTime getLastModification() const
|
||||||
{
|
{
|
||||||
@ -84,7 +88,7 @@ private:
|
|||||||
return update_time;
|
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;
|
std::string query;
|
||||||
|
|
||||||
@ -103,6 +107,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeString(" FROM ", out);
|
writeString(" FROM ", out);
|
||||||
|
if (!db.empty())
|
||||||
|
{
|
||||||
|
writeProbablyBackQuotedString(db, out);
|
||||||
|
writeChar('.', out);
|
||||||
|
}
|
||||||
writeProbablyBackQuotedString(table, out);
|
writeProbablyBackQuotedString(table, out);
|
||||||
writeChar(';', out);
|
writeChar(';', out);
|
||||||
}
|
}
|
||||||
@ -130,6 +139,11 @@ private:
|
|||||||
|
|
||||||
const auto & id_column_name = sample_block.getByPosition(0).name;
|
const auto & id_column_name = sample_block.getByPosition(0).name;
|
||||||
writeString(" FROM ", out);
|
writeString(" FROM ", out);
|
||||||
|
if (!db.empty())
|
||||||
|
{
|
||||||
|
writeProbablyBackQuotedString(db, out);
|
||||||
|
writeChar('.', out);
|
||||||
|
}
|
||||||
writeProbablyBackQuotedString(table, out);
|
writeProbablyBackQuotedString(table, out);
|
||||||
writeString(" WHERE ", out);
|
writeString(" WHERE ", out);
|
||||||
writeProbablyBackQuotedString(id_column_name, out);
|
writeProbablyBackQuotedString(id_column_name, out);
|
||||||
@ -142,7 +156,7 @@ private:
|
|||||||
writeString(", ", out);
|
writeString(", ", out);
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
writeString(toString(id), out);
|
writeString(DB::toString(id), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeString(");", out);
|
writeString(");", out);
|
||||||
@ -151,6 +165,7 @@ private:
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string db;
|
||||||
const std::string table;
|
const std::string table;
|
||||||
Block sample_block;
|
Block sample_block;
|
||||||
mutable mysqlxx::PoolWithFailover pool;
|
mutable mysqlxx::PoolWithFailover pool;
|
||||||
|
@ -177,7 +177,7 @@ public:
|
|||||||
{
|
{
|
||||||
for (ColumnsWithNameAndType::const_iterator it = input_columns_.begin(); it != input_columns_.end(); ++it)
|
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);
|
sample_block.insert(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string name;
|
const std::string name;
|
||||||
NamesAndTypesList columns;
|
const NamesAndTypesList columns;
|
||||||
|
|
||||||
StorageSystemDictionaries(const std::string & name);
|
StorageSystemDictionaries(const std::string & name);
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ void ExpressionActions::checkLimits(Block & block) const
|
|||||||
|
|
||||||
void ExpressionActions::addInput(const ColumnWithNameAndType & column)
|
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);
|
sample_block.insert(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +505,7 @@ void ExpressionActions::prependArrayJoin(const ExpressionAction & action, const
|
|||||||
}
|
}
|
||||||
for (const std::string & name : array_join_set)
|
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));
|
actions.insert(actions.begin(), ExpressionAction::removeColumn(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ int main(int argc, char ** argv)
|
|||||||
|
|
||||||
Context context;
|
Context context;
|
||||||
NamesAndTypesList columns;
|
NamesAndTypesList columns;
|
||||||
columns.push_back(NameAndTypePair("x", new DataTypeInt16));
|
columns.emplace_back("x", new DataTypeInt16);
|
||||||
columns.push_back(NameAndTypePair("s1", new DataTypeString));
|
columns.emplace_back("s1", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("s2", new DataTypeString));
|
columns.emplace_back("s2", new DataTypeString);
|
||||||
context.setColumns(columns);
|
context.setColumns(columns);
|
||||||
|
|
||||||
ExpressionAnalyzer analyzer(ast, context, context.getColumns());
|
ExpressionAnalyzer analyzer(ast, context, context.getColumns());
|
||||||
|
@ -73,6 +73,10 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
|
|||||||
|
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
|
/// Может быть указан алиас. На данный момент, он ничего не значит и не используется.
|
||||||
|
ParserAlias().ignore(pos, end);
|
||||||
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
if (!s_using.ignore(pos, end, expected))
|
if (!s_using.ignore(pos, end, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -125,6 +125,10 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/// Может быть указан алиас. На данный момент, он ничего не значит и не используется.
|
||||||
|
ParserAlias().ignore(pos, end);
|
||||||
|
ws.ignore(pos, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FINAL и SAMPLE может быть здесь или после всех JOIN-ов
|
/** FINAL и SAMPLE может быть здесь или после всех JOIN-ов
|
||||||
|
@ -11,7 +11,7 @@ namespace DB
|
|||||||
StorageSystemDatabases::StorageSystemDatabases(const std::string & name_)
|
StorageSystemDatabases::StorageSystemDatabases(const std::string & name_)
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
columns.push_back(NameAndTypePair("name", new DataTypeString));
|
columns.emplace_back("name", new DataTypeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr StorageSystemDatabases::create(const std::string & name_)
|
StoragePtr StorageSystemDatabases::create(const std::string & name_)
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
#include <DB/Storages/StorageSystemDictionaries.h>
|
#include <DB/Storages/StorageSystemDictionaries.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
|
#include <DB/DataTypes/DataTypeArray.h>
|
||||||
|
#include <DB/DataTypes/DataTypeDateTime.h>
|
||||||
#include <DB/Columns/ColumnString.h>
|
#include <DB/Columns/ColumnString.h>
|
||||||
|
#include <DB/Columns/ColumnArray.h>
|
||||||
#include <DB/DataStreams/OneBlockInputStream.h>
|
#include <DB/DataStreams/OneBlockInputStream.h>
|
||||||
#include <DB/Interpreters/Context.h>
|
#include <DB/Interpreters/Context.h>
|
||||||
#include <DB/Dictionaries/IDictionary.h>
|
#include <DB/Dictionaries/IDictionary.h>
|
||||||
|
#include <DB/Dictionaries/IDictionarySource.h>
|
||||||
|
#include <DB/Dictionaries/DictionaryStructure.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -13,10 +18,19 @@ namespace DB
|
|||||||
StorageSystemDictionaries::StorageSystemDictionaries(const std::string & name)
|
StorageSystemDictionaries::StorageSystemDictionaries(const std::string & name)
|
||||||
: name{name},
|
: name{name},
|
||||||
columns{
|
columns{
|
||||||
{ "name", new DataTypeString },
|
{ "name", new DataTypeString },
|
||||||
{ "type", new DataTypeString },
|
{ "type", new DataTypeString },
|
||||||
{ "origin", new DataTypeString },
|
{ "origin", new DataTypeString },
|
||||||
{ "bytes_allocated", new DataTypeUInt64 },
|
{ "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_name{new ColumnString, new DataTypeString, "name"};
|
||||||
ColumnWithNameAndType col_type{new ColumnString, new DataTypeString, "type"};
|
ColumnWithNameAndType col_type{new ColumnString, new DataTypeString, "type"};
|
||||||
ColumnWithNameAndType col_origin{new ColumnString, new DataTypeString, "origin"};
|
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_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 auto & external_dictionaries = context.getExternalDictionaries();
|
||||||
const std::lock_guard<std::mutex> lock{external_dictionaries.dictionaries_mutex};
|
const std::lock_guard<std::mutex> lock{external_dictionaries.dictionaries_mutex};
|
||||||
|
|
||||||
for (const auto & dict_info : external_dictionaries.dictionaries)
|
for (const auto & dict_info : external_dictionaries.dictionaries)
|
||||||
{
|
{
|
||||||
|
const auto & name = dict_info.first;
|
||||||
const auto dict_ptr = dict_info.second.first->get();
|
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_type.column->insert(dict_ptr->getTypeName());
|
||||||
col_origin.column->insert(dict_info.second.second);
|
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_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{"<unknown exception type>"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
col_last_exception.column->insert(std::string{});
|
||||||
|
|
||||||
|
col_source.column->insert(dict_ptr->getSource()->toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Block block{
|
Block block{
|
||||||
col_name,
|
col_name,
|
||||||
col_type,
|
col_type,
|
||||||
col_origin,
|
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}};
|
return BlockInputStreams{1, new OneBlockInputStream{block}};
|
||||||
|
@ -13,8 +13,8 @@ namespace DB
|
|||||||
StorageSystemEvents::StorageSystemEvents(const std::string & name_)
|
StorageSystemEvents::StorageSystemEvents(const std::string & name_)
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
columns.push_back(NameAndTypePair("event", new DataTypeString));
|
columns.emplace_back("event", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("value", new DataTypeUInt64));
|
columns.emplace_back("value", new DataTypeUInt64);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr StorageSystemEvents::create(const std::string & name_)
|
StoragePtr StorageSystemEvents::create(const std::string & name_)
|
||||||
|
@ -56,7 +56,7 @@ private:
|
|||||||
StorageSystemNumbers::StorageSystemNumbers(const std::string & name_, bool multithreaded_)
|
StorageSystemNumbers::StorageSystemNumbers(const std::string & name_, bool multithreaded_)
|
||||||
: name(name_), multithreaded(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_)
|
StoragePtr StorageSystemNumbers::create(const std::string & name_, bool multithreaded_)
|
||||||
|
@ -14,7 +14,7 @@ namespace DB
|
|||||||
StorageSystemOne::StorageSystemOne(const std::string & name_)
|
StorageSystemOne::StorageSystemOne(const std::string & name_)
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
columns.push_back(NameAndTypePair("dummy", new DataTypeUInt8));
|
columns.emplace_back("dummy", new DataTypeUInt8);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr StorageSystemOne::create(const std::string & name_)
|
StoragePtr StorageSystemOne::create(const std::string & name_)
|
||||||
|
@ -16,19 +16,19 @@ namespace DB
|
|||||||
StorageSystemParts::StorageSystemParts(const std::string & name_)
|
StorageSystemParts::StorageSystemParts(const std::string & name_)
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
columns.push_back(NameAndTypePair("partition", new DataTypeString));
|
columns.emplace_back("partition", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("name", new DataTypeString));
|
columns.emplace_back("name", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("replicated", new DataTypeUInt8));
|
columns.emplace_back("replicated", new DataTypeUInt8);
|
||||||
columns.push_back(NameAndTypePair("active", new DataTypeUInt8));
|
columns.emplace_back("active", new DataTypeUInt8);
|
||||||
columns.push_back(NameAndTypePair("marks", new DataTypeUInt64));
|
columns.emplace_back("marks", new DataTypeUInt64);
|
||||||
columns.push_back(NameAndTypePair("bytes", new DataTypeUInt64));
|
columns.emplace_back("bytes", new DataTypeUInt64);
|
||||||
columns.push_back(NameAndTypePair("modification_time", new DataTypeDateTime));
|
columns.emplace_back("modification_time", new DataTypeDateTime);
|
||||||
columns.push_back(NameAndTypePair("remove_time", new DataTypeDateTime));
|
columns.emplace_back("remove_time", new DataTypeDateTime);
|
||||||
columns.push_back(NameAndTypePair("refcount", new DataTypeUInt32));
|
columns.emplace_back("refcount", new DataTypeUInt32);
|
||||||
|
|
||||||
columns.push_back(NameAndTypePair("database", new DataTypeString));
|
columns.emplace_back("database", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("table", new DataTypeString));
|
columns.emplace_back("table", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("engine", new DataTypeString));
|
columns.emplace_back("engine", new DataTypeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr StorageSystemParts::create(const std::string & name_)
|
StoragePtr StorageSystemParts::create(const std::string & name_)
|
||||||
|
@ -12,9 +12,9 @@ namespace DB
|
|||||||
StorageSystemTables::StorageSystemTables(const std::string & name_)
|
StorageSystemTables::StorageSystemTables(const std::string & name_)
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
columns.push_back(NameAndTypePair("database", new DataTypeString));
|
columns.emplace_back("database", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("name", new DataTypeString));
|
columns.emplace_back("name", new DataTypeString);
|
||||||
columns.push_back(NameAndTypePair("engine", new DataTypeString));
|
columns.emplace_back("engine", new DataTypeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoragePtr StorageSystemTables::create(const std::string & name_)
|
StoragePtr StorageSystemTables::create(const std::string & name_)
|
||||||
|
@ -32,7 +32,7 @@ int main(int argc, const char ** argv)
|
|||||||
}
|
}
|
||||||
Context context;
|
Context context;
|
||||||
NamesAndTypesList columns;
|
NamesAndTypesList columns;
|
||||||
columns.push_back(NameAndTypePair("key", new DataTypeUInt64));
|
columns.emplace_back("key", new DataTypeUInt64);
|
||||||
SortDescription sort_descr;
|
SortDescription sort_descr;
|
||||||
sort_descr.push_back(SortColumnDescription("key", 1));
|
sort_descr.push_back(SortColumnDescription("key", 1));
|
||||||
|
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
0
|
||||||
|
1 Hello
|
2
dbms/tests/queries/0_stateless/00138_table_aliases.sql
Normal file
2
dbms/tests/queries/0_stateless/00138_table_aliases.sql
Normal file
@ -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;
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -28,7 +28,7 @@ private:
|
|||||||
unsigned char m_hour;
|
unsigned char m_hour;
|
||||||
unsigned char m_minute;
|
unsigned char m_minute;
|
||||||
unsigned char m_second;
|
unsigned char m_second;
|
||||||
|
|
||||||
void init(time_t time)
|
void init(time_t time)
|
||||||
{
|
{
|
||||||
if (unlikely(time > DATE_LUT_MAX || time == 0))
|
if (unlikely(time > DATE_LUT_MAX || time == 0))
|
||||||
@ -39,10 +39,10 @@ private:
|
|||||||
m_hour = 0;
|
m_hour = 0;
|
||||||
m_minute = 0;
|
m_minute = 0;
|
||||||
m_second = 0;
|
m_second = 0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DateLUT & date_lut = DateLUT::instance();
|
DateLUT & date_lut = DateLUT::instance();
|
||||||
const DateLUT::Values & values = date_lut.getValues(time);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user