Commit forgotten files

This commit is contained in:
kssenii 2022-11-20 19:28:11 +01:00
parent 08e4805c99
commit 93365b0b29
5 changed files with 141 additions and 8 deletions

View File

@ -5,11 +5,6 @@
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
namespace
{
SettingChange * find(SettingsChanges & changes, std::string_view name)

View File

@ -1,8 +1,5 @@
#pragma once
#include <Core/Field.h>
#include <Parsers/IAST.h>
#include <Common/FieldVisitorToString.h>
namespace DB

View File

@ -0,0 +1,74 @@
#include <Disks/getOrCreateDiskFromAST.h>
#include <Common/logger_useful.h>
#include <Common/assert_cast.h>
#include <Common/filesystemHelpers.h>
#include <Disks/getDiskConfigurationFromAST.h>
#include <Disks/DiskSelector.h>
#include <Parsers/formatAST.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTFunction.h>
#include <Interpreters/Context.h>
namespace DB
{
namespace ErrorCodes
{
extern const int BAD_ARGUMENTS;
}
bool isDiskFunction(ASTPtr ast)
{
if (!ast)
return false;
const auto * function = ast->as<ASTFunction>();
return function && function->name == "disk" && function->arguments->as<ASTExpressionList>();
}
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<const ASTExpressionList *>(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;
}
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <string>
#include <Interpreters/Context_fwd.h>
#include <Parsers/IAST_fwd.h>
namespace DB
{
class ASTFunction;
/**
* Create a DiskPtr from disk AST function like disk(<disk_configuration>),
* 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(<disk_configuration>) function.
*/
bool isDiskFunction(ASTPtr ast);
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <Parsers/formatAST.h>
#include <Common/SettingsChanges.h>
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> 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); }
};
}