Merge remote-tracking branch 'upstream/master' into rewrite-functions-to-subcolumns

This commit is contained in:
Anton Popov 2021-05-22 03:06:36 +03:00
commit e3ca1cf94d
126 changed files with 1497 additions and 1003 deletions

View File

@ -127,7 +127,7 @@
* Fixed some tests on AArch64 platform. [#22596](https://github.com/ClickHouse/ClickHouse/pull/22596) ([alexey-milovidov](https://github.com/alexey-milovidov)). * Fixed some tests on AArch64 platform. [#22596](https://github.com/ClickHouse/ClickHouse/pull/22596) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Added function alignment for possibly better performance. [#21431](https://github.com/ClickHouse/ClickHouse/pull/21431) ([Danila Kutenin](https://github.com/danlark1)). * Added function alignment for possibly better performance. [#21431](https://github.com/ClickHouse/ClickHouse/pull/21431) ([Danila Kutenin](https://github.com/danlark1)).
* Adjust some tests to output identical results on amd64 and aarch64 (qemu). The result was depending on implementation specific CPU behaviour. [#22590](https://github.com/ClickHouse/ClickHouse/pull/22590) ([alexey-milovidov](https://github.com/alexey-milovidov)). * Adjust some tests to output identical results on amd64 and aarch64 (qemu). The result was depending on implementation specific CPU behaviour. [#22590](https://github.com/ClickHouse/ClickHouse/pull/22590) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Allow query profiling only on x86_64. See [#15174](https://github.com/ClickHouse/ClickHouse/issues/15174)#issuecomment-812954965 and [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638)#issuecomment-703805337. This closes [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638). [#22580](https://github.com/ClickHouse/ClickHouse/pull/22580) ([alexey-milovidov](https://github.com/alexey-milovidov)). * Allow query profiling only on x86_64. See [#15174](https://github.com/ClickHouse/ClickHouse/issues/15174#issuecomment-812954965) and [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638#issuecomment-703805337). This closes [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638). [#22580](https://github.com/ClickHouse/ClickHouse/pull/22580) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Allow building with unbundled xz (lzma) using `USE_INTERNAL_XZ_LIBRARY=OFF` CMake option. [#22571](https://github.com/ClickHouse/ClickHouse/pull/22571) ([Kfir Itzhak](https://github.com/mastertheknife)). * Allow building with unbundled xz (lzma) using `USE_INTERNAL_XZ_LIBRARY=OFF` CMake option. [#22571](https://github.com/ClickHouse/ClickHouse/pull/22571) ([Kfir Itzhak](https://github.com/mastertheknife)).
* Enable bundled `openldap` on `ppc64le` [#22487](https://github.com/ClickHouse/ClickHouse/pull/22487) ([Kfir Itzhak](https://github.com/mastertheknife)). * Enable bundled `openldap` on `ppc64le` [#22487](https://github.com/ClickHouse/ClickHouse/pull/22487) ([Kfir Itzhak](https://github.com/mastertheknife)).
* Disable incompatible libraries (platform specific typically) on `ppc64le` [#22475](https://github.com/ClickHouse/ClickHouse/pull/22475) ([Kfir Itzhak](https://github.com/mastertheknife)). * Disable incompatible libraries (platform specific typically) on `ppc64le` [#22475](https://github.com/ClickHouse/ClickHouse/pull/22475) ([Kfir Itzhak](https://github.com/mastertheknife)).

View File

@ -78,6 +78,8 @@ PoolWithFailover::PoolWithFailover(
const RemoteDescription & addresses, const RemoteDescription & addresses,
const std::string & user, const std::string & user,
const std::string & password, const std::string & password,
unsigned default_connections_,
unsigned max_connections_,
size_t max_tries_) size_t max_tries_)
: max_tries(max_tries_) : max_tries(max_tries_)
, shareable(false) , shareable(false)
@ -85,7 +87,13 @@ PoolWithFailover::PoolWithFailover(
/// Replicas have the same priority, but traversed replicas are moved to the end of the queue. /// Replicas have the same priority, but traversed replicas are moved to the end of the queue.
for (const auto & [host, port] : addresses) for (const auto & [host, port] : addresses)
{ {
replicas_by_priority[0].emplace_back(std::make_shared<Pool>(database, host, user, password, port)); replicas_by_priority[0].emplace_back(std::make_shared<Pool>(database,
host, user, password, port,
/* socket_ = */ "",
MYSQLXX_DEFAULT_TIMEOUT,
MYSQLXX_DEFAULT_RW_TIMEOUT,
default_connections_,
max_connections_));
} }
} }

View File

@ -115,6 +115,8 @@ namespace mysqlxx
const RemoteDescription & addresses, const RemoteDescription & addresses,
const std::string & user, const std::string & user,
const std::string & password, const std::string & password,
unsigned default_connections_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
unsigned max_connections_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
size_t max_tries_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES); size_t max_tries_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
PoolWithFailover(const PoolWithFailover & other); PoolWithFailover(const PoolWithFailover & other);

View File

@ -15,7 +15,12 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2], name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
... ...
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']); ) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause'])
SETTINGS
[connection_pool_size=16, ]
[connection_max_tries=3, ]
[connection_auto_close=true ]
;
``` ```
See a detailed description of the [CREATE TABLE](../../../sql-reference/statements/create/table.md#create-table-query) query. See a detailed description of the [CREATE TABLE](../../../sql-reference/statements/create/table.md#create-table-query) query.

View File

@ -5,11 +5,11 @@ toc_title: "Функции для шифрования"
# Функции шифрования {#encryption-functions} # Функции шифрования {#encryption-functions}
Даннвые функции реализуют шифрование и расшифровку данных с помощью AES (Advanced Encryption Standard) алгоритма. Данные функции реализуют шифрование и расшифровку данных с помощью AES (Advanced Encryption Standard) алгоритма.
Длина ключа зависит от режима шифрования. Он может быть длинной в 16, 24 и 32 байта для режимов шифрования `-128-`, `-196-` и `-256-` соответственно. Длина ключа зависит от режима шифрования. Он может быть длинной в 16, 24 и 32 байта для режимов шифрования `-128-`, `-196-` и `-256-` соответственно.
Длина инициализирующего вектора всегда 16 байт (лишнии байты игнорируются). Длина инициализирующего вектора всегда 16 байт (лишние байты игнорируются).
Обратите внимание, что до версии Clickhouse 21.1 эти функции работали медленно. Обратите внимание, что до версии Clickhouse 21.1 эти функции работали медленно.

View File

@ -62,7 +62,6 @@ def build_amp(lang, args, cfg):
for root, _, filenames in os.walk(site_temp): for root, _, filenames in os.walk(site_temp):
if 'index.html' in filenames: if 'index.html' in filenames:
paths.append(prepare_amp_html(lang, args, root, site_temp, main_site_dir)) paths.append(prepare_amp_html(lang, args, root, site_temp, main_site_dir))
test.test_amp(paths, lang)
logging.info(f'Finished building AMP version for {lang}') logging.info(f'Finished building AMP version for {lang}')

View File

@ -40,7 +40,7 @@ def build_for_lang(lang, args):
site_names = { site_names = {
'en': 'ClickHouse Blog', 'en': 'ClickHouse Blog',
'ru': 'Блог ClickHouse ' 'ru': 'Блог ClickHouse'
} }
assert len(site_names) == len(languages) assert len(site_names) == len(languages)
@ -62,7 +62,7 @@ def build_for_lang(lang, args):
strict=True, strict=True,
theme=theme_cfg, theme=theme_cfg,
nav=blog_nav, nav=blog_nav,
copyright='©20162020 Yandex LLC', copyright='©20162021 Yandex LLC',
use_directory_urls=True, use_directory_urls=True,
repo_name='ClickHouse/ClickHouse', repo_name='ClickHouse/ClickHouse',
repo_url='https://github.com/ClickHouse/ClickHouse/', repo_url='https://github.com/ClickHouse/ClickHouse/',

View File

@ -94,7 +94,7 @@ def build_for_lang(lang, args):
site_dir=site_dir, site_dir=site_dir,
strict=True, strict=True,
theme=theme_cfg, theme=theme_cfg,
copyright='©20162020 Yandex LLC', copyright='©20162021 Yandex LLC',
use_directory_urls=True, use_directory_urls=True,
repo_name='ClickHouse/ClickHouse', repo_name='ClickHouse/ClickHouse',
repo_url='https://github.com/ClickHouse/ClickHouse/', repo_url='https://github.com/ClickHouse/ClickHouse/',

View File

@ -31,7 +31,16 @@ def build_nav_entry(root, args):
result_items.append((prio, title, payload)) result_items.append((prio, title, payload))
elif filename.endswith('.md'): elif filename.endswith('.md'):
path = os.path.join(root, filename) path = os.path.join(root, filename)
meta, content = util.read_md_file(path)
meta = ''
content = ''
try:
meta, content = util.read_md_file(path)
except:
print('Error in file: {}'.format(path))
raise
path = path.split('/', 2)[-1] path = path.split('/', 2)[-1]
title = meta.get('toc_title', find_first_header(content)) title = meta.get('toc_title', find_first_header(content))
if title: if title:

View File

@ -3,34 +3,9 @@
import logging import logging
import os import os
import sys import sys
import bs4 import bs4
import logging
import os
import subprocess import subprocess
import bs4
def test_amp(paths, lang):
try:
# Get latest amp validator version
subprocess.check_call('amphtml-validator --help',
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=True)
except subprocess.CalledProcessError:
subprocess.check_call('npm i -g amphtml-validator', stderr=subprocess.DEVNULL, shell=True)
paths = ' '.join(paths)
command = f'amphtml-validator {paths}'
try:
subprocess.check_output(command, shell=True).decode('utf-8')
except subprocess.CalledProcessError:
logging.error(f'Invalid AMP for {lang}')
raise
def test_template(template_path): def test_template(template_path):
if template_path.endswith('amp.html'): if template_path.endswith('amp.html'):

View File

@ -1366,6 +1366,27 @@ private:
{ {
const auto * exception = server_exception ? server_exception.get() : client_exception.get(); const auto * exception = server_exception ? server_exception.get() : client_exception.get();
fmt::print(stderr, "Error on processing query '{}': {}\n", ast_to_process->formatForErrorMessage(), exception->message()); fmt::print(stderr, "Error on processing query '{}': {}\n", ast_to_process->formatForErrorMessage(), exception->message());
// Try to reconnect after errors, for two reasons:
// 1. We might not have realized that the server died, e.g. if
// it sent us a <Fatal> trace and closed connection properly.
// 2. The connection might have gotten into a wrong state and
// the next query will get false positive about
// "Unknown packet from server".
try
{
connection->forceConnected(connection_parameters.timeouts);
}
catch (...)
{
// Just report it, we'll terminate below.
fmt::print(stderr,
"Error while reconnecting to the server: Code: {}: {}\n",
getCurrentExceptionCode(),
getCurrentExceptionMessage(true));
assert(!connection->isConnected());
}
} }
if (!connection->isConnected()) if (!connection->isConnected())
@ -1469,11 +1490,6 @@ private:
server_exception.reset(); server_exception.reset();
client_exception.reset(); client_exception.reset();
have_error = false; have_error = false;
// We have to reinitialize connection after errors, because it
// might have gotten into a wrong state and we'll get false
// positives about "Unknown packet from server".
connection->forceConnected(connection_parameters.timeouts);
} }
else if (ast_to_process->formatForErrorMessage().size() > 500) else if (ast_to_process->formatForErrorMessage().size() > 500)
{ {

View File

@ -52,6 +52,9 @@ template <typename Value, bool float_return> using FuncQuantilesTDigest = Aggreg
template <typename Value, bool float_return> using FuncQuantileTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantileTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, false>; template <typename Value, bool float_return> using FuncQuantileTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantileTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, false>;
template <typename Value, bool float_return> using FuncQuantilesTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantilesTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, true>; template <typename Value, bool float_return> using FuncQuantilesTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantilesTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, true>;
template <typename Value, bool float_return> using FuncQuantileBFloat16 = AggregateFunctionQuantile<Value, QuantileBFloat16Histogram<Value>, NameQuantileBFloat16, false, std::conditional_t<float_return, Float64, void>, false>;
template <typename Value, bool float_return> using FuncQuantilesBFloat16 = AggregateFunctionQuantile<Value, QuantileBFloat16Histogram<Value>, NameQuantilesBFloat16, false, std::conditional_t<float_return, Float64, void>, true>;
template <template <typename, bool> class Function> template <template <typename, bool> class Function>
static constexpr bool supportDecimal() static constexpr bool supportDecimal()
@ -156,6 +159,9 @@ void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory)
factory.registerFunction(NameQuantileTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantileTDigestWeighted>); factory.registerFunction(NameQuantileTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantileTDigestWeighted>);
factory.registerFunction(NameQuantilesTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantilesTDigestWeighted>); factory.registerFunction(NameQuantilesTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantilesTDigestWeighted>);
factory.registerFunction(NameQuantileBFloat16::name, createAggregateFunctionQuantile<FuncQuantileBFloat16>);
factory.registerFunction(NameQuantilesBFloat16::name, createAggregateFunctionQuantile<FuncQuantilesBFloat16>);
/// 'median' is an alias for 'quantile' /// 'median' is an alias for 'quantile'
factory.registerAlias("median", NameQuantile::name); factory.registerAlias("median", NameQuantile::name);
factory.registerAlias("medianDeterministic", NameQuantileDeterministic::name); factory.registerAlias("medianDeterministic", NameQuantileDeterministic::name);
@ -167,6 +173,7 @@ void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory)
factory.registerAlias("medianTimingWeighted", NameQuantileTimingWeighted::name); factory.registerAlias("medianTimingWeighted", NameQuantileTimingWeighted::name);
factory.registerAlias("medianTDigest", NameQuantileTDigest::name); factory.registerAlias("medianTDigest", NameQuantileTDigest::name);
factory.registerAlias("medianTDigestWeighted", NameQuantileTDigestWeighted::name); factory.registerAlias("medianTDigestWeighted", NameQuantileTDigestWeighted::name);
factory.registerAlias("medianBFloat16", NameQuantileBFloat16::name);
} }
} }

View File

@ -9,6 +9,7 @@
#include <AggregateFunctions/QuantileExactWeighted.h> #include <AggregateFunctions/QuantileExactWeighted.h>
#include <AggregateFunctions/QuantileTiming.h> #include <AggregateFunctions/QuantileTiming.h>
#include <AggregateFunctions/QuantileTDigest.h> #include <AggregateFunctions/QuantileTDigest.h>
#include <AggregateFunctions/QuantileBFloat16Histogram.h>
#include <AggregateFunctions/IAggregateFunction.h> #include <AggregateFunctions/IAggregateFunction.h>
#include <AggregateFunctions/QuantilesCommon.h> #include <AggregateFunctions/QuantilesCommon.h>
@ -228,4 +229,7 @@ struct NameQuantileTDigestWeighted { static constexpr auto name = "quantileTDige
struct NameQuantilesTDigest { static constexpr auto name = "quantilesTDigest"; }; struct NameQuantilesTDigest { static constexpr auto name = "quantilesTDigest"; };
struct NameQuantilesTDigestWeighted { static constexpr auto name = "quantilesTDigestWeighted"; }; struct NameQuantilesTDigestWeighted { static constexpr auto name = "quantilesTDigestWeighted"; };
struct NameQuantileBFloat16 { static constexpr auto name = "quantileBFloat16"; };
struct NameQuantilesBFloat16 { static constexpr auto name = "quantilesBFloat16"; };
} }

View File

@ -0,0 +1,63 @@
#include <AggregateFunctions/AggregateFunctionFactory.h>
#include <AggregateFunctions/AggregateFunctionSegmentLengthSum.h>
#include <AggregateFunctions/FactoryHelpers.h>
#include <AggregateFunctions/Helpers.h>
#include <DataTypes/DataTypeDate.h>
#include <DataTypes/DataTypeDateTime.h>
#include <ext/range.h>
namespace DB
{
namespace ErrorCodes
{
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
}
namespace
{
template <template <typename> class Data>
AggregateFunctionPtr createAggregateFunctionSegmentLengthSum(const std::string & name, const DataTypes & arguments, const Array &)
{
if (arguments.size() != 2)
throw Exception(
"Aggregate function " + name + " requires two timestamps argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
auto args = {arguments[0].get(), arguments[1].get()};
if (WhichDataType{args.begin()[0]}.idx != WhichDataType{args.begin()[1]}.idx)
throw Exception(
"Illegal type " + args.begin()[0]->getName() + " and " + args.begin()[1]->getName() + " of arguments of aggregate function "
+ name + ", there two arguments should have same DataType",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
for (const auto & arg : args)
{
if (!isNativeNumber(arg) && !isDateOrDateTime(arg))
throw Exception(
"Illegal type " + arg->getName() + " of argument of aggregate function " + name
+ ", must be Number, Date, DateTime or DateTime64",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
AggregateFunctionPtr res(createWithBasicNumberOrDateOrDateTime<AggregateFunctionSegmentLengthSum, Data>(*arguments[0], arguments));
if (res)
return res;
throw Exception(
"Illegal type " + arguments.front().get()->getName() + " of first argument of aggregate function " + name
+ ", must be Native Unsigned Number",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
}
}
void registerAggregateFunctionSegmentLengthSum(AggregateFunctionFactory & factory)
{
factory.registerFunction("segmentLengthSum", createAggregateFunctionSegmentLengthSum<AggregateFunctionSegmentLengthSumData>);
}
}

View File

@ -0,0 +1,199 @@
#pragma once
#include <unordered_set>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypesNumber.h>
#include <IO/ReadHelpers.h>
#include <IO/WriteHelpers.h>
#include <Common/ArenaAllocator.h>
#include <Common/assert_cast.h>
#include <AggregateFunctions/AggregateFunctionNull.h>
namespace DB
{
template <typename T>
struct AggregateFunctionSegmentLengthSumData
{
using Segment = std::pair<T, T>;
using Segments = PODArrayWithStackMemory<Segment, 64>;
bool sorted = false;
Segments segments;
size_t size() const { return segments.size(); }
void add(T start, T end)
{
if (sorted && segments.size() > 0)
{
sorted = segments.back().first <= start;
}
segments.emplace_back(start, end);
}
void merge(const AggregateFunctionSegmentLengthSumData & other)
{
if (other.segments.empty())
return;
const auto size = segments.size();
segments.insert(std::begin(other.segments), std::end(other.segments));
/// either sort whole container or do so partially merging ranges afterwards
if (!sorted && !other.sorted)
std::stable_sort(std::begin(segments), std::end(segments));
else
{
const auto begin = std::begin(segments);
const auto middle = std::next(begin, size);
const auto end = std::end(segments);
if (!sorted)
std::stable_sort(begin, middle);
if (!other.sorted)
std::stable_sort(middle, end);
std::inplace_merge(begin, middle, end);
}
sorted = true;
}
void sort()
{
if (!sorted)
{
std::stable_sort(std::begin(segments), std::end(segments));
sorted = true;
}
}
void serialize(WriteBuffer & buf) const
{
writeBinary(sorted, buf);
writeBinary(segments.size(), buf);
for (const auto & time_gap : segments)
{
writeBinary(time_gap.first, buf);
writeBinary(time_gap.second, buf);
}
}
void deserialize(ReadBuffer & buf)
{
readBinary(sorted, buf);
size_t size;
readBinary(size, buf);
segments.clear();
segments.reserve(size);
T start, end;
for (size_t i = 0; i < size; ++i)
{
readBinary(start, buf);
readBinary(end, buf);
segments.emplace_back(start, end);
}
}
};
template <typename T, typename Data>
class AggregateFunctionSegmentLengthSum final : public IAggregateFunctionDataHelper<Data, AggregateFunctionSegmentLengthSum<T, Data>>
{
private:
template <typename TResult>
TResult getSegmentLengthSum(Data & data) const
{
if (data.size() == 0)
return 0;
data.sort();
TResult res = 0;
typename Data::Segment cur_segment = data.segments[0];
for (size_t i = 1; i < data.segments.size(); ++i)
{
if (cur_segment.second < data.segments[i].first)
{
res += cur_segment.second - cur_segment.first;
cur_segment = data.segments[i];
}
else
cur_segment.second = std::max(cur_segment.second, data.segments[i].second);
}
res += cur_segment.second - cur_segment.first;
return res;
}
public:
String getName() const override { return "segmentLengthSum"; }
explicit AggregateFunctionSegmentLengthSum(const DataTypes & arguments)
: IAggregateFunctionDataHelper<Data, AggregateFunctionSegmentLengthSum<T, Data>>(arguments, {})
{
}
DataTypePtr getReturnType() const override
{
if constexpr (std::is_floating_point_v<T>)
return std::make_shared<DataTypeFloat64>();
return std::make_shared<DataTypeUInt64>();
}
bool allocatesMemoryInArena() const override { return false; }
AggregateFunctionPtr getOwnNullAdapter(
const AggregateFunctionPtr & nested_function,
const DataTypes & arguments,
const Array & params,
const AggregateFunctionProperties & /*properties*/) const override
{
return std::make_shared<AggregateFunctionNullVariadic<false, false, false>>(nested_function, arguments, params);
}
void add(AggregateDataPtr __restrict place, const IColumn ** columns, const size_t row_num, Arena *) const override
{
auto start = assert_cast<const ColumnVector<T> *>(columns[0])->getData()[row_num];
auto end = assert_cast<const ColumnVector<T> *>(columns[1])->getData()[row_num];
this->data(place).add(start, end);
}
void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena *) const override
{
this->data(place).merge(this->data(rhs));
}
void serialize(ConstAggregateDataPtr __restrict place, WriteBuffer & buf) const override
{
this->data(place).serialize(buf);
}
void deserialize(AggregateDataPtr __restrict place, ReadBuffer & buf, Arena *) const override
{
this->data(place).deserialize(buf);
}
void insertResultInto(AggregateDataPtr __restrict place, IColumn & to, Arena *) const override
{
if constexpr (std::is_floating_point_v<T>)
assert_cast<ColumnFloat64 &>(to).getData().push_back(getSegmentLengthSum<Float64>(this->data(place)));
else
assert_cast<ColumnUInt64 &>(to).getData().push_back(getSegmentLengthSum<UInt64>(this->data(place)));
}
};
}

View File

@ -114,6 +114,24 @@ static IAggregateFunction * createWithUnsignedIntegerType(const IDataType & argu
return nullptr; return nullptr;
} }
template <template <typename, typename> class AggregateFunctionTemplate, template <typename> class Data, typename... TArgs>
static IAggregateFunction * createWithBasicNumberOrDateOrDateTime(const IDataType & argument_type, TArgs &&... args)
{
WhichDataType which(argument_type);
#define DISPATCH(TYPE) \
if (which.idx == TypeIndex::TYPE) \
return new AggregateFunctionTemplate<TYPE, Data<TYPE>>(std::forward<TArgs>(args)...);
FOR_BASIC_NUMERIC_TYPES(DISPATCH)
#undef DISPATCH
if (which.idx == TypeIndex::Date)
return new AggregateFunctionTemplate<UInt16, Data<UInt16>>(std::forward<TArgs>(args)...);
if (which.idx == TypeIndex::DateTime)
return new AggregateFunctionTemplate<UInt32, Data<UInt32>>(std::forward<TArgs>(args)...);
return nullptr;
}
template <template <typename> class AggregateFunctionTemplate, typename... TArgs> template <template <typename> class AggregateFunctionTemplate, typename... TArgs>
static IAggregateFunction * createWithNumericBasedType(const IDataType & argument_type, TArgs && ... args) static IAggregateFunction * createWithNumericBasedType(const IDataType & argument_type, TArgs && ... args)
{ {

View File

@ -0,0 +1,207 @@
#pragma once
#include <IO/ReadBuffer.h>
#include <IO/WriteBuffer.h>
#include <Common/HashTable/HashMap.h>
#include <common/types.h>
#include <ext/bit_cast.h>
namespace DB
{
/** `bfloat16` is a 16-bit floating point data type that is the same as the corresponding most significant 16 bits of the `float`.
* https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
*
* To calculate quantile, simply convert input value to 16 bit (convert to float, then take the most significant 16 bits),
* and calculate the histogram of these values.
*
* Hash table is the preferred way to store histogram, because the number of distinct values is small:
* ```
* SELECT uniq(bfloat)
* FROM
* (
* SELECT
* number,
* toFloat32(number) AS f,
* bitShiftRight(bitAnd(reinterpretAsUInt32(reinterpretAsFixedString(f)), 4294901760) AS cut, 16),
* reinterpretAsFloat32(reinterpretAsFixedString(cut)) AS bfloat
* FROM numbers(100000000)
* )
*
* uniq(bfloat)
* 2623
*
* ```
* (when increasing the range of values 1000 times, the number of distinct bfloat16 values increases just by 1280).
*
* Then calculate quantile from the histogram.
*
* This sketch is very simple and rough. Its relative precision is constant 1 / 256 = 0.390625%.
*/
template <typename Value>
struct QuantileBFloat16Histogram
{
using BFloat16 = UInt16;
using Weight = UInt64;
/// Make automatic memory for 16 elements to avoid allocations for small states.
/// The usage of trivial hash is ok, because we effectively take logarithm of the values and pathological cases are unlikely.
using Data = HashMapWithStackMemory<BFloat16, Weight, TrivialHash, 4>;
Data data;
void add(const Value & x)
{
add(x, 1);
}
void add(const Value & x, Weight w)
{
if (!isNaN(x))
data[toBFloat16(x)] += w;
}
void merge(const QuantileBFloat16Histogram & rhs)
{
for (const auto & pair : rhs.data)
data[pair.getKey()] += pair.getMapped();
}
void serialize(WriteBuffer & buf) const
{
data.write(buf);
}
void deserialize(ReadBuffer & buf)
{
data.read(buf);
}
Value get(Float64 level) const
{
return getImpl<Value>(level);
}
void getMany(const Float64 * levels, const size_t * indices, size_t size, Value * result) const
{
getManyImpl(levels, indices, size, result);
}
Float64 getFloat(Float64 level) const
{
return getImpl<Float64>(level);
}
void getManyFloat(const Float64 * levels, const size_t * indices, size_t size, Float64 * result) const
{
getManyImpl(levels, indices, size, result);
}
private:
/// Take the most significant 16 bits of the floating point number.
BFloat16 toBFloat16(const Value & x) const
{
return ext::bit_cast<UInt32>(static_cast<Float32>(x)) >> 16;
}
/// Put the bits into most significant 16 bits of the floating point number and fill other bits with zeros.
Float32 toFloat32(const BFloat16 & x) const
{
return ext::bit_cast<Float32>(x << 16);
}
using Pair = PairNoInit<Float32, Weight>;
template <typename T>
T getImpl(Float64 level) const
{
size_t size = data.size();
if (0 == size)
return std::numeric_limits<T>::quiet_NaN();
std::unique_ptr<Pair[]> array_holder(new Pair[size]);
Pair * array = array_holder.get();
Float64 sum_weight = 0;
Pair * arr_it = array;
for (const auto & pair : data)
{
sum_weight += pair.getMapped();
*arr_it = {toFloat32(pair.getKey()), pair.getMapped()};
++arr_it;
}
std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.first < b.first; });
Float64 threshold = std::ceil(sum_weight * level);
Float64 accumulated = 0;
for (const Pair * p = array; p != (array + size); ++p)
{
accumulated += p->second;
if (accumulated >= threshold)
return p->first;
}
return array[size - 1].first;
}
template <typename T>
void getManyImpl(const Float64 * levels, const size_t * indices, size_t num_levels, T * result) const
{
size_t size = data.size();
if (0 == size)
{
for (size_t i = 0; i < num_levels; ++i)
result[i] = std::numeric_limits<T>::quiet_NaN();
return;
}
std::unique_ptr<Pair[]> array_holder(new Pair[size]);
Pair * array = array_holder.get();
Float64 sum_weight = 0;
Pair * arr_it = array;
for (const auto & pair : data)
{
sum_weight += pair.getMapped();
*arr_it = {toFloat32(pair.getKey()), pair.getMapped()};
++arr_it;
}
std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.first < b.first; });
size_t level_index = 0;
Float64 accumulated = 0;
Float64 threshold = std::ceil(sum_weight * levels[indices[level_index]]);
for (const Pair * p = array; p != (array + size); ++p)
{
accumulated += p->second;
while (accumulated >= threshold)
{
result[indices[level_index]] = p->first;
++level_index;
if (level_index == num_levels)
return;
threshold = std::ceil(sum_weight * levels[indices[level_index]]);
}
}
while (level_index < num_levels)
{
result[indices[level_index]] = array[size - 1].first;
++level_index;
}
}
};
}

View File

@ -62,6 +62,7 @@ void registerAggregateFunctionCombinatorDistinct(AggregateFunctionCombinatorFact
void registerWindowFunctions(AggregateFunctionFactory & factory); void registerWindowFunctions(AggregateFunctionFactory & factory);
void registerAggregateFunctionSegmentLengthSum(AggregateFunctionFactory &);
void registerAggregateFunctions() void registerAggregateFunctions()
{ {
@ -111,6 +112,8 @@ void registerAggregateFunctions()
registerAggregateFunctionStudentTTest(factory); registerAggregateFunctionStudentTTest(factory);
registerWindowFunctions(factory); registerWindowFunctions(factory);
registerAggregateFunctionSegmentLengthSum(factory);
} }
{ {

View File

@ -43,6 +43,7 @@ SRCS(
AggregateFunctionRankCorrelation.cpp AggregateFunctionRankCorrelation.cpp
AggregateFunctionResample.cpp AggregateFunctionResample.cpp
AggregateFunctionRetention.cpp AggregateFunctionRetention.cpp
AggregateFunctionSegmentLengthSum.cpp
AggregateFunctionSequenceMatch.cpp AggregateFunctionSequenceMatch.cpp
AggregateFunctionSimpleLinearRegression.cpp AggregateFunctionSimpleLinearRegression.cpp
AggregateFunctionSimpleState.cpp AggregateFunctionSimpleState.cpp

View File

@ -187,6 +187,7 @@ add_object_library(clickhouse_interpreters_clusterproxy Interpreters/ClusterProx
add_object_library(clickhouse_interpreters_jit Interpreters/JIT) add_object_library(clickhouse_interpreters_jit Interpreters/JIT)
add_object_library(clickhouse_columns Columns) add_object_library(clickhouse_columns Columns)
add_object_library(clickhouse_storages Storages) add_object_library(clickhouse_storages Storages)
add_object_library(clickhouse_storages_mysql Storages/MySQL)
add_object_library(clickhouse_storages_distributed Storages/Distributed) add_object_library(clickhouse_storages_distributed Storages/Distributed)
add_object_library(clickhouse_storages_mergetree Storages/MergeTree) add_object_library(clickhouse_storages_mergetree Storages/MergeTree)
add_object_library(clickhouse_storages_liveview Storages/LiveView) add_object_library(clickhouse_storages_liveview Storages/LiveView)

View File

@ -1,309 +0,0 @@
#pragma once
#include <cstddef>
#include <cstdlib>
#include <Common/Exception.h>
#include <Common/formatReadable.h>
namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_ALLOCATE_MEMORY;
}
/** An array of (almost) unchangeable size:
* the size is specified in the constructor;
* `resize` method removes old data, and necessary only for
* so that you can first create an empty object using the default constructor,
* and then decide on the size.
*
* There is a possibility to not initialize elements by default, but create them inplace.
* Member destructors are called automatically.
*
* `sizeof` is equal to the size of one pointer.
*
* Not exception-safe.
*
* Copying is supported via assign() method. Moving empties the original object.
* That is, it is inconvenient to use this array in many cases.
*
* Designed for situations in which many arrays of the same small size are created,
* but the size is not known at compile time.
* Also gives a significant advantage in cases where it is important that `sizeof` is minimal.
* For example, if arrays are put in an open-addressing hash table with inplace storage of values (like HashMap)
*
* In this case, compared to std::vector:
* - for arrays of 1 element size - an advantage of about 2 times;
* - for arrays of 5 elements - an advantage of about 1.5 times
* (DB::Field, containing UInt64 and String, used as T);
*/
const size_t empty_auto_array_helper = 0;
template <typename T>
class AutoArray
{
public:
/// For deferred creation.
AutoArray()
{
setEmpty();
}
explicit AutoArray(size_t size_)
{
init(size_, false);
}
/** Initializes all elements with a copy constructor with the `value` parameter.
*/
AutoArray(size_t size_, const T & value)
{
init(size_, true);
for (size_t i = 0; i < size_; ++i)
{
new (place(i)) T(value);
}
}
/** `resize` removes all existing items.
*/
void resize(size_t size_, bool dont_init_elems = false)
{
uninit();
init(size_, dont_init_elems);
}
/** Move operations.
*/
AutoArray(AutoArray && src)
{
if (this == &src)
return;
setEmpty();
data_ptr = src.data_ptr;
src.setEmpty();
}
AutoArray & operator= (AutoArray && src)
{
if (this == &src)
return *this;
uninit();
data_ptr = src.data_ptr;
src.setEmpty();
return *this;
}
~AutoArray()
{
uninit();
}
size_t size() const
{
return m_size();
}
bool empty() const
{
return size() == 0;
}
void clear()
{
uninit();
setEmpty();
}
template <typename It>
void assign(It from_begin, It from_end)
{
uninit();
size_t size = from_end - from_begin;
init(size, /* dont_init_elems = */ true);
It it = from_begin;
for (size_t i = 0; i < size; ++i, ++it)
new (place(i)) T(*it);
}
void assign(const AutoArray & from)
{
assign(from.begin(), from.end());
}
/** You can read and modify elements using the [] operator
* only if items were initialized
* (that is, into the constructor was not passed DontInitElemsTag,
* or you initialized them using `place` and `placement new`).
*/
T & operator[](size_t i)
{
return elem(i);
}
const T & operator[](size_t i) const
{
return elem(i);
}
T * data()
{
return elemPtr(0);
}
const T * data() const
{
return elemPtr(0);
}
/** Get the piece of memory in which the element should be located.
* The function is intended to initialize an element,
* which has not yet been initialized
* new (arr.place(i)) T(args);
*/
char * place(size_t i)
{
return data_ptr + sizeof(T) * i;
}
using iterator = T *;
using const_iterator = const T *;
iterator begin() { return elemPtr(0); }
iterator end() { return elemPtr(size()); }
const_iterator begin() const { return elemPtr(0); }
const_iterator end() const { return elemPtr(size()); }
bool operator== (const AutoArray<T> & rhs) const
{
size_t s = size();
if (s != rhs.size())
return false;
for (size_t i = 0; i < s; ++i)
if (elem(i) != rhs.elem(i))
return false;
return true;
}
bool operator!= (const AutoArray<T> & rhs) const
{
return !(*this == rhs);
}
bool operator< (const AutoArray<T> & rhs) const
{
size_t s = size();
size_t rhs_s = rhs.size();
if (s < rhs_s)
return true;
if (s > rhs_s)
return false;
for (size_t i = 0; i < s; ++i)
{
if (elem(i) < rhs.elem(i))
return true;
if (elem(i) > rhs.elem(i))
return false;
}
return false;
}
private:
static constexpr size_t alignment = alignof(T);
/// Bytes allocated to store size of array before data. It is padded to have minimum size as alignment.
/// Padding is at left and the size is stored at right (just before the first data element).
static constexpr size_t prefix_size = std::max(sizeof(size_t), alignment);
char * data_ptr;
size_t & m_size()
{
return reinterpret_cast<size_t *>(data_ptr)[-1];
}
size_t m_size() const
{
return reinterpret_cast<const size_t *>(data_ptr)[-1];
}
T * elemPtr(size_t i)
{
return reinterpret_cast<T *>(data_ptr) + i;
}
const T * elemPtr(size_t i) const
{
return reinterpret_cast<const T *>(data_ptr) + i;
}
T & elem(size_t i)
{
return *elemPtr(i);
}
const T & elem(size_t i) const
{
return *elemPtr(i);
}
void setEmpty()
{
data_ptr = const_cast<char *>(reinterpret_cast<const char *>(&empty_auto_array_helper)) + sizeof(size_t);
}
void init(size_t new_size, bool dont_init_elems)
{
if (!new_size)
{
setEmpty();
return;
}
void * new_data = nullptr;
int res = posix_memalign(&new_data, alignment, prefix_size + new_size * sizeof(T));
if (0 != res)
throwFromErrno(fmt::format("Cannot allocate memory (posix_memalign) {}.", ReadableSize(new_size)),
ErrorCodes::CANNOT_ALLOCATE_MEMORY, res);
data_ptr = static_cast<char *>(new_data);
data_ptr += prefix_size;
m_size() = new_size;
if (!dont_init_elems)
for (size_t i = 0; i < new_size; ++i)
new (place(i)) T();
}
void uninit()
{
size_t s = size();
if (s)
{
for (size_t i = 0; i < s; ++i)
elem(i).~T();
data_ptr -= prefix_size;
free(data_ptr);
}
}
};
}

View File

@ -123,7 +123,7 @@ inline bool isWhitespaceASCII(char c)
/// Since |isWhiteSpaceASCII()| is used inside algorithms it's easier to implement another function than add extra argument. /// Since |isWhiteSpaceASCII()| is used inside algorithms it's easier to implement another function than add extra argument.
inline bool isWhitespaceASCIIOneLine(char c) inline bool isWhitespaceASCIIOneLine(char c)
{ {
return c == ' ' || c == '\t' || c == '\r' || c == '\f' || c == '\v'; return c == ' ' || c == '\t' || c == '\f' || c == '\v';
} }
inline bool isControlASCII(char c) inline bool isControlASCII(char c)

View File

@ -7,9 +7,6 @@ endif()
add_executable (sip_hash_perf sip_hash_perf.cpp) add_executable (sip_hash_perf sip_hash_perf.cpp)
target_link_libraries (sip_hash_perf PRIVATE clickhouse_common_io) target_link_libraries (sip_hash_perf PRIVATE clickhouse_common_io)
add_executable (auto_array auto_array.cpp)
target_link_libraries (auto_array PRIVATE clickhouse_common_io)
add_executable (small_table small_table.cpp) add_executable (small_table small_table.cpp)
target_link_libraries (small_table PRIVATE clickhouse_common_io) target_link_libraries (small_table PRIVATE clickhouse_common_io)

View File

@ -1,197 +0,0 @@
#include <iostream>
#include <iomanip>
#include <map>
#include <pcg_random.hpp>
#include <Core/Field.h>
#include <Common/HashTable/HashMap.h>
#include <Common/AutoArray.h>
#include <IO/WriteHelpers.h>
#include <Common/Stopwatch.h>
int main(int argc, char ** argv)
{
pcg64 rng;
{
size_t n = 10;
using T = std::string;
DB::AutoArray<T> arr(n);
for (size_t i = 0; i < arr.size(); ++i)
arr[i] = "Hello, world! " + DB::toString(i);
for (auto & elem : arr)
std::cerr << elem << std::endl;
}
std::cerr << std::endl;
{
size_t n = 10;
using T = std::string;
using Arr = DB::AutoArray<T>;
Arr arr;
arr.resize(n);
for (size_t i = 0; i < arr.size(); ++i)
arr[i] = "Hello, world! " + DB::toString(i);
for (auto & elem : arr)
std::cerr << elem << std::endl;
std::cerr << std::endl;
Arr arr2 = std::move(arr);
std::cerr << arr.size() << ", " << arr2.size() << std::endl; // NOLINT
for (auto & elem : arr2)
std::cerr << elem << std::endl;
}
std::cerr << std::endl;
{
size_t n = 10;
size_t keys = 10;
using T = std::string;
using Arr = DB::AutoArray<T>;
using Map = std::map<Arr, T>;
Map map;
for (size_t i = 0; i < keys; ++i)
{
Arr key(n);
for (size_t j = 0; j < n; ++j)
key[j] = DB::toString(rng());
map[std::move(key)] = "Hello, world! " + DB::toString(i);
}
for (const auto & kv : map)
{
std::cerr << "[";
for (size_t j = 0; j < n; ++j)
std::cerr << (j == 0 ? "" : ", ") << kv.first[j];
std::cerr << "]";
std::cerr << ":\t" << kv.second << std::endl;
}
std::cerr << std::endl;
Map map2 = std::move(map);
for (const auto & kv : map2)
{
std::cerr << "[";
for (size_t j = 0; j < n; ++j)
std::cerr << (j == 0 ? "" : ", ") << kv.first[j];
std::cerr << "]";
std::cerr << ":\t" << kv.second << std::endl;
}
}
std::cerr << std::endl;
{
size_t n = 10;
size_t keys = 10;
using T = std::string;
using Arr = DB::AutoArray<T>;
using Vec = std::vector<Arr>;
Vec vec;
for (size_t i = 0; i < keys; ++i)
{
Arr key(n);
for (size_t j = 0; j < n; ++j)
key[j] = DB::toString(rng());
vec.push_back(std::move(key));
}
for (const auto & elem : vec)
{
std::cerr << "[";
for (size_t j = 0; j < n; ++j)
std::cerr << (j == 0 ? "" : ", ") << elem[j];
std::cerr << "]" << std::endl;
}
std::cerr << std::endl;
Vec vec2 = std::move(vec);
for (const auto & elem : vec2)
{
std::cerr << "[";
for (size_t j = 0; j < n; ++j)
std::cerr << (j == 0 ? "" : ", ") << elem[j];
std::cerr << "]" << std::endl;
}
}
if (argc == 2 && !strcmp(argv[1], "1"))
{
size_t n = 5;
size_t map_size = 1000000;
using T = DB::Field;
T field = std::string("Hello, world");
using Arr = std::vector<T>;
using Map = HashMap<UInt64, Arr>;
Stopwatch watch;
Map map;
for (size_t i = 0; i < map_size; ++i)
{
Map::LookupResult it;
bool inserted;
map.emplace(rng(), it, inserted);
if (inserted)
{
new (&it->getMapped()) Arr(n);
for (size_t j = 0; j < n; ++j)
(it->getMapped())[j] = field;
}
}
std::cerr << std::fixed << std::setprecision(2)
<< "Vector: Elapsed: " << watch.elapsedSeconds()
<< " (" << map_size / watch.elapsedSeconds() << " rows/sec., "
<< "sizeof(Map::value_type) = " << sizeof(Map::value_type)
<< std::endl;
}
{
size_t n = 10000;
using Arr = DB::AutoArray<std::string>;
Arr arr1(n);
Arr arr2(n);
for (size_t i = 0; i < n; ++i)
{
arr1[i] = "Hello, world! " + DB::toString(i);
arr2[i] = "Goodbye, world! " + DB::toString(i);
}
arr2 = std::move(arr1);
arr1.resize(n); // NOLINT
std::cerr
<< "arr1.size(): " << arr1.size() << ", arr2.size(): " << arr2.size() << std::endl
<< "arr1.data(): " << arr1.data() << ", arr2.data(): " << arr2.data() << std::endl
<< "arr1[0]: " << arr1[0] << ", arr2[0]: " << arr2[0] << std::endl;
}
return 0;
}

View File

@ -61,6 +61,10 @@ static void NO_INLINE testForType(size_t method, size_t rows_size)
test<Key, ::absl::flat_hash_map<Key, UInt64>>(data.data(), data.size(), "Abseil HashMap"); test<Key, ::absl::flat_hash_map<Key, UInt64>>(data.data(), data.size(), "Abseil HashMap");
} }
else if (method == 3) else if (method == 3)
{
test<Key, ::absl::flat_hash_map<Key, UInt64, DefaultHash<Key>>>(data.data(), data.size(), "Abseil HashMap with CH Hash");
}
else if (method == 4)
{ {
test<Key, std::unordered_map<Key, UInt64>>(data.data(), data.size(), "std::unordered_map"); test<Key, std::unordered_map<Key, UInt64>>(data.data(), data.size(), "std::unordered_map");
} }
@ -81,50 +85,110 @@ static void NO_INLINE testForType(size_t method, size_t rows_size)
* ./integer_hash_tables_benchmark 1 $2 100000000 < $1 * ./integer_hash_tables_benchmark 1 $2 100000000 < $1
* ./integer_hash_tables_benchmark 2 $2 100000000 < $1 * ./integer_hash_tables_benchmark 2 $2 100000000 < $1
* ./integer_hash_tables_benchmark 3 $2 100000000 < $1 * ./integer_hash_tables_benchmark 3 $2 100000000 < $1
* ./integer_hash_tables_benchmark 4 $2 100000000 < $1
* *
* Results of this benchmark on hits_100m_obfuscated * Results of this benchmark on hits_100m_obfuscated X86-64
* *
* File hits_100m_obfuscated/201307_1_96_4/WatchID.bin * File hits_100m_obfuscated/201307_1_96_4/WatchID.bin
* CH HashMap: Elapsed: 7.366 (13575745.933 elem/sec.), map size: 99997493 * CH HashMap: Elapsed: 7.416 (13484217.815 elem/sec.), map size: 99997493
* Google DenseMap: Elapsed: 10.089 (9911817.125 elem/sec.), map size: 99997493 * Google DenseMap: Elapsed: 10.303 (9706022.031 elem/sec.), map size: 99997493
* Abseil HashMap: Elapsed: 9.011 (11097794.073 elem/sec.), map size: 99997493 * Abseil HashMap: Elapsed: 9.106 (10982139.229 elem/sec.), map size: 99997493
* std::unordered_map: Elapsed: 44.758 (2234223.189 elem/sec.), map size: 99997493 * Abseil HashMap with CH Hash: Elapsed: 9.221 (10845360.669 elem/sec.), map size: 99997493
* std::unordered_map: Elapsed: 45.213 (2211758.706 elem/sec.), map size: 9999749
* *
* File hits_100m_obfuscated/201307_1_96_4/URLHash.bin * File hits_100m_obfuscated/201307_1_96_4/URLHash.bin
* CH HashMap: Elapsed: 2.672 (37421588.347 elem/sec.), map size: 20714865 * CH HashMap: Elapsed: 2.620 (38168135.308 elem/sec.), map size: 20714865
* Google DenseMap: Elapsed: 3.409 (29333308.209 elem/sec.), map size: 20714865 * Google DenseMap: Elapsed: 3.426 (29189309.058 elem/sec.), map size: 20714865
* Abseil HashMap: Elapsed: 2.778 (36000540.035 elem/sec.), map size: 20714865 * Abseil HashMap: Elapsed: 2.788 (35870495.097 elem/sec.), map size: 20714865
* std::unordered_map: Elapsed: 8.643 (11570012.207 elem/sec.), map size: 20714865 * Abseil HashMap with CH Hash: Elapsed: 2.991 (33428850.155 elem/sec.), map size: 20714865
* std::unordered_map: Elapsed: 8.503 (11760331.346 elem/sec.), map size: 20714865
* *
* File hits_100m_obfuscated/201307_1_96_4/UserID.bin * File hits_100m_obfuscated/201307_1_96_4/UserID.bin
* CH HashMap: Elapsed: 2.116 (47267659.076 elem/sec.), map size: 17630976 * CH HashMap: Elapsed: 2.157 (46352039.753 elem/sec.), map size: 17630976
* Google DenseMap: Elapsed: 2.722 (36740693.786 elem/sec.), map size: 17630976 * Google DenseMap: Elapsed: 2.725 (36694226.782 elem/sec.), map size: 17630976
* Abseil HashMap: Elapsed: 2.597 (38509988.663 elem/sec.), map size: 17630976 * Abseil HashMap: Elapsed: 2.590 (38604284.187 elem/sec.), map size: 17630976
* std::unordered_map: Elapsed: 7.327 (13647271.471 elem/sec.), map size: 17630976 * Abseil HashMap with CH Hash: Elapsed: 2.785 (35904856.137 elem/sec.), map size: 17630976
* std::unordered_map: Elapsed: 7.268 (13759557.609 elem/sec.), map size: 17630976
* *
* File hits_100m_obfuscated/201307_1_96_4/RegionID.bin * File hits_100m_obfuscated/201307_1_96_4/RegionID.bin
* CH HashMap: Elapsed: 0.201 (498144193.695 elem/sec.), map size: 9040 * CH HashMap: Elapsed: 0.192 (521583315.810 elem/sec.), map size: 9040
* Google DenseMap: Elapsed: 0.261 (382656387.016 elem/sec.), map size: 9046 * Google DenseMap: Elapsed: 0.297 (337081407.799 elem/sec.), map size: 9046
* Abseil HashMap: Elapsed: 0.307 (325874545.117 elem/sec.), map size: 9040 * Abseil HashMap: Elapsed: 0.295 (338805623.511 elem/sec.), map size: 9040
* std::unordered_map: Elapsed: 0.466 (214379083.420 elem/sec.), map size: 9040 * Abseil HashMap with CH Hash: Elapsed: 0.331 (302155391.036 elem/sec.), map size: 9040
* std::unordered_map: Elapsed: 0.455 (219971555.390 elem/sec.), map size: 9040
* *
* File hits_100m_obfuscated/201307_1_96_4/CounterID.bin * File hits_100m_obfuscated/201307_1_96_4/CounterID.bin
* CH HashMap: Elapsed: 0.220 (455344735.648 elem/sec.), map size: 6506 * CH HashMap: Elapsed: 0.217 (460216823.609 elem/sec.), map size: 6506
* Google DenseMap: Elapsed: 0.297 (336187522.818 elem/sec.), map size: 6506 * Google DenseMap: Elapsed: 0.373 (267838665.098 elem/sec.), map size: 6506
* Abseil HashMap: Elapsed: 0.307 (325264214.480 elem/sec.), map size: 6506 * Abseil HashMap: Elapsed: 0.325 (308124728.989 elem/sec.), map size: 6506
* std::unordered_map: Elapsed: 0.389 (257195996.114 elem/sec.), map size: 6506 * Abseil HashMap with CH Hash: Elapsed: 0.354 (282167144.801 elem/sec.), map size: 6506
* std::unordered_map: Elapsed: 0.390 (256573354.171 elem/sec.), map size: 6506
* *
* File hits_100m_obfuscated/201307_1_96_4/TraficSourceID.bin * File hits_100m_obfuscated/201307_1_96_4/TraficSourceID.bin
* CH HashMap: Elapsed: 0.274 (365196673.729 elem/sec.), map size: 10 * CH HashMap: Elapsed: 0.246 (406714566.282 elem/sec.), map size: 10
* Google DenseMap: Elapsed: 0.782 (127845746.927 elem/sec.), map size: 1565609 /// Broken because there is 0 key in dataset * Google DenseMap: Elapsed: 0.760 (131615151.233 elem/sec.), map size: 1565609 /// Broken because there is 0 key in dataset
* Abseil HashMap: Elapsed: 0.303 (330461565.053 elem/sec.), map size: 10 * Abseil HashMap: Elapsed: 0.309 (324068156.680 elem/sec.), map size: 10
* std::unordered_map: Elapsed: 0.843 (118596530.649 elem/sec.), map size: 10 * Abseil HashMap with CH Hash: Elapsed: 0.339 (295108223.814 elem/sec.), map size: 10
* std::unordered_map: Elapsed: 0.811 (123304031.195 elem/sec.), map size: 10
* *
* File hits_100m_obfuscated/201307_1_96_4/AdvEngineID.bin * File hits_100m_obfuscated/201307_1_96_4/AdvEngineID.bin
* CH HashMap: Elapsed: 0.160 (623399865.019 elem/sec.), map size: 19 * CH HashMap: Elapsed: 0.155 (643245257.748 elem/sec.), map size: 19
* Google DenseMap: Elapsed: 1.673 (59757144.027 elem/sec.), map size: 32260732 /// Broken because there is 0 key in dataset * Google DenseMap: Elapsed: 1.629 (61395025.417 elem/sec.), map size: 32260732 // Broken because there is 0 key in dataset
* Abseil HashMap: Elapsed: 0.297 (336589258.845 elem/sec.), map size: 19 * Abseil HashMap: Elapsed: 0.292 (342765027.204 elem/sec.), map size: 19
* std::unordered_map: Elapsed: 0.332 (301114451.384 elem/sec.), map size: 19 * Abseil HashMap with CH Hash: Elapsed: 0.330 (302822020.210 elem/sec.), map size: 19
* std::unordered_map: Elapsed: 0.308 (325059333.730 elem/sec.), map size: 19
*
*
* Results of this benchmark on hits_100m_obfuscated AARCH64
*
* File hits_100m_obfuscated/201307_1_96_4/WatchID.bin
* CH HashMap: Elapsed: 9.530 (10493528.533 elem/sec.), map size: 99997493
* Google DenseMap: Elapsed: 14.436 (6927091.135 elem/sec.), map size: 99997493
* Abseil HashMap: Elapsed: 16.671 (5998504.085 elem/sec.), map size: 99997493
* Abseil HashMap with CH Hash: Elapsed: 16.803 (5951365.711 elem/sec.), map size: 99997493
* std::unordered_map: Elapsed: 50.805 (1968305.658 elem/sec.), map size: 99997493
*
* File hits_100m_obfuscated/201307_1_96_4/URLHash.bin
* CH HashMap: Elapsed: 3.693 (27076878.092 elem/sec.), map size: 20714865
* Google DenseMap: Elapsed: 5.051 (19796401.694 elem/sec.), map size: 20714865
* Abseil HashMap: Elapsed: 5.617 (17804528.625 elem/sec.), map size: 20714865
* Abseil HashMap with CH Hash: Elapsed: 5.702 (17537013.639 elem/sec.), map size: 20714865
* std::unordered_map: Elapsed: 10.757 (9296040.953 elem/sec.), map size: 2071486
*
* File hits_100m_obfuscated/201307_1_96_4/UserID.bin
* CH HashMap: Elapsed: 2.982 (33535795.695 elem/sec.), map size: 17630976
* Google DenseMap: Elapsed: 3.940 (25381557.959 elem/sec.), map size: 17630976
* Abseil HashMap: Elapsed: 4.493 (22259078.458 elem/sec.), map size: 17630976
* Abseil HashMap with CH Hash: Elapsed: 4.596 (21759738.710 elem/sec.), map size: 17630976
* std::unordered_map: Elapsed: 9.035 (11067903.596 elem/sec.), map size: 17630976
*
* File hits_100m_obfuscated/201307_1_96_4/RegionID.bin
* CH HashMap: Elapsed: 0.302 (331026285.361 elem/sec.), map size: 9040
* Google DenseMap: Elapsed: 0.623 (160419421.840 elem/sec.), map size: 9046
* Abseil HashMap: Elapsed: 0.981 (101971186.758 elem/sec.), map size: 9040
* Abseil HashMap with CH Hash: Elapsed: 0.991 (100932993.199 elem/sec.), map size: 9040
* std::unordered_map: Elapsed: 0.809 (123541402.715 elem/sec.), map size: 9040
*
* File hits_100m_obfuscated/201307_1_96_4/CounterID.bin
* CH HashMap: Elapsed: 0.343 (291821742.078 elem/sec.), map size: 6506
* Google DenseMap: Elapsed: 0.718 (139191105.450 elem/sec.), map size: 6506
* Abseil HashMap: Elapsed: 1.019 (98148285.278 elem/sec.), map size: 6506
* Abseil HashMap with CH Hash: Elapsed: 1.048 (95446843.667 elem/sec.), map size: 6506
* std::unordered_map: Elapsed: 0.701 (142701070.085 elem/sec.), map size: 6506
*
* File hits_100m_obfuscated/201307_1_96_4/TraficSourceID.bin
* CH HashMap: Elapsed: 0.376 (265905243.103 elem/sec.), map size: 10
* Google DenseMap: Elapsed: 1.309 (76420707.298 elem/sec.), map size: 1565609 /// Broken because there is 0 key in dataset
* Abseil HashMap: Elapsed: 0.955 (104668109.775 elem/sec.), map size: 10
* Abseil HashMap with CH Hash: Elapsed: 0.967 (103456305.391 elem/sec.), map size: 10
* std::unordered_map: Elapsed: 1.241 (80591305.890 elem/sec.), map size: 10
*
* File hits_100m_obfuscated/201307_1_96_4/AdvEngineID.bin
* CH HashMap: Elapsed: 0.213 (470208130.105 elem/sec.), map size: 19
* Google DenseMap: Elapsed: 2.525 (39607131.523 elem/sec.), map size: 32260732 /// Broken because there is 0 key in dataset
* Abseil HashMap: Elapsed: 0.950 (105233678.618 elem/sec.), map size: 19
* Abseil HashMap with CH Hash: Elapsed: 0.962 (104001230.717 elem/sec.), map size: 19
* std::unordered_map: Elapsed: 0.585 (171059989.837 elem/sec.), map size: 19
*/ */
int main(int argc, char ** argv) int main(int argc, char ** argv)

View File

@ -81,10 +81,41 @@ struct NetworkInterfaces
bool isLocalAddress(const Poco::Net::IPAddress & address) bool isLocalAddress(const Poco::Net::IPAddress & address)
{ {
/** 127.0.0.1 is treat as local address unconditionally.
* ::1 is also treat as local address unconditionally.
*
* 127.0.0.{2..255} are not treat as local addresses, because they are used in tests
* to emulate distributed queries across localhost.
*
* But 127.{0,1}.{0,1}.{0,1} are treat as local addresses,
* because they are used in Debian for localhost.
*/
if (address.isLoopback())
{
if (address.family() == Poco::Net::AddressFamily::IPv4)
{
/// The address is located in memory in big endian form (network byte order).
const unsigned char * digits = static_cast<const unsigned char *>(address.addr());
if (digits[0] == 127
&& digits[1] <= 1
&& digits[2] <= 1
&& digits[3] <= 1)
{
return true;
}
}
else if (address.family() == Poco::Net::AddressFamily::IPv6)
{
return true;
}
}
NetworkInterfaces interfaces; NetworkInterfaces interfaces;
return interfaces.hasAddress(address); return interfaces.hasAddress(address);
} }
bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port) bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port)
{ {
return clickhouse_port == address.port() && isLocalAddress(address.host()); return clickhouse_port == address.port() && isLocalAddress(address.host());

View File

@ -11,9 +11,30 @@ TEST(LocalAddress, SmokeTest)
std::string address_str; std::string address_str;
DB::readString(address_str, cmd->out); DB::readString(address_str, cmd->out);
cmd->wait(); cmd->wait();
std::cerr << "Got Address:" << address_str << std::endl; std::cerr << "Got Address: " << address_str << std::endl;
Poco::Net::IPAddress address(address_str); Poco::Net::IPAddress address(address_str);
EXPECT_TRUE(DB::isLocalAddress(address)); EXPECT_TRUE(DB::isLocalAddress(address));
} }
TEST(LocalAddress, Localhost)
{
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"127.0.0.1"}));
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"127.0.1.1"}));
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"127.1.1.1"}));
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"127.1.0.1"}));
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"127.1.0.0"}));
EXPECT_TRUE(DB::isLocalAddress(Poco::Net::IPAddress{"::1"}));
/// Make sure we don't mess with the byte order.
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"1.0.0.127"}));
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"1.1.1.127"}));
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"0.0.0.0"}));
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"::"}));
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"::2"}));
/// See the comment in the implementation of isLocalAddress.
EXPECT_FALSE(DB::isLocalAddress(Poco::Net::IPAddress{"127.0.0.2"}));
}

View File

@ -721,6 +721,9 @@ private:
#undef DBMS_MIN_FIELD_SIZE #undef DBMS_MIN_FIELD_SIZE
using Row = std::vector<Field>;
template <> struct Field::TypeToEnum<Null> { static const Types::Which value = Types::Null; }; template <> struct Field::TypeToEnum<Null> { static const Types::Which value = Types::Null; };
template <> struct Field::TypeToEnum<UInt64> { static const Types::Which value = Types::UInt64; }; template <> struct Field::TypeToEnum<UInt64> { static const Types::Which value = Types::UInt64; };
template <> struct Field::TypeToEnum<UInt128> { static const Types::Which value = Types::UInt128; }; template <> struct Field::TypeToEnum<UInt128> { static const Types::Which value = Types::UInt128; };

View File

@ -452,7 +452,7 @@ namespace MySQLReplication
UInt32 number_columns; UInt32 number_columns;
String schema; String schema;
String table; String table;
std::vector<Field> rows; Row rows;
RowsEvent(std::shared_ptr<TableMapEvent> table_map_, EventHeader && header_, const RowsEventHeader & rows_header) RowsEvent(std::shared_ptr<TableMapEvent> table_map_, EventHeader && header_, const RowsEventHeader & rows_header)
: EventBase(std::move(header_)), number_columns(0), table_map(table_map_) : EventBase(std::move(header_)), number_columns(0), table_map(table_map_)

View File

@ -1,18 +0,0 @@
#pragma once
#include <vector>
#include <Common/AutoArray.h>
#include <Core/Field.h>
namespace DB
{
/** The data type for representing one row of the table in the RAM.
* Warning! It is preferable to store column blocks instead of single rows. See Block.h
*/
using Row = AutoArray<Field>;
}

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <Core/Row.h>
#include <Core/SortDescription.h> #include <Core/SortDescription.h>
#include <Core/SortCursor.h> #include <Core/SortCursor.h>

View File

@ -193,7 +193,7 @@ void PostgreSQLBlockInputStream::insertValue(IColumn & column, std::string_view
size_t dimension = 0, max_dimension = 0, expected_dimensions = array_info[idx].num_dimensions; size_t dimension = 0, max_dimension = 0, expected_dimensions = array_info[idx].num_dimensions;
const auto parse_value = array_info[idx].pqxx_parser; const auto parse_value = array_info[idx].pqxx_parser;
std::vector<std::vector<Field>> dimensions(expected_dimensions + 1); std::vector<Row> dimensions(expected_dimensions + 1);
while (parsed.first != pqxx::array_parser::juncture::done) while (parsed.first != pqxx::array_parser::juncture::done)
{ {

View File

@ -20,6 +20,7 @@
# include <Parsers/parseQuery.h> # include <Parsers/parseQuery.h>
# include <Parsers/queryToString.h> # include <Parsers/queryToString.h>
# include <Storages/StorageMySQL.h> # include <Storages/StorageMySQL.h>
# include <Storages/MySQL/MySQLSettings.h>
# include <Common/escapeForFileName.h> # include <Common/escapeForFileName.h>
# include <Common/parseAddress.h> # include <Common/parseAddress.h>
# include <Common/setThreadName.h> # include <Common/setThreadName.h>
@ -253,12 +254,13 @@ void DatabaseConnectionMySQL::fetchLatestTablesStructureIntoCache(
std::move(mysql_pool), std::move(mysql_pool),
database_name_in_mysql, database_name_in_mysql,
table_name, table_name,
false, /* replace_query_ */ false,
"", /* on_duplicate_clause = */ "",
ColumnsDescription{columns_name_and_type}, ColumnsDescription{columns_name_and_type},
ConstraintsDescription{}, ConstraintsDescription{},
String{}, String{},
getContext())); getContext(),
MySQLSettings{}));
} }
} }

View File

@ -477,7 +477,7 @@ static inline void fillSignAndVersionColumnsData(Block & data, Int8 sign_value,
template <bool assert_nullable = false> template <bool assert_nullable = false>
static void writeFieldsToColumn( static void writeFieldsToColumn(
IColumn & column_to, const std::vector<Field> & rows_data, size_t column_index, const std::vector<bool> & mask, ColumnUInt8 * null_map_column = nullptr) IColumn & column_to, const Row & rows_data, size_t column_index, const std::vector<bool> & mask, ColumnUInt8 * null_map_column = nullptr)
{ {
if (ColumnNullable * column_nullable = typeid_cast<ColumnNullable *>(&column_to)) if (ColumnNullable * column_nullable = typeid_cast<ColumnNullable *>(&column_to))
writeFieldsToColumn<true>(column_nullable->getNestedColumn(), rows_data, column_index, mask, &column_nullable->getNullMapColumn()); writeFieldsToColumn<true>(column_nullable->getNestedColumn(), rows_data, column_index, mask, &column_nullable->getNullMapColumn());
@ -599,7 +599,7 @@ static void writeFieldsToColumn(
} }
template <Int8 sign> template <Int8 sign>
static size_t onWriteOrDeleteData(const std::vector<Field> & rows_data, Block & buffer, size_t version) static size_t onWriteOrDeleteData(const Row & rows_data, Block & buffer, size_t version)
{ {
size_t prev_bytes = buffer.bytes(); size_t prev_bytes = buffer.bytes();
for (size_t column = 0; column < buffer.columns() - 2; ++column) for (size_t column = 0; column < buffer.columns() - 2; ++column)
@ -623,7 +623,7 @@ static inline bool differenceSortingKeys(const Tuple & row_old_data, const Tuple
return false; return false;
} }
static inline size_t onUpdateData(const std::vector<Field> & rows_data, Block & buffer, size_t version, const std::vector<size_t> & sorting_columns_index) static inline size_t onUpdateData(const Row & rows_data, Block & buffer, size_t version, const std::vector<size_t> & sorting_columns_index)
{ {
if (rows_data.size() % 2 != 0) if (rows_data.size() % 2 != 0)
throw Exception("LOGICAL ERROR: It is a bug.", ErrorCodes::LOGICAL_ERROR); throw Exception("LOGICAL ERROR: It is a bug.", ErrorCodes::LOGICAL_ERROR);

View File

@ -1,6 +1,5 @@
#include <Common/quoteString.h> #include <Common/quoteString.h>
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
#include <Core/Row.h>
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionsMiscellaneous.h> #include <Functions/FunctionsMiscellaneous.h>

View File

@ -34,7 +34,7 @@ public:
FillColumnDescription & getFillDescription(size_t ind) { return description[ind].fill_description; } FillColumnDescription & getFillDescription(size_t ind) { return description[ind].fill_description; }
private: private:
std::vector<Field> row; Row row;
SortDescription description; SortDescription description;
}; };

View File

@ -1,7 +1,6 @@
#include <optional> #include <optional>
#include <Core/Field.h> #include <Core/Field.h>
#include <Core/Row.h>
#include <Columns/ColumnsNumber.h> #include <Columns/ColumnsNumber.h>
#include <Columns/ColumnTuple.h> #include <Columns/ColumnTuple.h>

View File

@ -12,7 +12,6 @@
#define DBMS_HASH_MAP_COUNT_COLLISIONS #define DBMS_HASH_MAP_COUNT_COLLISIONS
*/ */
#include <common/types.h> #include <common/types.h>
#include <Core/Row.h>
#include <IO/ReadBufferFromFile.h> #include <IO/ReadBufferFromFile.h>
#include <Compression/CompressedReadBuffer.h> #include <Compression/CompressedReadBuffer.h>
#include <Common/HashTable/HashMap.h> #include <Common/HashTable/HashMap.h>
@ -27,19 +26,6 @@
* This is important, because if you run all the tests one by one, the results will be incorrect. * This is important, because if you run all the tests one by one, the results will be incorrect.
* (Due to the peculiarities of the work of the allocator, the first test takes advantage.) * (Due to the peculiarities of the work of the allocator, the first test takes advantage.)
* *
* Depending on USE_AUTO_ARRAY, one of the structures is selected as the value.
* USE_AUTO_ARRAY = 0 - uses std::vector (hard-copy structure, sizeof = 24 bytes).
* USE_AUTO_ARRAY = 1 - uses AutoArray (a structure specially designed for such cases, sizeof = 8 bytes).
*
* That is, the test also allows you to compare AutoArray and std::vector.
*
* If USE_AUTO_ARRAY = 0, then HashMap confidently overtakes all.
* If USE_AUTO_ARRAY = 1, then HashMap is slightly less serious (20%) ahead of google::dense_hash_map.
*
* When using HashMap, AutoArray has a rather serious (40%) advantage over std::vector.
* And when using other hash tables, AutoArray even more seriously overtakes std::vector
* (up to three and a half times in the case of std::unordered_map and google::sparse_hash_map).
*
* HashMap, unlike google::dense_hash_map, much more depends on the quality of the hash function. * HashMap, unlike google::dense_hash_map, much more depends on the quality of the hash function.
* *
* PS. Measure everything yourself, otherwise I'm almost confused. * PS. Measure everything yourself, otherwise I'm almost confused.
@ -49,9 +35,6 @@
* But in this test, there was something similar to the old scenario of using hash tables in the aggregation. * But in this test, there was something similar to the old scenario of using hash tables in the aggregation.
*/ */
#define USE_AUTO_ARRAY 0
struct AlternativeHash struct AlternativeHash
{ {
size_t operator() (UInt64 x) const size_t operator() (UInt64 x) const
@ -85,12 +68,7 @@ int main(int argc, char ** argv)
using namespace DB; using namespace DB;
using Key = UInt64; using Key = UInt64;
#if USE_AUTO_ARRAY
using Value = AutoArray<IAggregateFunction*>;
#else
using Value = std::vector<IAggregateFunction*>; using Value = std::vector<IAggregateFunction*>;
#endif
size_t n = argc < 2 ? 10000000 : std::stol(argv[1]); size_t n = argc < 2 ? 10000000 : std::stol(argv[1]);
//size_t m = std::stol(argv[2]); //size_t m = std::stol(argv[2]);
@ -119,13 +97,8 @@ int main(int argc, char ** argv)
INIT INIT
#ifndef USE_AUTO_ARRAY
#undef INIT #undef INIT
#define INIT #define INIT
#endif
Row row(1);
row[0] = UInt64(0);
std::cerr << "sizeof(Key) = " << sizeof(Key) << ", sizeof(Value) = " << sizeof(Value) << std::endl; std::cerr << "sizeof(Key) = " << sizeof(Key) << ", sizeof(Value) = " << sizeof(Value) << std::endl;

View File

@ -95,7 +95,7 @@ void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, F
if (tables()) if (tables())
{ {
s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "FROM " << (s.hilite ? hilite_none : ""); s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "FROM" << (s.hilite ? hilite_none : "");
tables()->formatImpl(s, state, frame); tables()->formatImpl(s, state, frame);
} }

View File

@ -35,24 +35,24 @@ void ASTSelectWithUnionQuery::formatQueryImpl(const FormatSettings & settings, F
if (mode == Mode::Unspecified) if (mode == Mode::Unspecified)
return ""; return "";
else if (mode == Mode::ALL) else if (mode == Mode::ALL)
return "ALL"; return " ALL";
else else
return "DISTINCT"; return " DISTINCT";
}; };
for (ASTs::const_iterator it = list_of_selects->children.begin(); it != list_of_selects->children.end(); ++it) for (ASTs::const_iterator it = list_of_selects->children.begin(); it != list_of_selects->children.end(); ++it)
{ {
if (it != list_of_selects->children.begin()) if (it != list_of_selects->children.begin())
settings.ostr << settings.nl_or_ws << indent_str << (settings.hilite ? hilite_keyword : "") << "UNION " settings.ostr << settings.nl_or_ws << indent_str << (settings.hilite ? hilite_keyword : "") << "UNION"
<< mode_to_str((is_normalized) ? union_mode : list_of_modes[it - list_of_selects->children.begin() - 1]) << mode_to_str((is_normalized) ? union_mode : list_of_modes[it - list_of_selects->children.begin() - 1])
<< (settings.hilite ? hilite_none : ""); << (settings.hilite ? hilite_none : "");
if (auto * node = (*it)->as<ASTSelectWithUnionQuery>()) if (auto * node = (*it)->as<ASTSelectWithUnionQuery>())
{ {
settings.ostr << settings.nl_or_ws << indent_str;
if (node->list_of_selects->children.size() == 1) if (node->list_of_selects->children.size() == 1)
{ {
if (it != list_of_selects->children.begin())
settings.ostr << settings.nl_or_ws;
(node->list_of_selects->children.at(0))->formatImpl(settings, state, frame); (node->list_of_selects->children.at(0))->formatImpl(settings, state, frame);
} }
else else

View File

@ -29,6 +29,11 @@ void ASTSubquery::appendColumnNameImpl(WriteBuffer & ostr) const
void ASTSubquery::formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const void ASTSubquery::formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{ {
/// NOTE: due to trickery of filling cte_name (in interpreters) it is hard
/// to print it w/o newline (for !oneline case), since if nl_or_ws
/// prepended here, then formatting will be incorrect with alias:
///
/// (select 1 in ((select 1) as sub))
if (!cte_name.empty()) if (!cte_name.empty())
{ {
settings.ostr << (settings.hilite ? hilite_identifier : ""); settings.ostr << (settings.hilite ? hilite_identifier : "");
@ -40,7 +45,7 @@ void ASTSubquery::formatImplWithoutAlias(const FormatSettings & settings, Format
std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' '); std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' ');
std::string nl_or_nothing = settings.one_line ? "" : "\n"; std::string nl_or_nothing = settings.one_line ? "" : "\n";
settings.ostr << nl_or_nothing << indent_str << "(" << nl_or_nothing; settings.ostr << "(" << nl_or_nothing;
FormatStateStacked frame_nested = frame; FormatStateStacked frame_nested = frame;
frame_nested.need_parens = false; frame_nested.need_parens = false;
++frame_nested.indent; ++frame_nested.indent;

View File

@ -109,14 +109,17 @@ void ASTTableExpression::formatImpl(const FormatSettings & settings, FormatState
if (database_and_table_name) if (database_and_table_name)
{ {
settings.ostr << " ";
database_and_table_name->formatImpl(settings, state, frame); database_and_table_name->formatImpl(settings, state, frame);
} }
else if (table_function) else if (table_function)
{ {
settings.ostr << " ";
table_function->formatImpl(settings, state, frame); table_function->formatImpl(settings, state, frame);
} }
else if (subquery) else if (subquery)
{ {
settings.ostr << settings.nl_or_ws << indent_str;
subquery->formatImpl(settings, state, frame); subquery->formatImpl(settings, state, frame);
} }
@ -142,9 +145,15 @@ void ASTTableExpression::formatImpl(const FormatSettings & settings, FormatState
} }
void ASTTableJoin::formatImplBeforeTable(const FormatSettings & settings, FormatState &, FormatStateStacked) const void ASTTableJoin::formatImplBeforeTable(const FormatSettings & settings, FormatState &, FormatStateStacked frame) const
{ {
settings.ostr << (settings.hilite ? hilite_keyword : ""); settings.ostr << (settings.hilite ? hilite_keyword : "");
std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
if (kind != Kind::Comma)
{
settings.ostr << settings.nl_or_ws << indent_str;
}
switch (locality) switch (locality)
{ {
@ -241,6 +250,7 @@ void ASTArrayJoin::formatImpl(const FormatSettings & settings, FormatState & sta
frame.expression_list_prepend_whitespace = true; frame.expression_list_prepend_whitespace = true;
settings.ostr << (settings.hilite ? hilite_keyword : "") settings.ostr << (settings.hilite ? hilite_keyword : "")
<< settings.nl_or_ws
<< (kind == Kind::Left ? "LEFT " : "") << "ARRAY JOIN" << (settings.hilite ? hilite_none : ""); << (kind == Kind::Left ? "LEFT " : "") << "ARRAY JOIN" << (settings.hilite ? hilite_none : "");
settings.one_line settings.one_line
@ -254,10 +264,7 @@ void ASTTablesInSelectQueryElement::formatImpl(const FormatSettings & settings,
if (table_expression) if (table_expression)
{ {
if (table_join) if (table_join)
{
table_join->as<ASTTableJoin &>().formatImplBeforeTable(settings, state, frame); table_join->as<ASTTableJoin &>().formatImplBeforeTable(settings, state, frame);
settings.ostr << " ";
}
table_expression->formatImpl(settings, state, frame); table_expression->formatImpl(settings, state, frame);
@ -275,13 +282,8 @@ void ASTTablesInSelectQuery::formatImpl(const FormatSettings & settings, FormatS
{ {
std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) for (const auto & child : children)
{ child->formatImpl(settings, state, frame);
if (it != children.begin())
settings.ostr << settings.nl_or_ws << indent_str;
(*it)->formatImpl(settings, state, frame);
}
} }
} }

View File

@ -16,8 +16,11 @@ ASTPtr ASTWithElement::clone() const
void ASTWithElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const void ASTWithElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{ {
std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
settings.writeIdentifier(name); settings.writeIdentifier(name);
settings.ostr << (settings.hilite ? hilite_keyword : "") << " AS " << (settings.hilite ? hilite_none : ""); settings.ostr << (settings.hilite ? hilite_keyword : "") << " AS" << (settings.hilite ? hilite_none : "");
settings.ostr << settings.nl_or_ws << indent_str;
dynamic_cast<const ASTWithAlias &>(*subquery).formatImplWithoutAlias(settings, state, frame); dynamic_cast<const ASTWithAlias &>(*subquery).formatImplWithoutAlias(settings, state, frame);
} }

View File

@ -344,7 +344,7 @@ AvroDeserializer::DeserializeFn AvroDeserializer::createDeserializeFn(avro::Node
if (target.isEnum()) if (target.isEnum())
{ {
const auto & enum_type = dynamic_cast<const IDataTypeEnum &>(*target_type); const auto & enum_type = dynamic_cast<const IDataTypeEnum &>(*target_type);
std::vector<Field> symbol_mapping; Row symbol_mapping;
for (size_t i = 0; i < root_node->names(); i++) for (size_t i = 0; i < root_node->names(); i++)
{ {
symbol_mapping.push_back(enum_type.castToValue(root_node->nameAt(i))); symbol_mapping.push_back(enum_type.castToValue(root_node->nameAt(i)));

View File

@ -12,6 +12,7 @@
#include <DataTypes/NestedUtils.h> #include <DataTypes/NestedUtils.h>
#include <IO/WriteHelpers.h> #include <IO/WriteHelpers.h>
namespace DB namespace DB
{ {
@ -109,6 +110,9 @@ static bool isInPartitionKey(const std::string & column_name, const Names & part
return is_in_partition_key != partition_key_columns.end(); return is_in_partition_key != partition_key_columns.end();
} }
using Row = std::vector<Field>;
/// Returns true if merge result is not empty /// Returns true if merge result is not empty
static bool mergeMap(const SummingSortedAlgorithm::MapDescription & desc, static bool mergeMap(const SummingSortedAlgorithm::MapDescription & desc,
Row & row, const ColumnRawPtrs & raw_columns, size_t row_number) Row & row, const ColumnRawPtrs & raw_columns, size_t row_number)

View File

@ -2,7 +2,7 @@
#include <Processors/Merges/Algorithms/IMergingAlgorithmWithDelayedChunk.h> #include <Processors/Merges/Algorithms/IMergingAlgorithmWithDelayedChunk.h>
#include <Processors/Merges/Algorithms/MergedData.h> #include <Processors/Merges/Algorithms/MergedData.h>
#include <Core/Row.h>
namespace DB namespace DB
{ {

View File

@ -68,9 +68,6 @@ void readHeaders(
if (in.eof()) if (in.eof())
throw Poco::Net::MessageException("Field is invalid"); throw Poco::Net::MessageException("Field is invalid");
if (value.empty())
throw Poco::Net::MessageException("Field value is empty");
if (ch == '\n') if (ch == '\n')
throw Poco::Net::MessageException("No CRLF found"); throw Poco::Net::MessageException("No CRLF found");

View File

@ -2,7 +2,6 @@
#include <DataStreams/IBlockInputStream.h> #include <DataStreams/IBlockInputStream.h>
#include <Core/Row.h>
#include <Core/Block.h> #include <Core/Block.h>
#include <common/types.h> #include <common/types.h>
#include <Core/NamesAndTypes.h> #include <Core/NamesAndTypes.h>

View File

@ -211,9 +211,12 @@ namespace
virtual void insertStringColumn(const ColumnPtr & column, const String & name) = 0; virtual void insertStringColumn(const ColumnPtr & column, const String & name) = 0;
virtual void insertUInt64Column(const ColumnPtr & column, const String & name) = 0; virtual void insertUInt64Column(const ColumnPtr & column, const String & name) = 0;
virtual void insertUUIDColumn(const ColumnPtr & column, const String & name) = 0; virtual void insertUUIDColumn(const ColumnPtr & column, const String & name) = 0;
virtual void
insertPartitionValueColumn(size_t rows, const Row & partition_value, const DataTypePtr & partition_value_type, const String & name) virtual void insertPartitionValueColumn(
= 0; size_t rows,
const Row & partition_value,
const DataTypePtr & partition_value_type,
const String & name) = 0;
}; };
} }
@ -358,8 +361,8 @@ namespace
columns.push_back(column); columns.push_back(column);
} }
void void insertPartitionValueColumn(
insertPartitionValueColumn(size_t rows, const Row & partition_value, const DataTypePtr & partition_value_type, const String &) final size_t rows, const Row & partition_value, const DataTypePtr & partition_value_type, const String &) final
{ {
ColumnPtr column; ColumnPtr column;
if (rows) if (rows)

View File

@ -79,7 +79,7 @@ void MergeTreeDataPartInMemory::flushToDisk(const String & base_path, const Stri
new_data_part->uuid = uuid; new_data_part->uuid = uuid;
new_data_part->setColumns(columns); new_data_part->setColumns(columns);
new_data_part->partition.value.assign(partition.value); new_data_part->partition.value = partition.value;
new_data_part->minmax_idx = minmax_idx; new_data_part->minmax_idx = minmax_idx;
if (disk->exists(destination_path)) if (disk->exists(destination_path))

View File

@ -150,7 +150,7 @@ BlocksWithPartition MergeTreeDataWriter::splitBlockIntoParts(const Block & block
if (!metadata_snapshot->hasPartitionKey()) /// Table is not partitioned. if (!metadata_snapshot->hasPartitionKey()) /// Table is not partitioned.
{ {
result.emplace_back(Block(block), Row()); result.emplace_back(Block(block), Row{});
return result; return result;
} }

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <Core/Block.h> #include <Core/Block.h>
#include <Core/Row.h>
#include <IO/WriteBufferFromFile.h> #include <IO/WriteBufferFromFile.h>
#include <Compression/CompressedWriteBuffer.h> #include <Compression/CompressedWriteBuffer.h>

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <Core/Row.h>
#include <common/types.h> #include <common/types.h>
#include <Disks/IDisk.h> #include <Disks/IDisk.h>
#include <IO/WriteBuffer.h> #include <IO/WriteBuffer.h>
#include <Core/Field.h>
namespace DB namespace DB
{ {
@ -38,7 +39,7 @@ public:
void store(const MergeTreeData & storage, const DiskPtr & disk, const String & part_path, MergeTreeDataPartChecksums & checksums) const; void store(const MergeTreeData & storage, const DiskPtr & disk, const String & part_path, MergeTreeDataPartChecksums & checksums) const;
void store(const Block & partition_key_sample, const DiskPtr & disk, const String & part_path, MergeTreeDataPartChecksums & checksums) const; void store(const Block & partition_key_sample, const DiskPtr & disk, const String & part_path, MergeTreeDataPartChecksums & checksums) const;
void assign(const MergeTreePartition & other) { value.assign(other.value); } void assign(const MergeTreePartition & other) { value = other.value; }
void create(const StorageMetadataPtr & metadata_snapshot, Block block, size_t row); void create(const StorageMetadataPtr & metadata_snapshot, Block block, size_t row);
}; };

View File

@ -0,0 +1,42 @@
#include <Storages/MySQL/MySQLSettings.h>
#include <Parsers/ASTCreateQuery.h>
#include <Parsers/ASTSetQuery.h>
#include <Parsers/ASTFunction.h>
#include <Common/Exception.h>
namespace DB
{
namespace ErrorCodes
{
extern const int UNKNOWN_SETTING;
}
IMPLEMENT_SETTINGS_TRAITS(MySQLSettingsTraits, LIST_OF_MYSQL_SETTINGS)
void MySQLSettings::loadFromQuery(ASTStorage & storage_def)
{
if (storage_def.settings)
{
try
{
applyChanges(storage_def.settings->changes);
}
catch (Exception & e)
{
if (e.code() == ErrorCodes::UNKNOWN_SETTING)
e.addMessage("for storage " + storage_def.engine->name);
throw;
}
}
else
{
auto settings_ast = std::make_shared<ASTSetQuery>();
settings_ast->is_standalone = false;
storage_def.set(storage_def.settings, settings_ast);
}
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <Core/Defines.h>
#include <Core/BaseSettings.h>
namespace Poco::Util
{
class AbstractConfiguration;
}
namespace DB
{
class ASTStorage;
#define LIST_OF_MYSQL_SETTINGS(M) \
M(UInt64, connection_pool_size, 16, "Size of connection pool (if all connections are in use, the query will wait until some connection will be freed).", 0) \
M(UInt64, connection_max_tries, 3, "Number of retries for pool with failover", 0) \
M(Bool, connection_auto_close, true, "Auto-close connection after query execution, i.e. disable connection reuse.", 0) \
DECLARE_SETTINGS_TRAITS(MySQLSettingsTraits, LIST_OF_MYSQL_SETTINGS)
/** Settings for the MySQL family of engines.
*/
struct MySQLSettings : public BaseSettings<MySQLSettingsTraits>
{
void loadFromQuery(ASTStorage & storage_def);
};
}

View File

@ -12,6 +12,7 @@
#include <Processors/Pipe.h> #include <Processors/Pipe.h>
#include <Common/parseRemoteDescription.h> #include <Common/parseRemoteDescription.h>
#include <Storages/StorageMySQL.h> #include <Storages/StorageMySQL.h>
#include <Storages/MySQL/MySQLSettings.h>
#include <Storages/StoragePostgreSQL.h> #include <Storages/StoragePostgreSQL.h>
#include <Storages/StorageURL.h> #include <Storages/StorageURL.h>
#include <common/logger_useful.h> #include <common/logger_useful.h>
@ -79,7 +80,8 @@ StorageExternalDistributed::StorageExternalDistributed(
columns_, columns_,
constraints_, constraints_,
String{}, String{},
context); context,
MySQLSettings{});
break; break;
} }
#endif #endif

View File

@ -15,6 +15,7 @@
#include <IO/Operators.h> #include <IO/Operators.h>
#include <IO/WriteHelpers.h> #include <IO/WriteHelpers.h>
#include <Parsers/ASTLiteral.h> #include <Parsers/ASTLiteral.h>
#include <Parsers/ASTCreateQuery.h>
#include <mysqlxx/Transaction.h> #include <mysqlxx/Transaction.h>
#include <Processors/Sources/SourceFromInputStream.h> #include <Processors/Sources/SourceFromInputStream.h>
#include <Processors/Pipe.h> #include <Processors/Pipe.h>
@ -50,13 +51,15 @@ StorageMySQL::StorageMySQL(
const ColumnsDescription & columns_, const ColumnsDescription & columns_,
const ConstraintsDescription & constraints_, const ConstraintsDescription & constraints_,
const String & comment, const String & comment,
ContextPtr context_) ContextPtr context_,
const MySQLSettings & mysql_settings_)
: IStorage(table_id_) : IStorage(table_id_)
, WithContext(context_->getGlobalContext()) , WithContext(context_->getGlobalContext())
, remote_database_name(remote_database_name_) , remote_database_name(remote_database_name_)
, remote_table_name(remote_table_name_) , remote_table_name(remote_table_name_)
, replace_query{replace_query_} , replace_query{replace_query_}
, on_duplicate_clause{on_duplicate_clause_} , on_duplicate_clause{on_duplicate_clause_}
, mysql_settings(mysql_settings_)
, pool(std::make_shared<mysqlxx::PoolWithFailover>(pool_)) , pool(std::make_shared<mysqlxx::PoolWithFailover>(pool_))
{ {
StorageInMemoryMetadata storage_metadata; StorageInMemoryMetadata storage_metadata;
@ -98,7 +101,8 @@ Pipe StorageMySQL::read(
} }
StreamSettings mysql_input_stream_settings(context_->getSettingsRef(), true, false); StreamSettings mysql_input_stream_settings(context_->getSettingsRef(),
mysql_settings.connection_auto_close);
return Pipe(std::make_shared<SourceFromInputStream>( return Pipe(std::make_shared<SourceFromInputStream>(
std::make_shared<MySQLWithFailoverBlockInputStream>(pool, query, sample_block, mysql_input_stream_settings))); std::make_shared<MySQLWithFailoverBlockInputStream>(pool, query, sample_block, mysql_input_stream_settings)));
} }
@ -250,8 +254,22 @@ void registerStorageMySQL(StorageFactory & factory)
const String & password = engine_args[4]->as<ASTLiteral &>().value.safeGet<String>(); const String & password = engine_args[4]->as<ASTLiteral &>().value.safeGet<String>();
size_t max_addresses = args.getContext()->getSettingsRef().glob_expansion_max_elements; size_t max_addresses = args.getContext()->getSettingsRef().glob_expansion_max_elements;
/// TODO: move some arguments from the arguments to the SETTINGS.
MySQLSettings mysql_settings;
if (args.storage_def->settings)
{
mysql_settings.loadFromQuery(*args.storage_def);
}
if (!mysql_settings.connection_pool_size)
throw Exception("connection_pool_size cannot be zero.", ErrorCodes::BAD_ARGUMENTS);
auto addresses = parseRemoteDescriptionForExternalDatabase(host_port, max_addresses, 3306); auto addresses = parseRemoteDescriptionForExternalDatabase(host_port, max_addresses, 3306);
mysqlxx::PoolWithFailover pool(remote_database, addresses, username, password); mysqlxx::PoolWithFailover pool(remote_database, addresses,
username, password,
MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
mysql_settings.connection_pool_size,
mysql_settings.connection_max_tries);
bool replace_query = false; bool replace_query = false;
std::string on_duplicate_clause; std::string on_duplicate_clause;
@ -275,9 +293,11 @@ void registerStorageMySQL(StorageFactory & factory)
args.columns, args.columns,
args.constraints, args.constraints,
args.comment, args.comment,
args.getContext()); args.getContext(),
mysql_settings);
}, },
{ {
.supports_settings = true,
.source_access_type = AccessType::MYSQL, .source_access_type = AccessType::MYSQL,
}); });
} }

View File

@ -9,6 +9,7 @@
#include <ext/shared_ptr_helper.h> #include <ext/shared_ptr_helper.h>
#include <Storages/IStorage.h> #include <Storages/IStorage.h>
#include <Storages/MySQL/MySQLSettings.h>
#include <mysqlxx/PoolWithFailover.h> #include <mysqlxx/PoolWithFailover.h>
@ -33,7 +34,8 @@ public:
const ColumnsDescription & columns_, const ColumnsDescription & columns_,
const ConstraintsDescription & constraints_, const ConstraintsDescription & constraints_,
const String & comment, const String & comment,
ContextPtr context_); ContextPtr context_,
const MySQLSettings & mysql_settings_);
std::string getName() const override { return "MySQL"; } std::string getName() const override { return "MySQL"; }
@ -56,6 +58,8 @@ private:
bool replace_query; bool replace_query;
std::string on_duplicate_clause; std::string on_duplicate_clause;
MySQLSettings mysql_settings;
mysqlxx::PoolWithFailoverPtr pool; mysqlxx::PoolWithFailoverPtr pool;
}; };

View File

@ -112,6 +112,7 @@ SRCS(
MergeTree/localBackup.cpp MergeTree/localBackup.cpp
MergeTree/registerStorageMergeTree.cpp MergeTree/registerStorageMergeTree.cpp
MutationCommands.cpp MutationCommands.cpp
MySQL/MySQLSettings.cpp
PartitionCommands.cpp PartitionCommands.cpp
ProjectionsDescription.cpp ProjectionsDescription.cpp
ReadInOrderOptimizer.cpp ReadInOrderOptimizer.cpp

View File

@ -15,6 +15,7 @@
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
#include <Parsers/ASTLiteral.h> #include <Parsers/ASTLiteral.h>
#include <Storages/StorageMySQL.h> #include <Storages/StorageMySQL.h>
#include <Storages/MySQL/MySQLSettings.h>
#include <TableFunctions/ITableFunction.h> #include <TableFunctions/ITableFunction.h>
#include <TableFunctions/TableFunctionFactory.h> #include <TableFunctions/TableFunctionFactory.h>
#include <TableFunctions/TableFunctionMySQL.h> #include <TableFunctions/TableFunctionMySQL.h>
@ -107,7 +108,8 @@ StoragePtr TableFunctionMySQL::executeImpl(
columns, columns,
ConstraintsDescription{}, ConstraintsDescription{},
String{}, String{},
context); context,
MySQLSettings{});
pool.reset(); pool.reset();

View File

@ -314,11 +314,12 @@ def colored(text, args, color=None, on_color=None, attrs=None):
SERVER_DIED = False SERVER_DIED = False
exit_code = 0 exit_code = 0
stop_time = None stop_time = None
queue = multiprocessing.Queue(maxsize=1)
# def run_tests_array(all_tests, suite, suite_dir, suite_tmp_dir, run_total): # def run_tests_array(all_tests, suite, suite_dir, suite_tmp_dir, run_total):
def run_tests_array(all_tests_with_params): def run_tests_array(all_tests_with_params):
all_tests, suite, suite_dir, suite_tmp_dir = all_tests_with_params all_tests, num_tests, suite, suite_dir, suite_tmp_dir = all_tests_with_params
global exit_code global exit_code
global SERVER_DIED global SERVER_DIED
global stop_time global stop_time
@ -348,10 +349,21 @@ def run_tests_array(all_tests_with_params):
else: else:
return '' return ''
if all_tests: if num_tests > 0:
print(f"\nRunning {len(all_tests)} {suite} tests ({multiprocessing.current_process().name}).\n") about = 'about ' if is_concurrent else ''
print(f"\nRunning {about}{num_tests} {suite} tests ({multiprocessing.current_process().name}).\n")
while True:
if is_concurrent:
case = queue.get()
if not case:
break
else:
if all_tests:
case = all_tests.pop(0)
else:
break
for case in all_tests:
if SERVER_DIED: if SERVER_DIED:
stop_tests() stop_tests()
break break
@ -677,6 +689,47 @@ def collect_build_flags(client):
return result return result
def do_run_tests(jobs, suite, suite_dir, suite_tmp_dir, all_tests, parallel_tests, sequential_tests, parallel):
if jobs > 1 and len(parallel_tests) > 0:
print("Found", len(parallel_tests), "parallel tests and", len(sequential_tests), "sequential tests")
run_n, run_total = parallel.split('/')
run_n = float(run_n)
run_total = float(run_total)
tests_n = len(parallel_tests)
if run_total > tests_n:
run_total = tests_n
if jobs > tests_n:
jobs = tests_n
if jobs > run_total:
run_total = jobs
batch_size = max(1, len(parallel_tests) // jobs)
parallel_tests_array = []
for _ in range(jobs):
parallel_tests_array.append((None, batch_size, suite, suite_dir, suite_tmp_dir))
with closing(multiprocessing.Pool(processes=jobs)) as pool:
pool.map_async(run_tests_array, parallel_tests_array)
for suit in parallel_tests:
queue.put(suit)
for _ in range(jobs):
queue.put(None)
queue.close()
pool.join()
run_tests_array((sequential_tests, len(sequential_tests), suite, suite_dir, suite_tmp_dir))
return len(sequential_tests) + len(parallel_tests)
else:
num_tests = len(all_tests)
run_tests_array((all_tests, num_tests, suite, suite_dir, suite_tmp_dir))
return num_tests
def main(args): def main(args):
global SERVER_DIED global SERVER_DIED
global stop_time global stop_time
@ -840,34 +893,8 @@ def main(args):
else: else:
parallel_tests.append(test) parallel_tests.append(test)
if jobs > 1 and len(parallel_tests) > 0: total_tests_run += do_run_tests(
print("Found", len(parallel_tests), "parallel tests and", len(sequential_tests), "sequential tests") jobs, suite, suite_dir, suite_tmp_dir, all_tests, parallel_tests, sequential_tests, args.parallel)
run_n, run_total = args.parallel.split('/')
run_n = float(run_n)
run_total = float(run_total)
tests_n = len(parallel_tests)
if run_total > tests_n:
run_total = tests_n
if jobs > tests_n:
jobs = tests_n
if jobs > run_total:
run_total = jobs
# Create two batches per process for more uniform execution time.
batch_size = max(1, len(parallel_tests) // (jobs * 2))
parallel_tests_array = []
for i in range(0, len(parallel_tests), batch_size):
parallel_tests_array.append((parallel_tests[i:i+batch_size], suite, suite_dir, suite_tmp_dir))
with closing(multiprocessing.Pool(processes=jobs)) as pool:
pool.map(run_tests_array, parallel_tests_array)
run_tests_array((sequential_tests, suite, suite_dir, suite_tmp_dir))
total_tests_run += len(sequential_tests) + len(parallel_tests)
else:
run_tests_array((all_tests, suite, suite_dir, suite_tmp_dir))
total_tests_run += len(all_tests)
if args.hung_check: if args.hung_check:

View File

@ -0,0 +1,29 @@
<test>
<preconditions>
<table_exists>hits_100m_single</table_exists>
</preconditions>
<substitutions>
<substitution>
<name>key</name>
<values>
<value>SearchEngineID</value>
<value>RegionID</value>
<value>SearchPhrase</value>
<value>ClientIP</value>
</values>
</substitution>
<substitution>
<name>func</name>
<values>
<value>quantile</value>
<value>quantileExact</value>
<value>quantileTDigest</value>
<value>quantileTiming</value>
<value>quantileBFloat16</value>
</values>
</substitution>
</substitutions>
<query>SELECT {key} AS k, {func}(ResolutionWidth) FROM hits_100m_single GROUP BY k FORMAT Null</query>
</test>

View File

@ -1,12 +1,9 @@
<test> <test>
<preconditions> <preconditions>
<table_exists>hits_100m_single</table_exists> <table_exists>hits_100m_single</table_exists>
<ram_size>30000000000</ram_size> <ram_size>30000000000</ram_size>
</preconditions> </preconditions>
<settings> <settings>
<max_memory_usage>30000000000</max_memory_usage> <max_memory_usage>30000000000</max_memory_usage>
<!-- <!--
@ -36,7 +33,7 @@
<value>SearchPhrase</value> <value>SearchPhrase</value>
<value>ClientIP</value> <value>ClientIP</value>
</values> </values>
</substitution> </substitution>
<substitution> <substitution>
<name>func</name> <name>func</name>
<values> <values>

View File

@ -1 +1 @@
CREATE VIEW default.test_view_00599\n(\n `id` UInt64\n) AS\nSELECT *\nFROM default.test_00599\nWHERE id = \n(\n SELECT 1\n) CREATE VIEW default.test_view_00599\n(\n `id` UInt64\n) AS\nSELECT *\nFROM default.test_00599\nWHERE id = (\n SELECT 1\n)

View File

@ -12,14 +12,11 @@ SELECT
platform, platform,
app app
FROM test_00751.t_00751 FROM test_00751.t_00751
WHERE (app = WHERE (app = (
(
SELECT min(app) SELECT min(app)
FROM test_00751.u_00751 FROM test_00751.u_00751
)) AND (platform = )) AND (platform = (
( SELECT (
SELECT
(
SELECT min(platform) SELECT min(platform)
FROM test_00751.v_00751 FROM test_00751.v_00751
) )

View File

@ -10,7 +10,9 @@
[30000] [30000]
30000 30000
[30000] [30000]
2016-06-15 23:01:04 2016-06-15 23:00:16
['2016-06-15 23:01:04'] ['2016-06-15 23:00:16']
2016-06-15 23:01:04 2016-06-15 23:00:16
['2016-06-15 23:01:04'] ['2016-06-15 23:00:16']
2016-04-02 17:23:12
['2016-04-02 17:23:12']

View File

@ -1,7 +1,7 @@
DROP TABLE IF EXISTS datetime; DROP TABLE IF EXISTS datetime;
CREATE TABLE datetime (d DateTime) ENGINE = Memory; CREATE TABLE datetime (d DateTime('UTC')) ENGINE = Memory;
INSERT INTO datetime(d) VALUES(toDateTime('2016-06-15 23:00:00')); INSERT INTO datetime(d) VALUES(toDateTime('2016-06-15 23:00:00', 'UTC'));
SELECT quantile(0.2)(d) FROM datetime; SELECT quantile(0.2)(d) FROM datetime;
SELECT quantiles(0.2)(d) FROM datetime; SELECT quantiles(0.2)(d) FROM datetime;
@ -27,4 +27,7 @@ SELECT quantilesTDigest(0.2)(d) FROM datetime;
SELECT quantileTDigestWeighted(0.2)(d, 1) FROM datetime; SELECT quantileTDigestWeighted(0.2)(d, 1) FROM datetime;
SELECT quantilesTDigestWeighted(0.2)(d, 1) FROM datetime; SELECT quantilesTDigestWeighted(0.2)(d, 1) FROM datetime;
SELECT quantileBFloat16(0.2)(d) FROM datetime;
SELECT quantilesBFloat16(0.2)(d) FROM datetime;
DROP TABLE datetime; DROP TABLE datetime;

View File

@ -4,8 +4,7 @@ SELECT 1
SELECT 1 SELECT 1
WHERE (1 IN (0, 2)) AND (2 = (identity(CAST(2, \'UInt8\')) AS subquery)) WHERE (1 IN (0, 2)) AND (2 = (identity(CAST(2, \'UInt8\')) AS subquery))
SELECT 1 SELECT 1
WHERE 1 IN ( WHERE 1 IN ((
(
SELECT arrayJoin([1, 2, 3]) SELECT arrayJoin([1, 2, 3])
) AS subquery) ) AS subquery)
SELECT 1 SELECT 1

View File

@ -6,6 +6,6 @@ CREATE TABLE default.distributed\n(\n `n` Int8\n)\nENGINE = Distributed(\'tes
CREATE TABLE default.distributed_tf\n(\n `n` Int8\n) AS cluster(\'test_shard_localhost\', \'default\', \'buffer\') CREATE TABLE default.distributed_tf\n(\n `n` Int8\n) AS cluster(\'test_shard_localhost\', \'default\', \'buffer\')
CREATE TABLE default.url\n(\n `n` UInt64,\n `col` String\n)\nENGINE = URL(\'https://localhost:8443/?query=select+n,+_table+from+default.merge+format+CSV\', \'CSV\') CREATE TABLE default.url\n(\n `n` UInt64,\n `col` String\n)\nENGINE = URL(\'https://localhost:8443/?query=select+n,+_table+from+default.merge+format+CSV\', \'CSV\')
CREATE TABLE default.rich_syntax\n(\n `n` Int64\n) AS remote(\'localhos{x|y|t}\', cluster(\'test_shard_localhost\', remote(\'127.0.0.{1..4}\', \'default\', \'view\'))) CREATE TABLE default.rich_syntax\n(\n `n` Int64\n) AS remote(\'localhos{x|y|t}\', cluster(\'test_shard_localhost\', remote(\'127.0.0.{1..4}\', \'default\', \'view\')))
CREATE VIEW default.view\n(\n `n` Int64\n) AS\nSELECT toInt64(n) AS n\nFROM \n(\n SELECT toString(n) AS n\n FROM default.merge\n WHERE _table != \'qwerty\'\n ORDER BY _table ASC\n)\nUNION ALL\nSELECT *\nFROM default.file CREATE VIEW default.view\n(\n `n` Int64\n) AS\nSELECT toInt64(n) AS n\nFROM\n(\n SELECT toString(n) AS n\n FROM default.merge\n WHERE _table != \'qwerty\'\n ORDER BY _table ASC\n)\nUNION ALL\nSELECT *\nFROM default.file
CREATE DICTIONARY default.dict\n(\n `n` UInt64,\n `col` String DEFAULT \'42\'\n)\nPRIMARY KEY n\nSOURCE(CLICKHOUSE(HOST \'localhost\' PORT 9440 SECURE 1 USER \'default\' TABLE \'url\'))\nLIFETIME(MIN 0 MAX 1)\nLAYOUT(CACHE(SIZE_IN_CELLS 1)) CREATE DICTIONARY default.dict\n(\n `n` UInt64,\n `col` String DEFAULT \'42\'\n)\nPRIMARY KEY n\nSOURCE(CLICKHOUSE(HOST \'localhost\' PORT 9440 SECURE 1 USER \'default\' TABLE \'url\'))\nLIFETIME(MIN 0 MAX 1)\nLAYOUT(CACHE(SIZE_IN_CELLS 1))
16 16

View File

@ -1,4 +1,5 @@
1 1
1
Code: 516 Code: 516
1 1
Code: 516 Code: 516

View File

@ -4,6 +4,7 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh # shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh . "$CURDIR"/../shell_config.sh
${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'EmptyHeader;' -d 'SELECT 1'
${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: default' -d 'SELECT 1' ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: default' -d 'SELECT 1'
${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: header_test' -d 'SELECT 1' | grep -o 'Code: 516' ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: header_test' -d 'SELECT 1' | grep -o 'Code: 516'
${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Key: ' -d 'SELECT 1' ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Key: ' -d 'SELECT 1'

View File

@ -7,4 +7,5 @@ WITH it AS
SELECT SELECT
number, number,
number number
FROM it AS i FROM
it AS i

View File

@ -51,4 +51,5 @@ WITH
SELECT SELECT
b, b,
a a
FROM x FROM
x

View File

@ -7,7 +7,7 @@ UNION ALL
SELECT 1 SELECT 1
UNION ALL UNION ALL
SELECT 1 SELECT 1
-
SELECT 1 SELECT 1
UNION ALL UNION ALL
( (
@ -19,7 +19,7 @@ UNION ALL
) )
UNION ALL UNION ALL
SELECT 1 SELECT 1
-
SELECT x SELECT x
FROM FROM
( (
@ -35,7 +35,7 @@ FROM
UNION ALL UNION ALL
SELECT 1 SELECT 1
) )
-
SELECT x SELECT x
FROM FROM
( (
@ -45,15 +45,15 @@ FROM
UNION ALL UNION ALL
SELECT 1 SELECT 1
) )
-
SELECT 1 SELECT 1
UNION DISTINCT UNION DISTINCT
SELECT 1 SELECT 1
UNION DISTINCT UNION DISTINCT
SELECT 1 SELECT 1
-
SELECT 1 SELECT 1
-
( (
SELECT 1 SELECT 1

View File

@ -13,7 +13,7 @@ UNION ALL
SELECT 1 SELECT 1
); );
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
SELECT 1 SELECT 1
@ -30,7 +30,7 @@ UNION ALL
SELECT 1 SELECT 1
); );
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
SELECT x SELECT x
@ -51,7 +51,7 @@ FROM
) )
); );
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
SELECT x SELECT x
@ -66,7 +66,7 @@ FROM
) )
); );
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
SELECT 1 SELECT 1
@ -75,12 +75,12 @@ SELECT 1
UNION DISTINCT UNION DISTINCT
SELECT 1; SELECT 1;
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
(((((((((((((((SELECT 1))))))))))))))); (((((((((((((((SELECT 1)))))))))))))));
SELECT ' '; SELECT '-';
EXPLAIN SYNTAX EXPLAIN SYNTAX
(((((((((((((((SELECT 1 UNION DISTINCT SELECT 1))) UNION DISTINCT SELECT 1)))) UNION ALL SELECT 1)))))))); (((((((((((((((SELECT 1 UNION DISTINCT SELECT 1))) UNION DISTINCT SELECT 1)))) UNION ALL SELECT 1))))))));

View File

@ -1,5 +1,5 @@
SELECT * \ SELECT * \
FROM \ FROM \
( \ ( \
SELECT 1 AS x \ SELECT 1 AS x \
UNION ALL \ UNION ALL \

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,16 @@
SELECT DISTINCT
eq
FROM
(
WITH
range(2 + number % 10) AS arr, -- minimum two elements, to avoid nan result --
arrayMap(x -> x = intDiv(number, 10) ? nan : x, arr) AS arr_with_nan,
arrayFilter(x -> x != intDiv(number, 10), arr) AS arr_filtered
SELECT
number,
arrayReduce('quantileBFloat16', arr_with_nan) AS q1,
arrayReduce('quantileBFloat16', arr_filtered) AS q2,
q1 = q2 AS eq
FROM
numbers(100)
);

View File

@ -0,0 +1,6 @@
a 5 UInt64
b 8 UInt64
c 3 UInt64
a 1 Float64
a 7201 UInt64
a 7 UInt64

View File

@ -0,0 +1,26 @@
DROP TABLE IF EXISTS segment;
DROP TABLE IF EXISTS fl_segment;
DROP TABLE IF EXISTS dt_segment;
DROP TABLE IF EXISTS date_segment;
CREATE TABLE segment ( `id` String, `start` Int64, `end` Int64 ) ENGINE = MergeTree ORDER BY start;
INSERT INTO segment VALUES ('a', 1, 3), ('a', 1, 3), ('a', 2, 4), ('a', 1, 1), ('a', 5, 6), ('a', 5, 7), ('b', 10, 12), ('b', 13, 19), ('b', 14, 16), ('c', -1, 1), ('c', -2, -1);
CREATE TABLE fl_segment ( `id` String, `start` Float, `end` Float ) ENGINE = MergeTree ORDER BY start;
INSERT INTO fl_segment VALUES ('a', 1.1, 3.2), ('a', 1.5, 3.6), ('a', 4.0, 5.0);
CREATE TABLE dt_segment ( `id` String, `start` DateTime, `end` DateTime ) ENGINE = MergeTree ORDER BY start;
INSERT INTO dt_segment VALUES ('a', '2020-01-01 02:11:22', '2020-01-01 03:12:31'), ('a', '2020-01-01 01:12:30', '2020-01-01 02:50:11');
CREATE TABLE date_segment ( `id` String, `start` Date, `end` Date ) ENGINE = MergeTree ORDER BY start;
INSERT INTO date_segment VALUES ('a', '2020-01-01', '2020-01-04'), ('a', '2020-01-03', '2020-01-08 02:50:11');
SELECT id, segmentLengthSum(start, end), toTypeName(segmentLengthSum(start, end)) FROM segment GROUP BY id ORDER BY id;
SELECT id, 3.4 < segmentLengthSum(start, end) AND segmentLengthSum(start, end) < 3.6, toTypeName(segmentLengthSum(start, end)) FROM fl_segment GROUP BY id ORDER BY id;
SELECT id, segmentLengthSum(start, end), toTypeName(segmentLengthSum(start, end)) FROM dt_segment GROUP BY id ORDER BY id;
SELECT id, segmentLengthSum(start, end), toTypeName(segmentLengthSum(start, end)) FROM date_segment GROUP BY id ORDER BY id;
DROP TABLE segment;
DROP TABLE fl_segment;
DROP TABLE dt_segment;
DROP TABLE date_segment;

View File

@ -0,0 +1,114 @@
# select * from system.one a
SELECT *
FROM system.one AS a
# /* oneline */ select * from system.one a
SELECT * FROM system.one AS a
# select * from (select * from system.one) b, system.one a
SELECT *
FROM
(
SELECT *
FROM system.one
) AS b, system.one AS a
# /* oneline */ select * from (select * from system.one) b, system.one a
SELECT * FROM (SELECT * FROM system.one) AS b, system.one AS a
# select * from system.one a, (select * from system.one) b, system.one c
SELECT *
FROM system.one AS a,
(
SELECT *
FROM system.one
) AS b, system.one AS c
# /* oneline */ select * from system.one a, (select * from system.one) b, system.one c
SELECT * FROM system.one AS a, (SELECT * FROM system.one) AS b, system.one AS c
# select * from system.one a, (select * from system.one) b, system.one c, (select * from system.one) d
SELECT *
FROM system.one AS a,
(
SELECT *
FROM system.one
) AS b, system.one AS c,
(
SELECT *
FROM system.one
) AS d
# /* oneline */ select * from system.one a, (select * from system.one) b, system.one c, (select * from system.one) d
SELECT * FROM system.one AS a, (SELECT * FROM system.one) AS b, system.one AS c, (SELECT * FROM system.one) AS d
# select * from system.one union all select * from system.one
SELECT *
FROM system.one
UNION ALL
SELECT *
FROM system.one
# /* oneline */ select * from system.one union all select * from system.one
SELECT * FROM system.one UNION ALL SELECT * FROM system.one
# select * from system.one union all (select * from system.one)
SELECT *
FROM system.one
UNION ALL
SELECT *
FROM system.one
# /* oneline */ select * from system.one union all (select * from system.one)
SELECT * FROM system.one UNION ALL SELECT * FROM system.one
# select 1 union all (select 1 union distinct select 1)
SELECT 1
UNION ALL
(
SELECT 1
UNION DISTINCT
SELECT 1
)
# /* oneline */ select 1 union all (select 1 union distinct select 1)
SELECT 1 UNION ALL (SELECT 1 UNION DISTINCT SELECT 1)
# select * from system.one array join arr as row
SELECT *
FROM system.one
ARRAY JOIN arr AS row
# /* oneline */ select * from system.one array join arr as row
SELECT * FROM system.one ARRAY JOIN arr AS row
# select 1 in 1
SELECT 1 IN (1)
# /* oneline */ select 1 in 1
SELECT 1 IN (1)
# select 1 in (select 1)
SELECT 1 IN (
SELECT 1
)
# /* oneline */ select 1 in (select 1)
SELECT 1 IN (SELECT 1)
# select 1 in f(1)
SELECT 1 IN f(1)
# /* oneline */ select 1 in f(1)
SELECT 1 IN f(1)
# select 1 in ((select 1) as sub)
SELECT 1 IN ((
SELECT 1
) AS sub)
# /* oneline */ select 1 in ((select 1) as sub)
SELECT 1 IN ((SELECT 1) AS sub)
# with it as ( select * from numbers(1) ) select it.number, i.number from it as i
WITH it AS
(
SELECT *
FROM numbers(1)
)
SELECT
it.number,
i.number
FROM it AS i
# /* oneline */ with it as ( select * from numbers(1) ) select it.number, i.number from it as i
WITH it AS (SELECT * FROM numbers(1)) SELECT it.number, i.number FROM it AS i
# SELECT x FROM ( SELECT 1 AS x UNION ALL ( SELECT 1 UNION ALL SELECT 1))
SELECT x
FROM
(
SELECT 1 AS x
UNION ALL
(
SELECT 1
UNION ALL
SELECT 1
)
)
# /* oneline */ SELECT x FROM ( SELECT 1 AS x UNION ALL ( SELECT 1 UNION ALL SELECT 1))
SELECT x FROM (SELECT 1 AS x UNION ALL (SELECT 1 UNION ALL SELECT 1))

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
set -e
queries=(
"select * from system.one a"
"select * from (select * from system.one) b, system.one a"
"select * from system.one a, (select * from system.one) b, system.one c"
"select * from system.one a, (select * from system.one) b, system.one c, (select * from system.one) d"
"select * from system.one union all select * from system.one"
"select * from system.one union all (select * from system.one)"
"select 1 union all (select 1 union distinct select 1)"
"select * from system.one array join arr as row"
"select 1 in 1"
"select 1 in (select 1)"
"select 1 in f(1)"
"select 1 in ((select 1) as sub)"
"with it as ( select * from numbers(1) ) select it.number, i.number from it as i"
"SELECT x FROM ( SELECT 1 AS x UNION ALL ( SELECT 1 UNION ALL SELECT 1))"
)
for q in "${queries[@]}"; do
echo "# $q"
$CLICKHOUSE_FORMAT <<<"$q"
echo "# /* oneline */ $q"
$CLICKHOUSE_FORMAT --oneline <<<"$q"
done

View File

@ -0,0 +1,40 @@
1704509 1384
732797 1336
598875 1384
792887 1336
3807842 1336
25703952 1336
716829 1384
59183 1336
33010362 1336
800784 1336
1704509 [1296,1384,1840,1960,3696]
732797 [1232,1336,1840,1944,3664]
598875 [1232,1384,1840,1944,3536]
792887 [1296,1336,1840,1888,3696]
3807842 [1232,1336,1840,1936,2032]
25703952 [1012,1336,1840,1944,3696]
716829 [1232,1384,1840,1944,3696]
59183 [316,1336,1840,2008,2032]
33010362 [1232,1336,1840,1936,2032]
800784 [1232,1336,1840,1928,2032]
1704509 1384
732797 1336
598875 1384
792887 1336
3807842 1336
25703952 1336
716829 1384
59183 1336
33010362 1336
800784 1336
1704509 [1296,1384,1840,1960,3696]
732797 [1232,1336,1840,1944,3664]
598875 [1232,1384,1840,1944,3536]
792887 [1296,1336,1840,1888,3696]
3807842 [1232,1336,1840,1936,2032]
25703952 [1012,1336,1840,1944,3696]
716829 [1232,1384,1840,1944,3696]
59183 [316,1336,1840,2008,2032]
33010362 [1232,1336,1840,1936,2032]
800784 [1232,1336,1840,1928,2032]

View File

@ -0,0 +1,6 @@
SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;
SELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;
SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;
SELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10;