From 93365b0b290bd959e17d5f1bfb706f6098873527 Mon Sep 17 00:00:00 2001 From: kssenii Date: Sun, 20 Nov 2022 19:28:11 +0100 Subject: [PATCH] Commit forgotten files --- src/Common/SettingsChanges.cpp | 5 -- src/Common/SettingsChanges.h | 3 -- src/Disks/getOrCreateDiskFromAST.cpp | 74 ++++++++++++++++++++++++++++ src/Disks/getOrCreateDiskFromAST.h | 23 +++++++++ src/Parsers/SettingValueFromAST.h | 44 +++++++++++++++++ 5 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 src/Disks/getOrCreateDiskFromAST.cpp create mode 100644 src/Disks/getOrCreateDiskFromAST.h create mode 100644 src/Parsers/SettingValueFromAST.h diff --git a/src/Common/SettingsChanges.cpp b/src/Common/SettingsChanges.cpp index d9c18122119..188947e3f45 100644 --- a/src/Common/SettingsChanges.cpp +++ b/src/Common/SettingsChanges.cpp @@ -5,11 +5,6 @@ namespace DB { -namespace ErrorCodes -{ - extern const int LOGICAL_ERROR; -} - namespace { SettingChange * find(SettingsChanges & changes, std::string_view name) diff --git a/src/Common/SettingsChanges.h b/src/Common/SettingsChanges.h index 57ccfe46b95..01856e9edad 100644 --- a/src/Common/SettingsChanges.h +++ b/src/Common/SettingsChanges.h @@ -1,8 +1,5 @@ #pragma once - #include -#include -#include namespace DB diff --git a/src/Disks/getOrCreateDiskFromAST.cpp b/src/Disks/getOrCreateDiskFromAST.cpp new file mode 100644 index 00000000000..48d40864396 --- /dev/null +++ b/src/Disks/getOrCreateDiskFromAST.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int BAD_ARGUMENTS; +} + +bool isDiskFunction(ASTPtr ast) +{ + if (!ast) + return false; + + const auto * function = ast->as(); + return function && function->name == "disk" && function->arguments->as(); +} + +std::string getOrCreateDiskFromDiskAST(const ASTFunction & function, ContextPtr context) +{ + /// We need a unique name for a created custom disk, but it needs to be the same + /// after table is reattached or server is restarted, so take a hash of the disk + /// configuration serialized ast as a disk name suffix. + auto disk_setting_string = serializeAST(function, true); + auto disk_name = DiskSelector::TMP_DISK_PREFIX + + toString(sipHash128(disk_setting_string.data(), disk_setting_string.size())); + + LOG_TRACE( + &Poco::Logger::get("getOrCreateDiskFromDiskAST"), + "Using disk name `{}` for custom disk {}", + disk_name, disk_setting_string); + + auto result_disk = context->getOrCreateDisk(disk_name, [&](const DisksMap & disks_map) -> DiskPtr { + const auto * function_args_expr = assert_cast(function.arguments.get()); + const auto & function_args = function_args_expr->children; + auto config = getDiskConfigurationFromAST(disk_name, function_args, context); + auto disk = DiskFactory::instance().create(disk_name, *config, disk_name, context, disks_map); + /// Mark that disk can be used without storage policy. + disk->markDiskAsCustom(); + return disk; + }); + + if (!result_disk->isRemote()) + { + static constexpr auto custom_disks_base_dir_in_config = "custom_local_disks_base_directory"; + auto disk_path_expected_prefix = context->getConfigRef().getString(custom_disks_base_dir_in_config, ""); + + if (disk_path_expected_prefix.empty()) + throw Exception( + ErrorCodes::BAD_ARGUMENTS, + "Base path for custom local disks must be defined in config file by `{}`", + custom_disks_base_dir_in_config); + + if (!pathStartsWith(result_disk->getPath(), disk_path_expected_prefix)) + throw Exception( + ErrorCodes::BAD_ARGUMENTS, + "Path of the custom local disk must be inside `{}` directory", + disk_path_expected_prefix); + } + + return disk_name; +} + +} diff --git a/src/Disks/getOrCreateDiskFromAST.h b/src/Disks/getOrCreateDiskFromAST.h new file mode 100644 index 00000000000..c1d4bda1a49 --- /dev/null +++ b/src/Disks/getOrCreateDiskFromAST.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include + +namespace DB +{ + +class ASTFunction; + +/** + * Create a DiskPtr from disk AST function like disk(), + * add it to DiskSelector by a unique (but always the same for given configuration) disk name + * and return this name. + */ +std::string getOrCreateDiskFromDiskAST(const ASTFunction & function, ContextPtr context); + +/* + * Is given ast has form of a disk() function. + */ +bool isDiskFunction(ASTPtr ast); + +} diff --git a/src/Parsers/SettingValueFromAST.h b/src/Parsers/SettingValueFromAST.h new file mode 100644 index 00000000000..5c0ed4c248f --- /dev/null +++ b/src/Parsers/SettingValueFromAST.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int CANNOT_GET_SETTING_VALUE; +} + +struct SettingValueFromAST : SettingValue +{ + explicit SettingValueFromAST(const ASTPtr & value_) : value(value_) {} + + ASTPtr value; + std::optional field; + + [[noreturn]] void throwNoValue() const + { + throw Exception( + ErrorCodes::CANNOT_GET_SETTING_VALUE, + "Cannot get setting value, it must be converted from AST to Field first"); + } + + const Field & getField() const override + { + if (field) + return *field; + throwNoValue(); + } + + Field & getField() override + { + if (field) + return *field; + throwNoValue(); + } + void setField(const Field & field_) { field = field_; } + std::string toString() const override { return serializeAST(*value); } +}; + +}