mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
add setting allow_ddl
This commit is contained in:
parent
94183c7af1
commit
c1ed0bb86a
@ -55,6 +55,7 @@ namespace ErrorCodes
|
||||
extern const int DUPLICATE_COLUMN;
|
||||
extern const int READONLY;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int QUERY_IS_PROHIBITED;
|
||||
}
|
||||
|
||||
|
||||
@ -634,23 +635,26 @@ void InterpreterCreateQuery::checkAccess(const ASTCreateQuery & create)
|
||||
|
||||
const Settings & settings = context.getSettingsRef();
|
||||
auto readonly = settings.readonly;
|
||||
auto allow_ddl = settings.allow_ddl;
|
||||
|
||||
if (!readonly)
|
||||
{
|
||||
if (!readonly && allow_ddl)
|
||||
return;
|
||||
}
|
||||
|
||||
/// CREATE|ATTACH DATABASE
|
||||
if (!create.database.empty() && create.table.empty())
|
||||
{
|
||||
throw Exception("Cannot create database in readonly mode", ErrorCodes::READONLY);
|
||||
if (readonly)
|
||||
throw Exception("Cannot create database in readonly mode", ErrorCodes::READONLY);
|
||||
|
||||
throw Exception("Cannot create database. DDL queries are prohibited for the user", ErrorCodes::QUERY_IS_PROHIBITED);
|
||||
}
|
||||
|
||||
if (create.is_temporary && readonly >= 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw Exception("Cannot create table in readonly mode", ErrorCodes::READONLY);
|
||||
if (readonly)
|
||||
throw Exception("Cannot create table in readonly mode", ErrorCodes::READONLY);
|
||||
|
||||
throw Exception("Cannot create table. DDL queries are prohibited for the user", ErrorCodes::QUERY_IS_PROHIBITED);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace ErrorCodes
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int SYNTAX_ERROR;
|
||||
extern const int UNKNOWN_TABLE;
|
||||
extern const int QUERY_IS_PROHIBITED;
|
||||
}
|
||||
|
||||
|
||||
@ -217,14 +218,16 @@ void InterpreterDropQuery::checkAccess(const ASTDropQuery & drop)
|
||||
{
|
||||
const Settings & settings = context.getSettingsRef();
|
||||
auto readonly = settings.readonly;
|
||||
bool allow_ddl = settings.allow_ddl;
|
||||
|
||||
/// It's allowed to drop temporary tables.
|
||||
if (!readonly || (drop.database.empty() && context.tryGetExternalTable(drop.table) && readonly >= 2))
|
||||
{
|
||||
if ((!readonly && allow_ddl) || (drop.database.empty() && context.tryGetExternalTable(drop.table) && readonly >= 2))
|
||||
return;
|
||||
}
|
||||
|
||||
throw Exception("Cannot drop table in readonly mode", ErrorCodes::READONLY);
|
||||
if (readonly)
|
||||
throw Exception("Cannot drop table in readonly mode", ErrorCodes::READONLY);
|
||||
|
||||
throw Exception("Cannot drop table. DDL queries are prohibited for the user", ErrorCodes::QUERY_IS_PROHIBITED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,10 +54,11 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int READONLY;
|
||||
extern const int UNKNOWN_TYPE_OF_QUERY;
|
||||
extern const int QUERY_IS_PROHIBITED;
|
||||
}
|
||||
|
||||
|
||||
static void throwIfReadOnly(Context & context)
|
||||
static void throwIfNoAccess(Context & context)
|
||||
{
|
||||
if (context.getSettingsRef().readonly)
|
||||
{
|
||||
@ -68,6 +69,8 @@ static void throwIfReadOnly(Context & context)
|
||||
else
|
||||
throw Exception("Cannot execute query in readonly mode", ErrorCodes::READONLY);
|
||||
}
|
||||
else if (!context.getSettingsRef().allow_ddl)
|
||||
throw Exception("Cannot execute query. DDL queries are prohibited for the user", ErrorCodes::QUERY_IS_PROHIBITED);
|
||||
}
|
||||
|
||||
|
||||
@ -95,17 +98,17 @@ std::unique_ptr<IInterpreter> InterpreterFactory::get(ASTPtr & query, Context &
|
||||
}
|
||||
else if (typeid_cast<ASTCreateQuery *>(query.get()))
|
||||
{
|
||||
/// readonly is checked inside InterpreterCreateQuery
|
||||
/// readonly and allow_ddl are checked inside InterpreterCreateQuery
|
||||
return std::make_unique<InterpreterCreateQuery>(query, context);
|
||||
}
|
||||
else if (typeid_cast<ASTDropQuery *>(query.get()))
|
||||
{
|
||||
/// readonly is checked inside InterpreterDropQuery
|
||||
/// readonly and allow_ddl are checked inside InterpreterDropQuery
|
||||
return std::make_unique<InterpreterDropQuery>(query, context);
|
||||
}
|
||||
else if (typeid_cast<ASTRenameQuery *>(query.get()))
|
||||
{
|
||||
throwIfReadOnly(context);
|
||||
throwIfNoAccess(context);
|
||||
return std::make_unique<InterpreterRenameQuery>(query, context);
|
||||
}
|
||||
else if (typeid_cast<ASTShowTablesQuery *>(query.get()))
|
||||
@ -123,7 +126,7 @@ std::unique_ptr<IInterpreter> InterpreterFactory::get(ASTPtr & query, Context &
|
||||
}
|
||||
else if (typeid_cast<ASTOptimizeQuery *>(query.get()))
|
||||
{
|
||||
throwIfReadOnly(context);
|
||||
throwIfNoAccess(context);
|
||||
return std::make_unique<InterpreterOptimizeQuery>(query, context);
|
||||
}
|
||||
else if (typeid_cast<ASTExistsQuery *>(query.get()))
|
||||
@ -148,7 +151,7 @@ std::unique_ptr<IInterpreter> InterpreterFactory::get(ASTPtr & query, Context &
|
||||
}
|
||||
else if (typeid_cast<ASTAlterQuery *>(query.get()))
|
||||
{
|
||||
throwIfReadOnly(context);
|
||||
throwIfNoAccess(context);
|
||||
return std::make_unique<InterpreterAlterQuery>(query, context);
|
||||
}
|
||||
else if (typeid_cast<ASTCheckQuery *>(query.get()))
|
||||
@ -161,7 +164,7 @@ std::unique_ptr<IInterpreter> InterpreterFactory::get(ASTPtr & query, Context &
|
||||
}
|
||||
else if (typeid_cast<ASTSystemQuery *>(query.get()))
|
||||
{
|
||||
throwIfReadOnly(context);
|
||||
throwIfNoAccess(context);
|
||||
return std::make_unique<InterpreterSystemQuery>(query, context);
|
||||
}
|
||||
else
|
||||
|
@ -10,6 +10,7 @@ namespace DB
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int READONLY;
|
||||
extern const int QUERY_IS_PROHIBITED;
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +37,7 @@ void InterpreterSetQuery::checkAccess(const ASTSetQuery & ast)
|
||||
|
||||
const Settings & settings = context.getSettingsRef();
|
||||
auto readonly = settings.readonly;
|
||||
auto allow_ddl = settings.allow_ddl;
|
||||
|
||||
for (const auto & change : ast.changes)
|
||||
{
|
||||
@ -43,6 +45,10 @@ void InterpreterSetQuery::checkAccess(const ASTSetQuery & ast)
|
||||
/// Setting isn't checked if value wasn't changed.
|
||||
if (!settings.tryGet(change.name, value) || applyVisitor(FieldVisitorToString(), change.value) != value)
|
||||
{
|
||||
|
||||
if (!allow_ddl && change.name == "allow_ddl")
|
||||
throw Exception("Cannot modify 'allow_ddl' setting when DDL queries are not allowed", ErrorCodes::QUERY_IS_PROHIBITED);
|
||||
|
||||
if (readonly == 1)
|
||||
throw Exception("Cannot execute SET query in readonly mode", ErrorCodes::READONLY);
|
||||
|
||||
|
@ -288,6 +288,7 @@ struct Settings
|
||||
M(SettingBool, asterisk_left_columns_only, 0, "If it is set to true, the asterisk only return left of join query.") \
|
||||
M(SettingUInt64, http_max_multipart_form_data_size, 1024 * 1024 * 1024, "Limit on size of multipart/form-data content. This setting cannot be parsed from URL parameters and should be set in user profile. Note that content is parsed and external tables are created in memory before start of query execution. And this is the only limit that has effect on that stage (limits on max memory usage and max execution time have no effect while reading HTTP form data).") \
|
||||
M(SettingBool, calculate_text_stack_trace, 1, "Calculate text stack trace in case of exceptions during query execution. This is the default. It requires symbol lookups that may slow down fuzzing tests when huge amount of wrong queries are executed. In normal cases you should not disable this option.") \
|
||||
M(SettingBool, allow_ddl, true, "If it is set to true, then a user is allowed to executed DDL queries.") \
|
||||
|
||||
|
||||
#define DECLARE(TYPE, NAME, DEFAULT, DESCRIPTION) \
|
||||
|
8
dbms/tests/queries/0_stateless/00716_allow_ddl.sql
Executable file
8
dbms/tests/queries/0_stateless/00716_allow_ddl.sql
Executable file
@ -0,0 +1,8 @@
|
||||
SET send_logs_level = 'none';
|
||||
SET allow_ddl = 0;
|
||||
|
||||
CREATE DATABASE some_db; -- { serverError 392 }
|
||||
CREATE TABLE test.some_table(a Int32) ENGINE = Memory; -- { serverError 392}
|
||||
ALTER TABLE test.some_table DELETE WHERE 1; -- { serverError 392}
|
||||
RENAME TABLE test.some_table TO test.some_table1; -- { serverError 392}
|
||||
SET allow_ddl = 1; -- { serverError 392}
|
Loading…
Reference in New Issue
Block a user