Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions src/main/settings.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "main/settings.h"

#include <limits>

#include "common/assert.h"
#include "common/exception/runtime.h"
#include "common/string_utils.h"
Expand Down Expand Up @@ -34,11 +36,30 @@ void setDefaultHashIndexEnabledOnStorageManagers(ClientContext* context, bool en
}
}

// The INT64 settings below are stored unsigned; a value that doesn't fit would wrap.
template<typename T>
T toUnsignedSetting(const char* name, const common::Value& parameter) {
const auto value = parameter.getValue<int64_t>();
if (value < 0) {
throw common::RuntimeException(std::format("{} must be >= 0, got {}.", name, value));
}
if constexpr (sizeof(T) < sizeof(int64_t)) {
if (static_cast<uint64_t>(value) > std::numeric_limits<T>::max()) {
throw common::RuntimeException(std::format("{} must be <= {}, got {}.", name,
std::numeric_limits<T>::max(), value));
}
}
return static_cast<T>(value);
}

} // namespace

void ThreadsSetting::setContext(ClientContext* context, const common::Value& parameter) {
parameter.validateType(inputType);
context->getClientConfigUnsafe()->numThreads = parameter.getValue<uint64_t>();
// 0 means the database's thread count, as in ClientContext::setMaxNumThreadForExec.
const auto numThreads = parameter.getValue<uint64_t>();
context->getClientConfigUnsafe()->numThreads =
numThreads == 0 ? context->getDBConfig()->maxNumThreads : numThreads;
}

common::Value ThreadsSetting::getSetting(const ClientContext* context) {
Expand Down Expand Up @@ -76,7 +97,8 @@ common::Value ProgressBarSetting::getSetting(const ClientContext* context) {
void VarLengthExtendMaxDepthSetting::setContext(ClientContext* context,
const common::Value& parameter) {
parameter.validateType(inputType);
context->getClientConfigUnsafe()->varLengthMaxDepth = parameter.getValue<int64_t>();
context->getClientConfigUnsafe()->varLengthMaxDepth =
toUnsignedSetting<uint32_t>(name, parameter);
}

common::Value VarLengthExtendMaxDepthSetting::getSetting(const ClientContext* context) {
Expand All @@ -86,7 +108,8 @@ common::Value VarLengthExtendMaxDepthSetting::getSetting(const ClientContext* co
void SparseFrontierThresholdSetting::setContext(ClientContext* context,
const common::Value& parameter) {
parameter.validateType(inputType);
context->getClientConfigUnsafe()->sparseFrontierThreshold = parameter.getValue<int64_t>();
context->getClientConfigUnsafe()->sparseFrontierThreshold =
toUnsignedSetting<uint64_t>(name, parameter);
}

common::Value SparseFrontierThresholdSetting::getSetting(const ClientContext* context) {
Expand Down Expand Up @@ -156,7 +179,7 @@ void RecursivePatternFactorSetting::setContext(ClientContext* context,
const common::Value& parameter) {
parameter.validateType(inputType);
context->getClientConfigUnsafe()->recursivePatternCardinalityScaleFactor =
parameter.getValue<std::int64_t>();
toUnsignedSetting<uint32_t>(name, parameter);
}

common::Value RecursivePatternFactorSetting::getSetting(const ClientContext* context) {
Expand All @@ -177,7 +200,8 @@ common::Value EnableMVCCSetting::getSetting(const ClientContext* context) {
void CheckpointThresholdSetting::setContext(ClientContext* context,
const common::Value& parameter) {
parameter.validateType(inputType);
context->getDBConfigUnsafe()->checkpointThreshold = parameter.getValue<int64_t>();
context->getDBConfigUnsafe()->checkpointThreshold =
toUnsignedSetting<uint64_t>(name, parameter);
}

common::Value CheckpointThresholdSetting::getSetting(const ClientContext* context) {
Expand Down
38 changes: 38 additions & 0 deletions test/test_files/function/call/setting_ranges.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-DATASET CSV empty

--

-CASE ThreadsZeroUsesDatabaseThreadCount
-LOG threads=0 means the database's thread count, as Connection::setMaxNumThreadForExec(0) does
-STATEMENT CALL threads=0
---- ok
-STATEMENT UNWIND range(1, 100000) AS x RETURN sum(x)
---- 1
5000050000

-CASE UnsignedSettingsRejectValuesThatWrap
-STATEMENT CALL checkpoint_threshold=-1
---- error
Runtime exception: checkpoint_threshold must be >= 0, got -1.
-STATEMENT CALL sparse_frontier_threshold=-1
---- error
Runtime exception: sparse_frontier_threshold must be >= 0, got -1.
-STATEMENT CALL var_length_extend_max_depth=-1
---- error
Runtime exception: var_length_extend_max_depth must be >= 0, got -1.
-STATEMENT CALL var_length_extend_max_depth=4294967296
---- error
Runtime exception: var_length_extend_max_depth must be <= 4294967295, got 4294967296.
-STATEMENT CALL recursive_pattern_factor=-5
---- error
Runtime exception: recursive_pattern_factor must be >= 0, got -5.
-STATEMENT CALL var_length_extend_max_depth=7
---- ok
-STATEMENT CALL current_setting('var_length_extend_max_depth') RETURN *
---- 1
7
-STATEMENT CALL checkpoint_threshold=0
---- ok
-STATEMENT CALL current_setting('checkpoint_threshold') RETURN *
---- 1
0
Loading