mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Merge 130a1c52a2
into 44b4bd38b9
This commit is contained in:
commit
2678f62717
@ -1187,6 +1187,22 @@ namespace
|
|||||||
source_ast->children.push_back(source_ast->elements);
|
source_ast->children.push_back(source_ast->elements);
|
||||||
dict.set(dict.source, source_ast);
|
dict.set(dict.source, source_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTs * getEngineArgsFromCreateQuery(ASTCreateQuery & create_query)
|
||||||
|
{
|
||||||
|
ASTStorage * storage_def = create_query.storage;
|
||||||
|
if (!storage_def)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!storage_def->engine)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const ASTFunction & engine_def = *storage_def->engine;
|
||||||
|
if (!engine_def.arguments)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &engine_def.arguments->children;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterCreateQuery::setEngine(ASTCreateQuery & create) const
|
void InterpreterCreateQuery::setEngine(ASTCreateQuery & create) const
|
||||||
@ -1876,7 +1892,11 @@ bool InterpreterCreateQuery::doCreateTable(ASTCreateQuery & create,
|
|||||||
mode);
|
mode);
|
||||||
|
|
||||||
/// If schema wes inferred while storage creation, add columns description to create query.
|
/// If schema wes inferred while storage creation, add columns description to create query.
|
||||||
addColumnsDescriptionToCreateQueryIfNecessary(query_ptr->as<ASTCreateQuery &>(), res);
|
auto & create_query = query_ptr->as<ASTCreateQuery &>();
|
||||||
|
addColumnsDescriptionToCreateQueryIfNecessary(create_query, res);
|
||||||
|
/// Add any inferred engine args if needed. For example, data format for engines File/S3/URL/etc
|
||||||
|
if (auto * engine_args = getEngineArgsFromCreateQuery(create_query))
|
||||||
|
res->addInferredEngineArgsToCreateQuery(*engine_args, getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
validateVirtualColumns(*res);
|
validateVirtualColumns(*res);
|
||||||
|
@ -284,6 +284,10 @@ public:
|
|||||||
/// Returns hints for serialization of columns accorsing to statistics accumulated by storage.
|
/// Returns hints for serialization of columns accorsing to statistics accumulated by storage.
|
||||||
virtual SerializationInfoByName getSerializationHints() const { return {}; }
|
virtual SerializationInfoByName getSerializationHints() const { return {}; }
|
||||||
|
|
||||||
|
/// Add engine args that were inferred during storage creation to create query to avoid the same
|
||||||
|
/// inference on server restart. For example - data format inference in File/URL/S3/etc engines.
|
||||||
|
virtual void addInferredEngineArgsToCreateQuery(ASTs & /*args*/, const ContextPtr & /*context*/) const {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageID storage_id;
|
StorageID storage_id;
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ void StorageAzureConfiguration::fromAST(ASTs & engine_args, ContextPtr context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
||||||
ASTs & args, const String & structure_, const String & format_, ContextPtr context)
|
ASTs & args, const String & structure_, const String & format_, ContextPtr context, bool with_structure)
|
||||||
{
|
{
|
||||||
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
||||||
{
|
{
|
||||||
@ -295,7 +295,7 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
||||||
args.push_back(format_equal_func);
|
args.push_back(format_equal_func);
|
||||||
}
|
}
|
||||||
if (collection->getOrDefault<String>("structure", "auto") == "auto")
|
if (with_structure && collection->getOrDefault<String>("structure", "auto") == "auto")
|
||||||
{
|
{
|
||||||
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
||||||
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
||||||
@ -319,10 +319,13 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
if (args.size() == 3)
|
if (args.size() == 3)
|
||||||
{
|
{
|
||||||
args.push_back(format_literal);
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
|
{
|
||||||
/// Add compression = "auto" before structure argument.
|
/// Add compression = "auto" before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// (connection_string, container_name, blobpath, structure) or
|
/// (connection_string, container_name, blobpath, structure) or
|
||||||
/// (connection_string, container_name, blobpath, format)
|
/// (connection_string, container_name, blobpath, format)
|
||||||
/// We can distinguish them by looking at the 4-th argument: check if it's format name or not.
|
/// We can distinguish them by looking at the 4-th argument: check if it's format name or not.
|
||||||
@ -334,12 +337,15 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (fourth_arg == "auto")
|
if (fourth_arg == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
|
{
|
||||||
/// Add compression=auto before structure argument.
|
/// Add compression=auto before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// (..., structure) -> (..., format, compression, structure)
|
/// (..., structure) -> (..., format, compression, structure)
|
||||||
else
|
else if (with_structure)
|
||||||
{
|
{
|
||||||
auto structure_arg = args.back();
|
auto structure_arg = args.back();
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
@ -362,17 +368,21 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (fourth_arg == "auto")
|
if (fourth_arg == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// (..., account_name, account_key) -> (..., account_name, account_key, format, compression, structure)
|
/// (..., account_name, account_key) -> (..., account_name, account_key, format, compression, structure)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args.push_back(format_literal);
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
|
{
|
||||||
/// Add compression=auto before structure argument.
|
/// Add compression=auto before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// (connection_string, container_name, blobpath, format, compression, structure) or
|
/// (connection_string, container_name, blobpath, format, compression, structure) or
|
||||||
/// (storage_account_url, container_name, blobpath, account_name, account_key, structure) or
|
/// (storage_account_url, container_name, blobpath, account_name, account_key, structure) or
|
||||||
/// (storage_account_url, container_name, blobpath, account_name, account_key, format)
|
/// (storage_account_url, container_name, blobpath, account_name, account_key, format)
|
||||||
@ -386,7 +396,7 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (fourth_arg == "auto")
|
if (fourth_arg == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[5], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[5], "structure") == "auto")
|
||||||
args[5] = structure_literal;
|
args[5] = structure_literal;
|
||||||
}
|
}
|
||||||
/// (..., account_name, account_key, format) -> (..., account_name, account_key, format, compression, structure)
|
/// (..., account_name, account_key, format) -> (..., account_name, account_key, format, compression, structure)
|
||||||
@ -394,12 +404,15 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (sixth_arg == "auto")
|
if (sixth_arg == "auto")
|
||||||
args[5] = format_literal;
|
args[5] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
|
{
|
||||||
/// Add compression=auto before structure argument.
|
/// Add compression=auto before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// (..., account_name, account_key, structure) -> (..., account_name, account_key, format, compression, structure)
|
/// (..., account_name, account_key, structure) -> (..., account_name, account_key, format, compression, structure)
|
||||||
else
|
else if (with_structure)
|
||||||
{
|
{
|
||||||
auto structure_arg = args.back();
|
auto structure_arg = args.back();
|
||||||
args[5] = format_literal;
|
args[5] = format_literal;
|
||||||
@ -417,6 +430,7 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
/// (..., format, compression) -> (..., format, compression, structure)
|
/// (..., format, compression) -> (..., format, compression, structure)
|
||||||
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
||||||
args[5] = format_literal;
|
args[5] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// (storage_account_url, container_name, blobpath, account_name, account_key, format, compression, structure)
|
/// (storage_account_url, container_name, blobpath, account_name, account_key, format, compression, structure)
|
||||||
@ -424,7 +438,7 @@ void StorageAzureConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
||||||
args[5] = format_literal;
|
args[5] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[7], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[7], "structure") == "auto")
|
||||||
args[7] = structure_literal;
|
args[7] = structure_literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,8 @@ public:
|
|||||||
ASTs & args,
|
ASTs & args,
|
||||||
const String & structure_,
|
const String & structure_,
|
||||||
const String & format_,
|
const String & format_,
|
||||||
ContextPtr context) override;
|
ContextPtr context,
|
||||||
|
bool with_structure) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
||||||
|
@ -175,7 +175,8 @@ void StorageHDFSConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
ASTs & args,
|
ASTs & args,
|
||||||
const String & structure_,
|
const String & structure_,
|
||||||
const String & format_,
|
const String & format_,
|
||||||
ContextPtr context)
|
ContextPtr context,
|
||||||
|
bool with_structure)
|
||||||
{
|
{
|
||||||
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
||||||
{
|
{
|
||||||
@ -187,7 +188,7 @@ void StorageHDFSConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
||||||
args.push_back(format_equal_func);
|
args.push_back(format_equal_func);
|
||||||
}
|
}
|
||||||
if (collection->getOrDefault<String>("structure", "auto") == "auto")
|
if (with_structure && collection->getOrDefault<String>("structure", "auto") == "auto")
|
||||||
{
|
{
|
||||||
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
||||||
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
||||||
@ -210,7 +211,8 @@ void StorageHDFSConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
/// Add format=auto before structure argument.
|
/// Add format=auto before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// hdfs(url, format)
|
/// hdfs(url, format)
|
||||||
@ -218,15 +220,17 @@ void StorageHDFSConfiguration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
||||||
args.back() = format_literal;
|
args.back() = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// hdfs(url, format, structure)
|
/// hdfs(url, format, structure)
|
||||||
/// hdfs(url, format, structure, compression_method)
|
/// hdfs(url, format, structure, compression_method)
|
||||||
|
/// hdfs(url, format, compression_method)
|
||||||
else if (count >= 3)
|
else if (count >= 3)
|
||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
||||||
args[1] = format_literal;
|
args[1] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
||||||
args[2] = structure_literal;
|
args[2] = structure_literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,8 @@ public:
|
|||||||
ASTs & args,
|
ASTs & args,
|
||||||
const String & structure_,
|
const String & structure_,
|
||||||
const String & format_,
|
const String & format_,
|
||||||
ContextPtr context) override;
|
ContextPtr context,
|
||||||
|
bool with_structure) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fromNamedCollection(const NamedCollection &, ContextPtr context) override;
|
void fromNamedCollection(const NamedCollection &, ContextPtr context) override;
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
ObjectStoragePtr createObjectStorage(ContextPtr, bool) override { return std::make_shared<LocalObjectStorage>("/"); }
|
ObjectStoragePtr createObjectStorage(ContextPtr, bool) override { return std::make_shared<LocalObjectStorage>("/"); }
|
||||||
|
|
||||||
void addStructureAndFormatToArgsIfNeeded(ASTs &, const String &, const String &, ContextPtr) override { }
|
void addStructureAndFormatToArgsIfNeeded(ASTs &, const String &, const String &, ContextPtr, bool) override { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
||||||
|
@ -395,7 +395,7 @@ void StorageS3Configuration::fromAST(ASTs & args, ContextPtr context, bool with_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
||||||
ASTs & args, const String & structure_, const String & format_, ContextPtr context)
|
ASTs & args, const String & structure_, const String & format_, ContextPtr context, bool with_structure)
|
||||||
{
|
{
|
||||||
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
||||||
{
|
{
|
||||||
@ -407,7 +407,7 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
||||||
args.push_back(format_equal_func);
|
args.push_back(format_equal_func);
|
||||||
}
|
}
|
||||||
if (collection->getOrDefault<String>("structure", "auto") == "auto")
|
if (with_structure && collection->getOrDefault<String>("structure", "auto") == "auto")
|
||||||
{
|
{
|
||||||
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
||||||
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
||||||
@ -429,7 +429,8 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
/// Add format=auto before structure argument.
|
/// Add format=auto before structure argument.
|
||||||
args.push_back(std::make_shared<ASTLiteral>("auto"));
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// s3(s3_url, format) or
|
/// s3(s3_url, format) or
|
||||||
@ -444,11 +445,13 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
else if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
else if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
||||||
args[1] = format_literal;
|
args[1] = format_literal;
|
||||||
|
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// s3(source, format, structure) or
|
/// s3(source, format, structure) or
|
||||||
/// s3(source, access_key_id, secret_access_key) or
|
/// s3(source, access_key_id, secret_access_key) or
|
||||||
/// s3(source, NOSIGN, format)
|
/// s3(source, NOSIGN, format) or
|
||||||
|
/// s3(source, format, compression_method)
|
||||||
/// We can distinguish them by looking at the 2-nd argument: check if it's NOSIGN, format name or neither.
|
/// We can distinguish them by looking at the 2-nd argument: check if it's NOSIGN, format name or neither.
|
||||||
else if (count == 3)
|
else if (count == 3)
|
||||||
{
|
{
|
||||||
@ -457,26 +460,29 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
||||||
args[2] = format_literal;
|
args[2] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
else if (second_arg == "auto" || FormatFactory::instance().exists(second_arg))
|
else if (second_arg == "auto" || FormatFactory::instance().exists(second_arg))
|
||||||
{
|
{
|
||||||
if (second_arg == "auto")
|
if (second_arg == "auto")
|
||||||
args[1] = format_literal;
|
args[1] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
||||||
args[2] = structure_literal;
|
args[2] = structure_literal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/// Add format and structure arguments.
|
/// Add format and structure arguments.
|
||||||
args.push_back(format_literal);
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// s3(source, format, structure, compression_method) or
|
/// s3(source, format, structure, compression_method) or
|
||||||
/// s3(source, access_key_id, secret_access_key, format) or
|
/// s3(source, access_key_id, secret_access_key, format) or
|
||||||
/// s3(source, access_key_id, secret_access_key, session_token) or
|
/// s3(source, access_key_id, secret_access_key, session_token) or
|
||||||
/// s3(source, NOSIGN, format, structure)
|
/// s3(source, NOSIGN, format, structure) or
|
||||||
|
/// s3(source, NOSIGN, format, compression_method)
|
||||||
/// We can distinguish them by looking at the 2-nd argument: check if it's NOSIGN, format name or neither.
|
/// We can distinguish them by looking at the 2-nd argument: check if it's NOSIGN, format name or neither.
|
||||||
else if (count == 4)
|
else if (count == 4)
|
||||||
{
|
{
|
||||||
@ -485,14 +491,14 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
||||||
args[2] = format_literal;
|
args[2] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[3], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[3], "structure") == "auto")
|
||||||
args[3] = structure_literal;
|
args[3] = structure_literal;
|
||||||
}
|
}
|
||||||
else if (second_arg == "auto" || FormatFactory::instance().exists(second_arg))
|
else if (second_arg == "auto" || FormatFactory::instance().exists(second_arg))
|
||||||
{
|
{
|
||||||
if (second_arg == "auto")
|
if (second_arg == "auto")
|
||||||
args[1] = format_literal;
|
args[1] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
||||||
args[2] = structure_literal;
|
args[2] = structure_literal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -502,18 +508,21 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args.push_back(format_literal);
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// s3(source, access_key_id, secret_access_key, format, structure) or
|
/// s3(source, access_key_id, secret_access_key, format, structure) or
|
||||||
/// s3(source, access_key_id, secret_access_key, session_token, format) or
|
/// s3(source, access_key_id, secret_access_key, session_token, format) or
|
||||||
/// s3(source, NOSIGN, format, structure, compression_method)
|
/// s3(source, NOSIGN, format, structure, compression_method) or
|
||||||
|
/// s3(source, access_key_id, secret_access_key, format, compression)
|
||||||
/// We can distinguish them by looking at the 2-nd argument: check if it's a NOSIGN keyword name or not.
|
/// We can distinguish them by looking at the 2-nd argument: check if it's a NOSIGN keyword name or not.
|
||||||
else if (count == 5)
|
else if (count == 5)
|
||||||
{
|
{
|
||||||
@ -522,7 +531,7 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[2], "format") == "auto")
|
||||||
args[2] = format_literal;
|
args[2] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
||||||
args[3] = structure_literal;
|
args[3] = structure_literal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -532,19 +541,21 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[4], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[4], "structure") == "auto")
|
||||||
args[4] = structure_literal;
|
args[4] = structure_literal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
||||||
args[4] = format_literal;
|
args[4] = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// s3(source, access_key_id, secret_access_key, format, structure, compression) or
|
/// s3(source, access_key_id, secret_access_key, format, structure, compression) or
|
||||||
/// s3(source, access_key_id, secret_access_key, session_token, format, structure)
|
/// s3(source, access_key_id, secret_access_key, session_token, format, structure) or
|
||||||
|
/// s3(source, access_key_id, secret_access_key, session_token, format, compression_method)
|
||||||
else if (count == 6)
|
else if (count == 6)
|
||||||
{
|
{
|
||||||
auto fourth_arg = checkAndGetLiteralArgument<String>(args[3], "format/session_token");
|
auto fourth_arg = checkAndGetLiteralArgument<String>(args[3], "format/session_token");
|
||||||
@ -552,14 +563,14 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[3], "format") == "auto")
|
||||||
args[3] = format_literal;
|
args[3] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[4], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[4], "structure") == "auto")
|
||||||
args[4] = structure_literal;
|
args[4] = structure_literal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
||||||
args[4] = format_literal;
|
args[4] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
||||||
args[5] = structure_literal;
|
args[5] = structure_literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,7 +579,7 @@ void StorageS3Configuration::addStructureAndFormatToArgsIfNeeded(
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[4], "format") == "auto")
|
||||||
args[4] = format_literal;
|
args[4] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[5], "format") == "auto")
|
||||||
args[5] = structure_literal;
|
args[5] = structure_literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,8 @@ public:
|
|||||||
ASTs & args,
|
ASTs & args,
|
||||||
const String & structure,
|
const String & structure,
|
||||||
const String & format,
|
const String & format,
|
||||||
ContextPtr context) override;
|
ContextPtr context,
|
||||||
|
bool with_structure) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
void fromNamedCollection(const NamedCollection & collection, ContextPtr context) override;
|
||||||
|
@ -483,6 +483,11 @@ std::pair<ColumnsDescription, std::string> StorageObjectStorage::resolveSchemaAn
|
|||||||
return std::pair(columns, format);
|
return std::pair(columns, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StorageObjectStorage::addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const
|
||||||
|
{
|
||||||
|
configuration->addStructureAndFormatToArgsIfNeeded(args, "", configuration->format, context, /*with_structure=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
SchemaCache & StorageObjectStorage::getSchemaCache(const ContextPtr & context, const std::string & storage_type_name)
|
SchemaCache & StorageObjectStorage::getSchemaCache(const ContextPtr & context, const std::string & storage_type_name)
|
||||||
{
|
{
|
||||||
if (storage_type_name == "s3")
|
if (storage_type_name == "s3")
|
||||||
|
@ -122,6 +122,8 @@ public:
|
|||||||
std::string & sample_path,
|
std::string & sample_path,
|
||||||
const ContextPtr & context);
|
const ContextPtr & context);
|
||||||
|
|
||||||
|
void addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String getPathSample(StorageInMemoryMetadata metadata, ContextPtr context);
|
String getPathSample(StorageInMemoryMetadata metadata, ContextPtr context);
|
||||||
|
|
||||||
@ -179,7 +181,7 @@ public:
|
|||||||
|
|
||||||
/// Add/replace structure and format arguments in the AST arguments if they have 'auto' values.
|
/// Add/replace structure and format arguments in the AST arguments if they have 'auto' values.
|
||||||
virtual void addStructureAndFormatToArgsIfNeeded(
|
virtual void addStructureAndFormatToArgsIfNeeded(
|
||||||
ASTs & args, const String & structure_, const String & format_, ContextPtr context) = 0;
|
ASTs & args, const String & structure_, const String & format_, ContextPtr context, bool with_structure) = 0;
|
||||||
|
|
||||||
bool withPartitionWildcard() const;
|
bool withPartitionWildcard() const;
|
||||||
bool withGlobs() const { return isPathWithGlobs() || isNamespaceWithGlobs(); }
|
bool withGlobs() const { return isPathWithGlobs() || isNamespaceWithGlobs(); }
|
||||||
|
@ -107,7 +107,7 @@ void StorageObjectStorageCluster::updateQueryToSendIfNeeded(
|
|||||||
|
|
||||||
ASTPtr cluster_name_arg = args.front();
|
ASTPtr cluster_name_arg = args.front();
|
||||||
args.erase(args.begin());
|
args.erase(args.begin());
|
||||||
configuration->addStructureAndFormatToArgsIfNeeded(args, structure, configuration->format, context);
|
configuration->addStructureAndFormatToArgsIfNeeded(args, structure, configuration->format, context, /*with_structure=*/true);
|
||||||
args.insert(args.begin(), cluster_name_arg);
|
args.insert(args.begin(), cluster_name_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2113,6 +2113,11 @@ void StorageFile::truncate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StorageFile::addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const
|
||||||
|
{
|
||||||
|
if (checkAndGetLiteralArgument<String>(evaluateConstantExpressionOrIdentifierAsLiteral(args[0], context), "format") == "auto")
|
||||||
|
args[0] = std::make_shared<ASTLiteral>(format_name);
|
||||||
|
}
|
||||||
|
|
||||||
void registerStorageFile(StorageFactory & factory)
|
void registerStorageFile(StorageFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -139,6 +139,8 @@ public:
|
|||||||
|
|
||||||
bool supportsTrivialCountOptimization(const StorageSnapshotPtr &, ContextPtr) const override { return true; }
|
bool supportsTrivialCountOptimization(const StorageSnapshotPtr &, ContextPtr) const override { return true; }
|
||||||
|
|
||||||
|
void addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class StorageFileSource;
|
friend class StorageFileSource;
|
||||||
friend class StorageFileSink;
|
friend class StorageFileSink;
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include <Common/logger_useful.h>
|
#include <Common/logger_useful.h>
|
||||||
#include <Common/re2.h>
|
#include <Common/re2.h>
|
||||||
|
|
||||||
|
#include <TableFunctions/TableFunctionURL.h>
|
||||||
|
|
||||||
#include <Formats/SchemaInferenceUtils.h>
|
#include <Formats/SchemaInferenceUtils.h>
|
||||||
#include <Core/FormatFactorySettings.h>
|
#include <Core/FormatFactorySettings.h>
|
||||||
#include <Core/ServerSettings.h>
|
#include <Core/ServerSettings.h>
|
||||||
@ -1570,6 +1572,11 @@ void StorageURL::processNamedCollectionResult(Configuration & configuration, con
|
|||||||
configuration.structure = collection.getOrDefault<String>("structure", "auto");
|
configuration.structure = collection.getOrDefault<String>("structure", "auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StorageURL::addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const
|
||||||
|
{
|
||||||
|
TableFunctionURL::updateStructureAndFormatArgumentsIfNeeded(args, "", format_name, context, /*with_structure=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
StorageURL::Configuration StorageURL::getConfiguration(ASTs & args, const ContextPtr & local_context)
|
StorageURL::Configuration StorageURL::getConfiguration(ASTs & args, const ContextPtr & local_context)
|
||||||
{
|
{
|
||||||
StorageURL::Configuration configuration;
|
StorageURL::Configuration configuration;
|
||||||
|
@ -305,6 +305,8 @@ public:
|
|||||||
|
|
||||||
bool supportsDynamicSubcolumns() const override { return true; }
|
bool supportsDynamicSubcolumns() const override { return true; }
|
||||||
|
|
||||||
|
void addInferredEngineArgsToCreateQuery(ASTs & args, const ContextPtr & context) const override;
|
||||||
|
|
||||||
static FormatSettings getFormatSettingsFromArgs(const StorageFactory::Arguments & args);
|
static FormatSettings getFormatSettingsFromArgs(const StorageFactory::Arguments & args);
|
||||||
|
|
||||||
struct Configuration : public StatelessTableEngineConfiguration
|
struct Configuration : public StatelessTableEngineConfiguration
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
|
|
||||||
ASTPtr cluster_name_arg = args.front();
|
ASTPtr cluster_name_arg = args.front();
|
||||||
args.erase(args.begin());
|
args.erase(args.begin());
|
||||||
Base::updateStructureAndFormatArgumentsIfNeeded(args, structure_, format_, context);
|
Base::updateStructureAndFormatArgumentsIfNeeded(args, structure_, format_, context, /*with_structure=*/true);
|
||||||
args.insert(args.begin(), cluster_name_arg);
|
args.insert(args.begin(), cluster_name_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ void ITableFunctionFileLike::parseArgumentsImpl(ASTs & args, const ContextPtr &
|
|||||||
compression_method = checkAndGetLiteralArgument<String>(args[3], "compression_method");
|
compression_method = checkAndGetLiteralArgument<String>(args[3], "compression_method");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure, const String & format, const ContextPtr & context)
|
void ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure, const String & format, const ContextPtr & context, bool with_structure)
|
||||||
{
|
{
|
||||||
if (args.empty() || args.size() > getMaxNumberOfArguments())
|
if (args.empty() || args.size() > getMaxNumberOfArguments())
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Expected 1 to {} arguments in table function, got {}", getMaxNumberOfArguments(), args.size());
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Expected 1 to {} arguments in table function, got {}", getMaxNumberOfArguments(), args.size());
|
||||||
@ -103,6 +103,7 @@ void ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(ASTs & ar
|
|||||||
if (args.size() == 1)
|
if (args.size() == 1)
|
||||||
{
|
{
|
||||||
args.push_back(format_literal);
|
args.push_back(format_literal);
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// f(filename, format)
|
/// f(filename, format)
|
||||||
@ -110,14 +111,15 @@ void ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(ASTs & ar
|
|||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
||||||
args.back() = format_literal;
|
args.back() = format_literal;
|
||||||
|
if (with_structure)
|
||||||
args.push_back(structure_literal);
|
args.push_back(structure_literal);
|
||||||
}
|
}
|
||||||
/// f(filename, format, structure) or f(filename, format, structure, compression)
|
/// f(filename, format, structure) or f(filename, format, structure, compression) or f(filename, format, compression)
|
||||||
else if (args.size() >= 3)
|
else if (args.size() >= 3)
|
||||||
{
|
{
|
||||||
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
if (checkAndGetLiteralArgument<String>(args[1], "format") == "auto")
|
||||||
args[1] = format_literal;
|
args[1] = format_literal;
|
||||||
if (checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
if (with_structure && checkAndGetLiteralArgument<String>(args[2], "structure") == "auto")
|
||||||
args[2] = structure_literal;
|
args[2] = structure_literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
|
|
||||||
static size_t getMaxNumberOfArguments() { return max_number_of_arguments; }
|
static size_t getMaxNumberOfArguments() { return max_number_of_arguments; }
|
||||||
|
|
||||||
static void updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure, const String & format, const ContextPtr &);
|
static void updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure, const String & format, const ContextPtr &, bool with_structure);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ public:
|
|||||||
const String & format,
|
const String & format,
|
||||||
const ContextPtr & context)
|
const ContextPtr & context)
|
||||||
{
|
{
|
||||||
Configuration().addStructureAndFormatToArgsIfNeeded(args, structure, format, context);
|
Configuration().addStructureAndFormatToArgsIfNeeded(args, structure, format, context, /*with_structure=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -77,7 +77,7 @@ void TableFunctionURL::parseArgumentsImpl(ASTs & args, const ContextPtr & contex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableFunctionURL::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure_, const String & format_, const ContextPtr & context)
|
void TableFunctionURL::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure_, const String & format_, const ContextPtr & context, bool with_structure)
|
||||||
{
|
{
|
||||||
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
if (auto collection = tryGetNamedCollectionWithOverrides(args, context))
|
||||||
{
|
{
|
||||||
@ -89,7 +89,7 @@ void TableFunctionURL::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, co
|
|||||||
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
auto format_equal_func = makeASTFunction("equals", std::move(format_equal_func_args));
|
||||||
args.push_back(format_equal_func);
|
args.push_back(format_equal_func);
|
||||||
}
|
}
|
||||||
if (collection->getOrDefault<String>("structure", "auto") == "auto")
|
if (with_structure && collection->getOrDefault<String>("structure", "auto") == "auto")
|
||||||
{
|
{
|
||||||
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
ASTs structure_equal_func_args = {std::make_shared<ASTIdentifier>("structure"), std::make_shared<ASTLiteral>(structure_)};
|
||||||
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
auto structure_equal_func = makeASTFunction("equals", std::move(structure_equal_func_args));
|
||||||
@ -109,7 +109,7 @@ void TableFunctionURL::updateStructureAndFormatArgumentsIfNeeded(ASTs & args, co
|
|||||||
args.pop_back();
|
args.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(args, structure_, format_, context);
|
ITableFunctionFileLike::updateStructureAndFormatArgumentsIfNeeded(args, structure_, format_, context, with_structure);
|
||||||
|
|
||||||
if (headers_ast)
|
if (headers_ast)
|
||||||
args.push_back(headers_ast);
|
args.push_back(headers_ast);
|
||||||
|
@ -34,7 +34,7 @@ public:
|
|||||||
|
|
||||||
ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
|
ColumnsDescription getActualTableStructure(ContextPtr context, bool is_insert_query) const override;
|
||||||
|
|
||||||
static void updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure_, const String & format_, const ContextPtr & context);
|
static void updateStructureAndFormatArgumentsIfNeeded(ASTs & args, const String & structure_, const String & format_, const ContextPtr & context, bool with_structure);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parseArguments(const ASTPtr & ast, ContextPtr context) override;
|
void parseArguments(const ASTPtr & ast, ContextPtr context) override;
|
||||||
|
@ -1314,6 +1314,7 @@ def test_size_virtual_column(cluster):
|
|||||||
|
|
||||||
def test_format_detection(cluster):
|
def test_format_detection(cluster):
|
||||||
node = cluster.instances["node"]
|
node = cluster.instances["node"]
|
||||||
|
connection_string = cluster.env_variables["AZURITE_CONNECTION_STRING"]
|
||||||
storage_account_url = cluster.env_variables["AZURITE_STORAGE_ACCOUNT_URL"]
|
storage_account_url = cluster.env_variables["AZURITE_STORAGE_ACCOUNT_URL"]
|
||||||
account_name = "devstoreaccount1"
|
account_name = "devstoreaccount1"
|
||||||
account_key = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
|
account_key = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
|
||||||
@ -1381,6 +1382,84 @@ def test_format_detection(cluster):
|
|||||||
|
|
||||||
assert result == expected_result
|
assert result == expected_result
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create table test_format_detection engine=AzureBlobStorage('{connection_string}', 'cont', 'test_format_detection1')",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{connection_string}\\', \\'cont\\', \\'test_format_detection1\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create or replace table test_format_detection engine=AzureBlobStorage('{connection_string}', 'cont', 'test_format_detection1', auto)",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{connection_string}\\', \\'cont\\', \\'test_format_detection1\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create or replace table test_format_detection engine=AzureBlobStorage('{connection_string}', 'cont', 'test_format_detection1', auto, 'none')",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{connection_string}\\', \\'cont\\', \\'test_format_detection1\\', \\'JSON\\', \\'none\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create or replace table test_format_detection engine=AzureBlobStorage('{storage_account_url}', 'cont', 'test_format_detection1', '{account_name}', '{account_key}')",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{storage_account_url}\\', \\'cont\\', \\'test_format_detection1\\', \\'{account_name}\\', \\'{account_key}\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create or replace table test_format_detection engine=AzureBlobStorage('{storage_account_url}', 'cont', 'test_format_detection1', '{account_name}', '{account_key}', auto)",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{storage_account_url}\\', \\'cont\\', \\'test_format_detection1\\', \\'{account_name}\\', \\'{account_key}\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
azure_query(
|
||||||
|
node,
|
||||||
|
f"create or replace table test_format_detection engine=AzureBlobStorage('{storage_account_url}', 'cont', 'test_format_detection1', '{account_name}', '{account_key}', auto, 'none')",
|
||||||
|
)
|
||||||
|
result = azure_query(
|
||||||
|
node,
|
||||||
|
f"show create table test_format_detection",
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = AzureBlobStorage(\\'{storage_account_url}\\', \\'cont\\', \\'test_format_detection1\\', \\'{account_name}\\', \\'{account_key}\\', \\'JSON\\', \\'none\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_write_to_globbed_partitioned_path(cluster):
|
def test_write_to_globbed_partitioned_path(cluster):
|
||||||
node = cluster.instances["node"]
|
node = cluster.instances["node"]
|
||||||
|
@ -636,7 +636,7 @@ def test_multiple_inserts(started_cluster):
|
|||||||
node1.query(f"drop table test_multiple_inserts")
|
node1.query(f"drop table test_multiple_inserts")
|
||||||
|
|
||||||
|
|
||||||
def test_format_detection(started_cluster):
|
def test_format_detection_from_file_name(started_cluster):
|
||||||
node1.query(
|
node1.query(
|
||||||
f"create table arrow_table (x UInt64) engine=HDFS('hdfs://hdfs1:9000/data.arrow')"
|
f"create table arrow_table (x UInt64) engine=HDFS('hdfs://hdfs1:9000/data.arrow')"
|
||||||
)
|
)
|
||||||
@ -1222,6 +1222,35 @@ def test_format_detection(started_cluster):
|
|||||||
|
|
||||||
assert expected_result == result
|
assert expected_result == result
|
||||||
|
|
||||||
|
node.query(
|
||||||
|
f"create table test_format_detection engine=HDFS('hdfs://hdfs1:9000/{dir}/test_format_detection1')"
|
||||||
|
)
|
||||||
|
result = node.query(f"show create table test_format_detection")
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = HDFS(\\'hdfs://hdfs1:9000/{dir}/test_format_detection1\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
node.query("drop table test_format_detection")
|
||||||
|
node.query(
|
||||||
|
f"create table test_format_detection engine=HDFS('hdfs://hdfs1:9000/{dir}/test_format_detection1', auto)"
|
||||||
|
)
|
||||||
|
result = node.query(f"show create table test_format_detection")
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = HDFS(\\'hdfs://hdfs1:9000/{dir}/test_format_detection1\\', \\'JSON\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
node.query("drop table test_format_detection")
|
||||||
|
node.query(
|
||||||
|
f"create table test_format_detection engine=HDFS('hdfs://hdfs1:9000/{dir}/test_format_detection1', auto, 'none')"
|
||||||
|
)
|
||||||
|
result = node.query(f"show create table test_format_detection")
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== f"CREATE TABLE default.test_format_detection\\n(\\n `x` Nullable(String),\\n `y` Nullable(String)\\n)\\nENGINE = HDFS(\\'hdfs://hdfs1:9000/{dir}/test_format_detection1\\', \\'JSON\\', \\'none\\')\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_write_to_globbed_partitioned_path(started_cluster):
|
def test_write_to_globbed_partitioned_path(started_cluster):
|
||||||
node = started_cluster.instances["node1"]
|
node = started_cluster.instances["node1"]
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'NOSIGN\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'JSON\', \'none\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'NOSIGN\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'test\', \'[HIDDEN]\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'NOSIGN\', \'JSON\', \'none\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'test\', \'[HIDDEN]\', \'\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'test\', \'[HIDDEN]\', \'\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'test\', \'[HIDDEN]\', \'JSON\', \'none\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = S3(\'http://localhost:11111/test/json_data\', \'test\', \'[HIDDEN]\', \'\', \'JSON\', \'none\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = URL(\'http://localhost:11111/test/json_data\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = URL(\'http://localhost:11111/test/json_data\', \'JSON\')
|
||||||
|
CREATE TABLE default.test\n(\n `a` Nullable(Int64)\n)\nENGINE = URL(\'http://localhost:11111/test/json_data\', \'JSON\', \'none\')
|
@ -0,0 +1,59 @@
|
|||||||
|
-- Tags: no-fasttest
|
||||||
|
|
||||||
|
drop table if exists test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', NOSIGN);
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', auto);
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', auto, 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', NOSIGN, auto);
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', 'test', 'testtest');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', NOSIGN, auto, 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', 'test', 'testtest', '');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', 'test', 'testtest', '', auto);
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', 'test', 'testtest', auto, 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=S3('http://localhost:11111/test/json_data', 'test', 'testtest', '', auto, 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=URL('http://localhost:11111/test/json_data');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=URL('http://localhost:11111/test/json_data', auto);
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=URL('http://localhost:11111/test/json_data', auto, 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
@ -0,0 +1 @@
|
|||||||
|
2
|
19
tests/queries/0_stateless/03274_format_inference_create_query_file.sh
Executable file
19
tests/queries/0_stateless/03274_format_inference_create_query_file.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=../shell_config.sh
|
||||||
|
. "$CURDIR"/../shell_config.sh
|
||||||
|
|
||||||
|
$CLICKHOUSE_LOCAL -q "select 42 as a format JSONEachRow" > data_$CLICKHOUSE_TEST_UNIQUE_NAME
|
||||||
|
$CLICKHOUSE_LOCAL -nm -q "
|
||||||
|
create table test engine=File(auto, './data_$CLICKHOUSE_TEST_UNIQUE_NAME');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
create table test engine=File(auto, './data_$CLICKHOUSE_TEST_UNIQUE_NAME', 'none');
|
||||||
|
show create table test;
|
||||||
|
drop table test;
|
||||||
|
" | grep "JSON" -c
|
||||||
|
|
||||||
|
rm data_$CLICKHOUSE_TEST_UNIQUE_NAME
|
||||||
|
|
1
tests/queries/0_stateless/data_minio/json_data
Normal file
1
tests/queries/0_stateless/data_minio/json_data
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"a" : 42}
|
Loading…
Reference in New Issue
Block a user