mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
Merge pull request #39974 from ClickHouse/vdimir/setting-num-with-auto
Add setting type to support special 'auto' value
This commit is contained in:
commit
1b44cb5c97
@ -212,7 +212,7 @@ static constexpr UInt64 operator""_GiB(unsigned long long value)
|
||||
\
|
||||
M(Bool, insert_deduplicate, true, "For INSERT queries in the replicated table, specifies that deduplication of insertings blocks should be performed", 0) \
|
||||
\
|
||||
M(UInt64, insert_quorum, 0, "For INSERT queries in the replicated table, wait writing for the specified number of replicas and linearize the addition of the data. 0 - disabled.", 0) \
|
||||
M(UInt64Auto, insert_quorum, 0, "For INSERT queries in the replicated table, wait writing for the specified number of replicas and linearize the addition of the data. 0 - disabled.", 0) \
|
||||
M(Milliseconds, insert_quorum_timeout, 600000, "", 0) \
|
||||
M(Bool, insert_quorum_parallel, true, "For quorum INSERT queries - enable to make parallel inserts without linearizability", 0) \
|
||||
M(UInt64, select_sequential_consistency, 0, "For SELECT queries from the replicated table, throw an exception if the replica does not have a chunk written with the quorum; do not read the parts that have not yet been written with the quorum.", 0) \
|
||||
|
@ -153,6 +153,9 @@ template struct SettingFieldNumber<Int64>;
|
||||
template struct SettingFieldNumber<float>;
|
||||
template struct SettingFieldNumber<bool>;
|
||||
|
||||
template struct SettingAutoWrapper<SettingFieldNumber<UInt64>>;
|
||||
template struct SettingAutoWrapper<SettingFieldNumber<Int64>>;
|
||||
template struct SettingAutoWrapper<SettingFieldNumber<float>>;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -58,11 +58,82 @@ using SettingFieldInt64 = SettingFieldNumber<Int64>;
|
||||
using SettingFieldFloat = SettingFieldNumber<float>;
|
||||
using SettingFieldBool = SettingFieldNumber<bool>;
|
||||
|
||||
|
||||
/** Unlike SettingFieldUInt64, supports the value of 'auto' - the number of processor cores without taking into account SMT.
|
||||
* A value of 0 is also treated as auto.
|
||||
* When serializing, `auto` is written in the same way as 0.
|
||||
/** Wraps any SettingField to support special value 'auto' that can be checked with `is_auto` flag.
|
||||
* Note about serialization:
|
||||
* The new versions with `SettingsWriteFormat::STRINGS_WITH_FLAGS` serialize values as a string.
|
||||
* In legacy SettingsWriteFormat mode, functions `read/writeBinary` would serialize values as a binary, and 'is_auto' would be ignored.
|
||||
* It's possible to upgrade settings from regular type to wrapped ones and keep compatibility with old versions,
|
||||
* but when serializing 'auto' old version will see binary representation of the default value.
|
||||
*/
|
||||
template <typename Base>
|
||||
struct SettingAutoWrapper
|
||||
{
|
||||
constexpr static auto keyword = "auto";
|
||||
static bool isAuto(const Field & f) { return f.getType() == Field::Types::String && f.safeGet<const String &>() == keyword; }
|
||||
static bool isAuto(const String & str) { return str == keyword; }
|
||||
|
||||
using Type = typename Base::Type;
|
||||
|
||||
Base base;
|
||||
bool is_auto = false;
|
||||
bool changed = false;
|
||||
|
||||
explicit SettingAutoWrapper() : is_auto(true) {}
|
||||
explicit SettingAutoWrapper(Type val) : is_auto(false) { base = Base(val); }
|
||||
|
||||
explicit SettingAutoWrapper(const Field & f)
|
||||
: is_auto(isAuto(f))
|
||||
{
|
||||
if (!is_auto)
|
||||
base = Base(f);
|
||||
}
|
||||
|
||||
SettingAutoWrapper & operator=(const Field & f)
|
||||
{
|
||||
changed = true;
|
||||
if (is_auto = isAuto(f); !is_auto)
|
||||
base = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator Field() const { return is_auto ? Field(keyword) : Field(base); }
|
||||
|
||||
String toString() const { return is_auto ? keyword : base.toString(); }
|
||||
|
||||
void parseFromString(const String & str)
|
||||
{
|
||||
changed = true;
|
||||
if (is_auto = isAuto(str); !is_auto)
|
||||
base.parseFromString(str);
|
||||
}
|
||||
|
||||
void writeBinary(WriteBuffer & out) const
|
||||
{
|
||||
if (is_auto)
|
||||
Base().writeBinary(out); /// serialize default value
|
||||
else
|
||||
base.writeBinary(out);
|
||||
}
|
||||
|
||||
/*
|
||||
* That it is fine to reset `is_auto` here and to use default value in case `is_auto`
|
||||
* because settings will be serialized only if changed.
|
||||
* If they were changed they were requested to use explicit value instead of `auto`.
|
||||
* And so interactions between client-server, and server-server (distributed queries), should be OK.
|
||||
*/
|
||||
void readBinary(ReadBuffer & in) { changed = true; is_auto = false; base.readBinary(in); }
|
||||
|
||||
Type valueOr(Type default_value) const { return is_auto ? default_value : base.value; }
|
||||
};
|
||||
|
||||
using SettingFieldUInt64Auto = SettingAutoWrapper<SettingFieldUInt64>;
|
||||
using SettingFieldInt64Auto = SettingAutoWrapper<SettingFieldInt64>;
|
||||
using SettingFieldFloatAuto = SettingAutoWrapper<SettingFieldFloat>;
|
||||
|
||||
/* Similar to SettingFieldUInt64Auto with small differences to behave like regular UInt64, supported to compatibility.
|
||||
* When setting to 'auto' it becomes equal to the number of processor cores without taking into account SMT.
|
||||
* A value of 0 is also treated as 'auto', so 'auto' is parsed and serialized in the same way as 0.
|
||||
*/
|
||||
struct SettingFieldMaxThreads
|
||||
{
|
||||
bool is_auto;
|
||||
|
@ -4443,8 +4443,9 @@ SinkToStoragePtr StorageReplicatedMergeTree::write(const ASTPtr & /*query*/, con
|
||||
bool deduplicate = storage_settings_ptr->replicated_deduplication_window != 0 && query_settings.insert_deduplicate;
|
||||
|
||||
// TODO: should we also somehow pass list of columns to deduplicate on to the ReplicatedMergeTreeSink?
|
||||
// TODO: insert_quorum = 'auto' would be supported in https://github.com/ClickHouse/ClickHouse/pull/39970, now it's same as 0.
|
||||
return std::make_shared<ReplicatedMergeTreeSink>(
|
||||
*this, metadata_snapshot, query_settings.insert_quorum,
|
||||
*this, metadata_snapshot, query_settings.insert_quorum.valueOr(0),
|
||||
query_settings.insert_quorum_timeout.totalMilliseconds(),
|
||||
query_settings.max_partitions_per_insert_block,
|
||||
query_settings.insert_quorum_parallel,
|
||||
|
@ -0,0 +1,4 @@
|
||||
0 0 UInt64Auto
|
||||
auto 1 UInt64Auto
|
||||
0 1 UInt64Auto
|
||||
1 1 UInt64Auto
|
10
tests/queries/0_stateless/02381_setting_value_auto.sql
Normal file
10
tests/queries/0_stateless/02381_setting_value_auto.sql
Normal file
@ -0,0 +1,10 @@
|
||||
SELECT value, changed, type FROM system.settings WHERE name = 'insert_quorum';
|
||||
|
||||
SET insert_quorum = 'auto';
|
||||
SELECT value, changed, type FROM system.settings WHERE name = 'insert_quorum';
|
||||
|
||||
SET insert_quorum = 0;
|
||||
SELECT value, changed, type FROM system.settings WHERE name = 'insert_quorum';
|
||||
|
||||
SET insert_quorum = 1;
|
||||
SELECT value, changed, type FROM system.settings WHERE name = 'insert_quorum';
|
Loading…
Reference in New Issue
Block a user