mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Fix some server crashes on incorrect functions usage. Add test.
This commit is contained in:
parent
f5ecb2db5d
commit
2663871717
@ -14,6 +14,11 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int TOO_LESS_ARGUMENTS_FOR_FUNCTION;
|
||||
}
|
||||
|
||||
void registerFunctionsConditional(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionIf>();
|
||||
@ -392,6 +397,10 @@ String FunctionCaseWithExpression::getName() const
|
||||
|
||||
DataTypePtr FunctionCaseWithExpression::getReturnTypeImpl(const DataTypes & args) const
|
||||
{
|
||||
if (!args.size())
|
||||
throw Exception{"Function " + getName() + " expects at least 1 arguments",
|
||||
ErrorCodes::TOO_LESS_ARGUMENTS_FOR_FUNCTION};
|
||||
|
||||
/// See the comments in executeImpl() to understand why we actually have to
|
||||
/// get the return type of a transform function.
|
||||
|
||||
@ -419,6 +428,10 @@ DataTypePtr FunctionCaseWithExpression::getReturnTypeImpl(const DataTypes & args
|
||||
|
||||
void FunctionCaseWithExpression::executeImpl(Block & block, const ColumnNumbers & args, size_t result)
|
||||
{
|
||||
if (!args.size())
|
||||
throw Exception{"Function " + getName() + " expects at least 1 arguments",
|
||||
ErrorCodes::TOO_LESS_ARGUMENTS_FOR_FUNCTION};
|
||||
|
||||
/// In the following code, we turn the construction:
|
||||
/// CASE expr WHEN val[0] THEN branch[0] ... WHEN val[N-1] then branch[N-1] ELSE branchN
|
||||
/// into the construction transform(expr, src, dest, branchN)
|
||||
|
@ -50,6 +50,7 @@ namespace ErrorCodes
|
||||
extern const int CANNOT_PARSE_TEXT;
|
||||
extern const int CANNOT_PARSE_UUID;
|
||||
extern const int TOO_LARGE_STRING_SIZE;
|
||||
extern const int TOO_LESS_ARGUMENTS_FOR_FUNCTION;
|
||||
}
|
||||
|
||||
|
||||
@ -743,6 +744,10 @@ public:
|
||||
private:
|
||||
void executeInternal(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||
{
|
||||
if (!arguments.size())
|
||||
throw Exception{"Function " + getName() + " expects at least 1 arguments",
|
||||
ErrorCodes::TOO_LESS_ARGUMENTS_FOR_FUNCTION};
|
||||
|
||||
IDataType * from_type = block.getByPosition(arguments[0]).type.get();
|
||||
|
||||
if (checkDataType<DataTypeUInt8>(from_type)) ConvertImpl<DataTypeUInt8, ToDataType, Name>::execute(block, arguments, result);
|
||||
|
@ -27,6 +27,9 @@ std::string extractTimeZoneNameFromFunctionArguments(const ColumnsWithTypeAndNam
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!arguments.size())
|
||||
return {};
|
||||
|
||||
/// If time zone is attached to an argument of type DateTime.
|
||||
if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(arguments[0].type.get()))
|
||||
return type->getTimeZone().getTimeZone();
|
||||
@ -41,6 +44,9 @@ const DateLUTImpl & extractTimeZoneFromFunctionArguments(Block & block, const Co
|
||||
return DateLUT::instance(extractTimeZoneNameFromColumn(*block.getByPosition(arguments[time_zone_arg_num]).column));
|
||||
else
|
||||
{
|
||||
if (!arguments.size())
|
||||
return DateLUT::instance();
|
||||
|
||||
/// If time zone is attached to an argument of type DateTime.
|
||||
if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(block.getByPosition(arguments[0]).type.get()))
|
||||
return type->getTimeZone();
|
||||
|
@ -1 +1 @@
|
||||
server still alive
|
||||
Still alive
|
||||
|
@ -11,4 +11,4 @@ clickhouse-client -q "CREATE TABLE test.advertiser_test ( action_date Date, adbl
|
||||
clickhouse-client -q "INSERT INTO test.advertiser_test SELECT *, sipHash64( CAST(adblock AS String) ), CAST(1 AS Int8) FROM test.advertiser;" 2>/dev/null
|
||||
clickhouse-client -q "DROP TABLE test.advertiser";
|
||||
clickhouse-client -q "DROP TABLE test.advertiser_test";
|
||||
clickhouse-client -q "SELECT 'server still alive'";
|
||||
clickhouse-client -q "SELECT 'Still alive'";
|
||||
|
@ -0,0 +1 @@
|
||||
Still alive
|
12
dbms/tests/queries/0_stateless/00521_functions_bad_arguments.sh
Executable file
12
dbms/tests/queries/0_stateless/00521_functions_bad_arguments.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
. $CURDIR/../shell_config.sh
|
||||
|
||||
# Server should not crash on any function trash calls
|
||||
|
||||
# todo: make --ignore-error function in clickhouse-client and load all queries as one .sql (or pipe)
|
||||
# todo: maybe add more strange usages
|
||||
perl -E "chomp, say qx{$CLICKHOUSE_CLIENT -q '\$_'} for map {chomp; (qq{SELECT \$_;}, qq{SELECT \$_();}, qq{SELECT \$_(NULL);}, qq{SELECT \$_([]);}, qq{SELECT \$_([NULL]);})} qx{$CLICKHOUSE_CLIENT -q 'SELECT name FROM system.functions ORDER BY name;'}" 2>&1 >/dev/null
|
||||
|
||||
$CLICKHOUSE_CLIENT -q 'Still alive'
|
Loading…
Reference in New Issue
Block a user