Ban non comparable types in primary key

This commit is contained in:
alesapin 2020-11-02 14:39:27 +03:00
parent 7a92960a11
commit f3b3025719
5 changed files with 24 additions and 3 deletions

View File

@ -512,6 +512,7 @@ namespace ErrorCodes
extern const int NO_ROW_DELIMITER = 546;
extern const int INVALID_RAID_TYPE = 547;
extern const int UNKNOWN_VOLUME = 548;
extern const int DATA_TYPE_CANNOT_BE_USED_IN_KEY = 549;
extern const int KEEPER_EXCEPTION = 999;
extern const int POCO_EXCEPTION = 1000;

View File

@ -26,6 +26,7 @@ namespace ErrorCodes
extern const int NOT_IMPLEMENTED;
extern const int LOGICAL_ERROR;
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int LOGICAL_ERROR;
}
template <typename T, typename SFINAE = void>
@ -767,9 +768,10 @@ T & Field::get()
#ifndef NDEBUG
// Disregard signedness when converting between int64 types.
constexpr Field::Types::Which target = TypeToEnum<NearestFieldType<ValueType>>::value;
assert(target == which
|| (isInt64FieldType(target) && isInt64FieldType(which))
|| target == Field::Types::Decimal64 /* DateTime64 fields */);
if (target != which
&& (!isInt64FieldType(target) || !isInt64FieldType(which))
&& target != Field::Types::Decimal64 /* DateTime64 fields */)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid Field get from type {} to type {}", Types::toString(which), Types::toString(target));
#endif
ValueType * MAY_ALIAS ptr = reinterpret_cast<ValueType *>(&storage);

View File

@ -2,10 +2,12 @@
#include <Functions/IFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <DataTypes/DataTypeAggregateFunction.h>
#include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/TreeRewriter.h>
#include <Storages/extractKeyExpressionList.h>
#include <Common/quoteString.h>
namespace DB
@ -14,6 +16,7 @@ namespace DB
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
extern const int DATA_TYPE_CANNOT_BE_USED_IN_KEY;
}
KeyDescription::KeyDescription(const KeyDescription & other)
@ -115,7 +118,13 @@ KeyDescription KeyDescription::getSortingKeyFromAST(
}
for (size_t i = 0; i < result.sample_block.columns(); ++i)
{
result.data_types.emplace_back(result.sample_block.getByPosition(i).type);
if (!result.data_types.back()->isComparable())
throw Exception(ErrorCodes::DATA_TYPE_CANNOT_BE_USED_IN_KEY,
"Column {} with type {} is not allowed in key expression, it's not comparable",
backQuote(result.sample_block.getByPosition(i).name), result.data_types.back()->getName());
}
return result;
}

View File

@ -0,0 +1,9 @@
DROP TABLE IF EXISTS uncomparable_keys;
CREATE TABLE foo (id UInt64, key AggregateFunction(max, UInt64)) ENGINE MergeTree ORDER BY key; --{serverError 549}
CREATE TABLE foo (id UInt64, key AggregateFunction(max, UInt64)) ENGINE MergeTree PARTITION BY key; --{serverError 549}
CREATE TABLE foo (id UInt64, key AggregateFunction(max, UInt64)) ENGINE MergeTree ORDER BY (key) SAMPLE BY key; --{serverError 549}
DROP TABLE IF EXISTS uncomparable_keys;