diff --git a/src/Interpreters/InterpreterCreateQuery.cpp b/src/Interpreters/InterpreterCreateQuery.cpp index 5207ee059353..8d5918757516 100644 --- a/src/Interpreters/InterpreterCreateQuery.cpp +++ b/src/Interpreters/InterpreterCreateQuery.cpp @@ -1918,8 +1918,7 @@ bool InterpreterCreateQuery::doCreateTable(ASTCreateQuery & create, auto table_function_ast = create.as_table_function->ptr(); auto table_function = TableFunctionFactory::instance().get(table_function_ast, getContext()); - if (!table_function->canBeUsedToCreateTable()) - throw Exception(ErrorCodes::BAD_ARGUMENTS, "Table function '{}' cannot be used to create a table", table_function->getName()); + table_function->validateUseToCreateTable(); /// In case of CREATE AS table_function() query we should use global context /// in storage creation because there will be no query context on server startup diff --git a/src/TableFunctions/ITableFunction.h b/src/TableFunctions/ITableFunction.h index 0e03d2cda2b8..333e51d8de0d 100644 --- a/src/TableFunctions/ITableFunction.h +++ b/src/TableFunctions/ITableFunction.h @@ -78,7 +78,7 @@ class ITableFunction : public std::enable_shared_from_this virtual bool supportsReadingSubsetOfColumns(const ContextPtr &) { return true; } - virtual bool canBeUsedToCreateTable() const { return true; } + virtual void validateUseToCreateTable() const {} /// Create storage according to the query. StoragePtr diff --git a/src/TableFunctions/ITableFunctionCluster.h b/src/TableFunctions/ITableFunctionCluster.h index 7d33c6aea7bb..cf698c69a97e 100644 --- a/src/TableFunctions/ITableFunctionCluster.h +++ b/src/TableFunctions/ITableFunctionCluster.h @@ -15,6 +15,7 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int CLUSTER_DOESNT_EXIST; extern const int LOGICAL_ERROR; + extern const int BAD_ARGUMENTS; } /// Base class for *Cluster table functions that require cluster_name for the first argument. @@ -35,7 +36,10 @@ class ITableFunctionCluster : public Base args.insert(args.begin(), cluster_name_arg); } - bool canBeUsedToCreateTable() const override { return false; } + void validateUseToCreateTable() const override + { + throw Exception(ErrorCodes::BAD_ARGUMENTS, "Table function '{}' cannot be used to create a table", getName()); + } protected: void parseArguments(const ASTPtr & ast, ContextPtr context) override diff --git a/src/TableFunctions/TableFunctionObjectStorageClusterFallback.cpp b/src/TableFunctions/TableFunctionObjectStorageClusterFallback.cpp index 6fe9f6853dce..d33297e22ce1 100644 --- a/src/TableFunctions/TableFunctionObjectStorageClusterFallback.cpp +++ b/src/TableFunctions/TableFunctionObjectStorageClusterFallback.cpp @@ -15,6 +15,7 @@ namespace Setting namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int BAD_ARGUMENTS; } struct S3ClusterFallbackDefinition @@ -117,6 +118,16 @@ StoragePtr TableFunctionObjectStorageClusterFallback::executeI return BaseSimple::executeImpl(ast_function, context, table_name, cached_columns, is_insert_query); } +template +void TableFunctionObjectStorageClusterFallback::validateUseToCreateTable() const +{ + if (is_cluster_function) + throw Exception( + ErrorCodes::BAD_ARGUMENTS, + "Table function '{}' cannot be used to create a table in cluster mode", + getName()); +} + #if USE_AWS_S3 using TableFunctionS3ClusterFallback = TableFunctionObjectStorageClusterFallback; #endif diff --git a/src/TableFunctions/TableFunctionObjectStorageClusterFallback.h b/src/TableFunctions/TableFunctionObjectStorageClusterFallback.h index afa6b8b49f11..28dfe22143dc 100644 --- a/src/TableFunctions/TableFunctionObjectStorageClusterFallback.h +++ b/src/TableFunctions/TableFunctionObjectStorageClusterFallback.h @@ -26,6 +26,8 @@ class TableFunctionObjectStorageClusterFallback : public Base String getName() const override { return name; } + void validateUseToCreateTable() const override; + private: const char * getStorageTypeName() const override {