diff --git a/src/Functions/hasColumnInTable.cpp b/src/Functions/hasColumnInTable.cpp index ef447070e7a..910a290fb88 100644 --- a/src/Functions/hasColumnInTable.cpp +++ b/src/Functions/hasColumnInTable.cpp @@ -17,6 +17,7 @@ namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int ILLEGAL_TYPE_OF_ARGUMENT; + extern const int UNKNOWN_TABLE; } @@ -110,6 +111,9 @@ void FunctionHasColumnInTable::executeImpl(Block & block, const ColumnNumbers & String table_name = get_string_from_block(arguments[arg++]); String column_name = get_string_from_block(arguments[arg++]); + if (table_name.empty()) + throw Exception("Table name is empty", ErrorCodes::UNKNOWN_TABLE); + bool has_column; if (host_name.empty()) { diff --git a/src/Interpreters/convertFieldToType.cpp b/src/Interpreters/convertFieldToType.cpp index d46573d0461..2d624922d2a 100644 --- a/src/Interpreters/convertFieldToType.cpp +++ b/src/Interpreters/convertFieldToType.cpp @@ -329,5 +329,16 @@ Field convertFieldToType(const Field & from_value, const IDataType & to_type, co return convertFieldToTypeImpl(from_value, to_type, from_type_hint); } +Field convertFieldToTypeOrThrow(const Field & from_value, const IDataType & to_type, const IDataType * from_type_hint) +{ + bool is_null = from_value.isNull(); + if (is_null && !to_type.isNullable()) + throw Exception(ErrorCodes::TYPE_MISMATCH, "Cannot convert NULL to {}", to_type.getName()); + Field converted = convertFieldToType(from_value, to_type, from_type_hint); + if (!is_null && converted.isNull()) + throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND, "Cannot convert value{}: it cannot be represented as {}", + from_type_hint ? " from " + from_type_hint->getName() : "", to_type.getName()); + return converted; +} } diff --git a/src/Interpreters/convertFieldToType.h b/src/Interpreters/convertFieldToType.h index 801beddd876..91b631d0e12 100644 --- a/src/Interpreters/convertFieldToType.h +++ b/src/Interpreters/convertFieldToType.h @@ -17,4 +17,7 @@ class IDataType; */ Field convertFieldToType(const Field & from_value, const IDataType & to_type, const IDataType * from_type_hint = nullptr); +/// Does the same, but throws ARGUMENT_OUT_OF_BOUND if value does not fall into the range. +Field convertFieldToTypeOrThrow(const Field & from_value, const IDataType & to_type, const IDataType * from_type_hint = nullptr); + } diff --git a/src/TableFunctions/TableFunctionValues.cpp b/src/TableFunctions/TableFunctionValues.cpp index 5ecd978146c..b4b243416f2 100644 --- a/src/TableFunctions/TableFunctionValues.cpp +++ b/src/TableFunctions/TableFunctionValues.cpp @@ -38,7 +38,7 @@ static void parseAndInsertValues(MutableColumns & res_columns, const ASTs & args { const auto & [value_field, value_type_ptr] = evaluateConstantExpression(args[i], context); - Field value = convertFieldToType(value_field, *sample_block.getByPosition(0).type, value_type_ptr.get()); + Field value = convertFieldToTypeOrThrow(value_field, *sample_block.getByPosition(0).type, value_type_ptr.get()); res_columns[0]->insert(value); } } @@ -51,11 +51,11 @@ static void parseAndInsertValues(MutableColumns & res_columns, const ASTs & args const Tuple & value_tuple = value_field.safeGet(); if (value_tuple.size() != sample_block.columns()) - throw Exception("Values size should match with number of columns", ErrorCodes::LOGICAL_ERROR); + throw Exception("Values size should match with number of columns", ErrorCodes::BAD_ARGUMENTS); for (size_t j = 0; j < value_tuple.size(); ++j) { - Field value = convertFieldToType(value_tuple[j], *sample_block.getByPosition(j).type, value_types_tuple[j].get()); + Field value = convertFieldToTypeOrThrow(value_tuple[j], *sample_block.getByPosition(j).type, value_types_tuple[j].get()); res_columns[j]->insert(value); } } diff --git a/tests/queries/0_stateless/00386_has_column_in_table.reference b/tests/queries/0_stateless/00386_has_column_in_table.reference index feb61b43751..5b80b696eda 100644 --- a/tests/queries/0_stateless/00386_has_column_in_table.reference +++ b/tests/queries/0_stateless/00386_has_column_in_table.reference @@ -12,3 +12,4 @@ 0 0 0 +0 diff --git a/tests/queries/0_stateless/00386_has_column_in_table.sql b/tests/queries/0_stateless/00386_has_column_in_table.sql index 42643dd73e6..d543bb42ca7 100644 --- a/tests/queries/0_stateless/00386_has_column_in_table.sql +++ b/tests/queries/0_stateless/00386_has_column_in_table.sql @@ -18,5 +18,14 @@ SELECT hasColumnInTable(currentDatabase(), 'has_column_in_table', 'nest.not_exis SELECT hasColumnInTable('localhost', currentDatabase(), 'has_column_in_table', 'nest.not_existing'); SELECT hasColumnInTable(currentDatabase(), 'has_column_in_table', 'not_existing'); SELECT hasColumnInTable('localhost', currentDatabase(), 'has_column_in_table', 'not_existing'); +SELECT hasColumnInTable('system', 'one', ''); + +/* bad queries */ +SELECT hasColumnInTable('', '', ''); -- { serverError 60; } +SELECT hasColumnInTable('', 't', 'c'); -- { serverError 81; } +SELECT hasColumnInTable(currentDatabase(), '', 'c'); -- { serverError 60; } +SELECT hasColumnInTable('d', 't', 's'); -- { serverError 81; } +SELECT hasColumnInTable(currentDatabase(), 't', 's'); -- { serverError 60; } + DROP TABLE has_column_in_table; diff --git a/tests/queries/0_stateless/00945_bloom_filter_index.sql b/tests/queries/0_stateless/00945_bloom_filter_index.sql index d509b99229a..d06a292c49a 100755 --- a/tests/queries/0_stateless/00945_bloom_filter_index.sql +++ b/tests/queries/0_stateless/00945_bloom_filter_index.sql @@ -1,7 +1,7 @@ DROP TABLE IF EXISTS single_column_bloom_filter; -CREATE TABLE single_column_bloom_filter (u64 UInt64, i32 Int32, i64 UInt64, INDEX idx (i32) TYPE bloom_filter GRANULARITY 1) ENGINE = MergeTree() ORDER BY u64 SETTINGS index_granularity = 6; +CREATE TABLE single_column_bloom_filter (u64 UInt64, i32 Float32, i64 UInt64, INDEX idx (i32) TYPE bloom_filter GRANULARITY 1) ENGINE = MergeTree() ORDER BY u64 SETTINGS index_granularity = 6; INSERT INTO single_column_bloom_filter SELECT number AS u64, number AS i32, number AS i64 FROM system.numbers LIMIT 100; diff --git a/tests/queries/0_stateless/00975_values_list.reference b/tests/queries/0_stateless/00975_values_list.reference index eee9e0a0ca5..f8ada08d130 100644 --- a/tests/queries/0_stateless/00975_values_list.reference +++ b/tests/queries/0_stateless/00975_values_list.reference @@ -11,3 +11,4 @@ abracadabra 23 23 23 24 24 24 1.6660 a b +\N diff --git a/tests/queries/0_stateless/00975_values_list.sql b/tests/queries/0_stateless/00975_values_list.sql index ad30cec21e9..40c86898966 100644 --- a/tests/queries/0_stateless/00975_values_list.sql +++ b/tests/queries/0_stateless/00975_values_list.sql @@ -11,4 +11,9 @@ SELECT * FROM VALUES('s String', ('abra'), ('cadabra'), ('abracadabra')); SELECT * FROM VALUES('n UInt64, s String, ss String', (1 + 22, '23', toString(23)), (toUInt64('24'), '24', concat('2', '4'))); SELECT * FROM VALUES('a Decimal(4, 4), b String, c String', (divide(toDecimal32(5, 3), 3), 'a', 'b')); + +SELECT * FROM VALUES('x Float64', toUInt64(-1)); -- { serverError 69; } +SELECT * FROM VALUES('x Float64', NULL); -- { serverError 53; } +SELECT * FROM VALUES('x Nullable(Float64)', NULL); + DROP TABLE values_list;