Merge pull request #36345 from ucasfl/throw-no-data

Add setting throw_if_no_data_to_insert
This commit is contained in:
Alexey Milovidov 2022-04-18 07:04:16 +03:00 committed by GitHub
commit 1333b4cd89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 4 deletions

View File

@ -1058,7 +1058,13 @@ void ClientBase::processInsertQuery(const String & query_to_execute, ASTPtr pars
/// Process the query that requires transferring data blocks to the server.
const auto parsed_insert_query = parsed_query->as<ASTInsertQuery &>();
if ((!parsed_insert_query.data && !parsed_insert_query.infile) && (is_interactive || (!stdin_is_a_tty && std_in.eof())))
throw Exception("No data to insert", ErrorCodes::NO_DATA_TO_INSERT);
{
const auto & settings = global_context->getSettingsRef();
if (settings.throw_if_no_data_to_insert)
throw Exception("No data to insert", ErrorCodes::NO_DATA_TO_INSERT);
else
return;
}
connection->sendQuery(
connection_parameters.timeouts,

View File

@ -582,6 +582,7 @@ class IColumn;
M(Bool, allow_experimental_object_type, false, "Allow Object and JSON data types", 0) \
M(String, insert_deduplication_token, "", "If not empty, used for duplicate detection instead of data digest", 0) \
M(Bool, throw_on_unsupported_query_inside_transaction, true, "Throw exception if unsupported query is used inside transaction", 0) \
M(Bool, throw_if_no_data_to_insert, true, "Enables or disables empty INSERTs, disable by default", 0) \
// End of COMMON_SETTINGS
// Please add settings related to formats into the FORMAT_FACTORY_SETTINGS and move obsolete settings to OBSOLETE_SETTINGS.

View File

@ -41,6 +41,7 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
ParserKeyword s_with("WITH");
ParserToken s_lparen(TokenType::OpeningRoundBracket);
ParserToken s_rparen(TokenType::ClosingRoundBracket);
ParserToken s_semicolon(TokenType::Semicolon);
ParserIdentifier name_p(true);
ParserList columns_p(std::make_unique<ParserInsertElement>(), std::make_unique<ParserToken>(TokenType::Comma), false);
ParserFunction table_function_p{false};
@ -146,8 +147,10 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
/// After FROM INFILE we expect FORMAT, SELECT, WITH or nothing.
if (!infile && s_values.ignore(pos, expected))
{
/// If VALUES is defined in query, everything except setting will be parsed as data
data = pos->begin;
/// If VALUES is defined in query, everything except setting will be parsed as data,
/// and if values followed by semicolon, the data should be null.
if (!s_semicolon.checkWithoutMoving(pos, expected))
data = pos->begin;
format_str = "Values";
}
else if (s_format.ignore(pos, expected))

View File

@ -956,7 +956,13 @@ namespace
if (!insert_query)
throw Exception("Query requires data to insert, but it is not an INSERT query", ErrorCodes::NO_DATA_TO_INSERT);
else
throw Exception("No data to insert", ErrorCodes::NO_DATA_TO_INSERT);
{
const auto & settings = query_context->getSettingsRef();
if (settings.throw_if_no_data_to_insert)
throw Exception("No data to insert", ErrorCodes::NO_DATA_TO_INSERT);
else
return;
}
}
/// This is significant, because parallel parsing may be used.

View File

@ -0,0 +1,11 @@
DROP TABLE IF EXISTS t;
CREATE TABLE t (n UInt32) ENGINE=Memory;
INSERT INTO t VALUES; -- { clientError 108 }
set throw_if_no_data_to_insert = 0;
INSERT INTO t VALUES;
DROP TABLE t;