@ -122,3 +122,26 @@ inline const std::string& Exception::to_string() const {
|
||||
return Status::Error<false>(e.code(), e.to_string()); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HANDLE_EXCEPTION_IF_CATCH_EXCEPTION(stmt, exception_handler) \
|
||||
do { \
|
||||
try { \
|
||||
doris::enable_thread_catch_bad_alloc++; \
|
||||
Defer defer {[&]() { doris::enable_thread_catch_bad_alloc--; }}; \
|
||||
{ \
|
||||
Status _status_ = (stmt); \
|
||||
if (UNLIKELY(!_status_.ok())) { \
|
||||
exception_handler(doris::Exception()); \
|
||||
return _status_; \
|
||||
} \
|
||||
} \
|
||||
} catch (const doris::Exception& e) { \
|
||||
exception_handler(e); \
|
||||
if (e.code() == doris::ErrorCode::MEM_ALLOC_FAILED) { \
|
||||
return Status::MemoryLimitExceeded(fmt::format( \
|
||||
"PreCatch error code:{}, {}, __FILE__:{}, __LINE__:{}, __FUNCTION__:{}", \
|
||||
e.code(), e.to_string(), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
|
||||
} \
|
||||
return Status::Error<false>(e.code(), e.to_string()); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
@ -1211,4 +1211,5 @@ RowsetSharedPtr Compaction::output_rowset() {
|
||||
return _output_rowset;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace doris
|
||||
|
||||
@ -115,9 +115,8 @@ public:
|
||||
|
||||
_filtered_rows = 0;
|
||||
_merged_rows = 0;
|
||||
|
||||
RETURN_IF_ERROR(_inner_process(rowset_reader, rowset_writer, new_tablet, base_tablet_schema,
|
||||
new_tablet_schema));
|
||||
RETURN_IF_ERROR_OR_CATCH_EXCEPTION(_inner_process(rowset_reader, rowset_writer, new_tablet,
|
||||
base_tablet_schema, new_tablet_schema));
|
||||
|
||||
// Check row num changes
|
||||
if (!_check_row_nums(rowset_reader, *rowset_writer)) {
|
||||
|
||||
@ -87,29 +87,4 @@ bool is_column_const(const IColumn& column) {
|
||||
return check_column<ColumnConst>(column);
|
||||
}
|
||||
|
||||
ColumnPtr IColumn::create_with_offsets(const Offsets64& offsets, const Field& default_field,
|
||||
size_t total_rows, size_t shift) const {
|
||||
if (offsets.size() + shift != size()) {
|
||||
LOG(FATAL) << fmt::format(
|
||||
"Incompatible sizes of offsets ({}), shift ({}) and size of column {}",
|
||||
offsets.size(), shift, size());
|
||||
}
|
||||
auto res = clone_empty();
|
||||
res->reserve(total_rows);
|
||||
ssize_t current_offset = -1;
|
||||
for (size_t i = 0; i < offsets.size(); ++i) {
|
||||
ssize_t offsets_diff = static_cast<ssize_t>(offsets[i]) - current_offset;
|
||||
current_offset = offsets[i];
|
||||
if (offsets_diff > 1) {
|
||||
res->insert_many(default_field, offsets_diff - 1);
|
||||
}
|
||||
res->insert_from(*this, i + shift);
|
||||
}
|
||||
ssize_t offsets_diff = static_cast<ssize_t>(total_rows) - current_offset;
|
||||
if (offsets_diff > 1) {
|
||||
res->insert_many(default_field, offsets_diff - 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace doris::vectorized
|
||||
|
||||
@ -125,13 +125,15 @@ public:
|
||||
/// If size is less current size, then data is cut.
|
||||
/// If size is greater, than default values are appended.
|
||||
virtual MutablePtr clone_resized(size_t s) const {
|
||||
LOG(FATAL) << "Cannot clone_resized() column " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method clone_resized is not supported for " + get_name());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// shrink the end zeros for CHAR type or ARRAY<CHAR> type
|
||||
virtual MutablePtr get_shrinked_column() {
|
||||
LOG(FATAL) << "Cannot get_shrinked_column() column " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method get_shrinked_column is not supported for " + get_name());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -189,7 +191,8 @@ public:
|
||||
}
|
||||
|
||||
virtual Int64 get_int(size_t /*n*/) const {
|
||||
LOG(FATAL) << "Method get_int is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method get_int is not supported for " + get_name());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -201,7 +204,8 @@ public:
|
||||
* Otherwise throw an exception.
|
||||
*/
|
||||
virtual bool get_bool(size_t /*n*/) const {
|
||||
LOG(FATAL) << "Method get_bool is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method get_bool is not supported for " + get_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -256,42 +260,51 @@ public:
|
||||
virtual void insert_data(const char* pos, size_t length) = 0;
|
||||
|
||||
virtual void insert_many_fix_len_data(const char* pos, size_t num) {
|
||||
LOG(FATAL) << "Method insert_many_fix_len_data is not supported for " << get_name();
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_fix_len_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
// todo(zeno) Use dict_args temp object to cover all arguments
|
||||
virtual void insert_many_dict_data(const int32_t* data_array, size_t start_index,
|
||||
const StringRef* dict, size_t data_num,
|
||||
uint32_t dict_num = 0) {
|
||||
LOG(FATAL) << "Method insert_many_dict_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_dict_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
virtual void insert_many_binary_data(char* data_array, uint32_t* len_array,
|
||||
uint32_t* start_offset_array, size_t num) {
|
||||
LOG(FATAL) << "Method insert_many_binary_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_binary_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
/// Insert binary data into column from a continuous buffer, the implementation maybe copy all binary data
|
||||
/// in one single time.
|
||||
virtual void insert_many_continuous_binary_data(const char* data, const uint32_t* offsets,
|
||||
const size_t num) {
|
||||
LOG(FATAL) << "Method insert_many_continuous_binary_data is not supported for "
|
||||
<< get_name();
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_continuous_binary_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
virtual void insert_many_strings(const StringRef* strings, size_t num) {
|
||||
LOG(FATAL) << "Method insert_many_binary_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_strings is not supported for " + get_name());
|
||||
}
|
||||
|
||||
virtual void insert_many_strings_overflow(const StringRef* strings, size_t num,
|
||||
size_t max_length) {
|
||||
LOG(FATAL) << "Method insert_many_strings_overflow is not supported for " << get_name();
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_strings_overflow is not supported for " + get_name());
|
||||
}
|
||||
|
||||
// Here `pos` points to the memory data type is the same as the data type of the column.
|
||||
// This function is used by `insert_keys_into_columns` in AggregationNode.
|
||||
virtual void insert_many_raw_data(const char* pos, size_t num) {
|
||||
LOG(FATAL) << "Method insert_many_raw_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method insert_many_raw_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
void insert_many_data(const char* pos, size_t length, size_t data_num) {
|
||||
@ -335,32 +348,39 @@ public:
|
||||
/// Return the size of largest row.
|
||||
/// This is for calculating the memory size for vectorized serialization of aggregation keys.
|
||||
virtual size_t get_max_row_byte_size() const {
|
||||
LOG(FATAL) << "get_max_row_byte_size not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method get_max_row_byte_size is not supported for " + get_name());
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void serialize_vec(std::vector<StringRef>& keys, size_t num_rows,
|
||||
size_t max_row_byte_size) const {
|
||||
LOG(FATAL) << "serialize_vec not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method serialize_vec is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
virtual void serialize_vec_with_null_map(std::vector<StringRef>& keys, size_t num_rows,
|
||||
const uint8_t* null_map) const {
|
||||
LOG(FATAL) << "serialize_vec_with_null_map not supported";
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method serialize_vec_with_null_map is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
// This function deserializes group-by keys into column in the vectorized way.
|
||||
virtual void deserialize_vec(std::vector<StringRef>& keys, const size_t num_rows) {
|
||||
LOG(FATAL) << "deserialize_vec not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method deserialize_vec is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
// Used in ColumnNullable::deserialize_vec
|
||||
virtual void deserialize_vec_with_null_map(std::vector<StringRef>& keys, const size_t num_rows,
|
||||
const uint8_t* null_map) {
|
||||
LOG(FATAL) << "deserialize_vec_with_null_map not supported";
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method deserialize_vec_with_null_map is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -369,7 +389,8 @@ public:
|
||||
/// On subsequent calls of this method for sequence of column values of arbitrary types,
|
||||
/// passed bytes to hash must identify sequence of values unambiguously.
|
||||
virtual void update_hash_with_value(size_t n, SipHash& hash) const {
|
||||
LOG(FATAL) << get_name() << " update_hash_with_value siphash not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method update_hash_with_value is not supported for " + get_name());
|
||||
}
|
||||
|
||||
/// Update state of hash function with value of n elements to avoid the virtual function call
|
||||
@ -378,13 +399,17 @@ public:
|
||||
/// do xxHash here, faster than other sip hash
|
||||
virtual void update_hashes_with_value(uint64_t* __restrict hashes,
|
||||
const uint8_t* __restrict null_data = nullptr) const {
|
||||
LOG(FATAL) << get_name() << " update_hashes_with_value xxhash not supported";
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method update_hashes_with_value is not supported for " + get_name());
|
||||
}
|
||||
|
||||
// use range for one hash value to avoid virtual function call in loop
|
||||
virtual void update_xxHash_with_value(size_t start, size_t end, uint64_t& hash,
|
||||
const uint8_t* __restrict null_data) const {
|
||||
LOG(FATAL) << get_name() << " update_hash_with_value xxhash not supported";
|
||||
throw doris::Exception(
|
||||
ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method update_xxHash_with_value is not supported for " + get_name());
|
||||
}
|
||||
|
||||
/// Update state of crc32 hash function with value of n elements to avoid the virtual function call
|
||||
@ -393,13 +418,15 @@ public:
|
||||
virtual void update_crcs_with_value(uint32_t* __restrict hash, PrimitiveType type,
|
||||
uint32_t rows, uint32_t offset = 0,
|
||||
const uint8_t* __restrict null_data = nullptr) const {
|
||||
LOG(FATAL) << get_name() << "update_crcs_with_value not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method update_crcs_with_value is not supported for " + get_name());
|
||||
}
|
||||
|
||||
// use range for one hash value to avoid virtual function call in loop
|
||||
virtual void update_crc_with_value(size_t start, size_t end, uint32_t& hash,
|
||||
const uint8_t* __restrict null_data) const {
|
||||
LOG(FATAL) << get_name() << " update_crc_with_value not supported";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method update_crc_with_value is not supported for " + get_name());
|
||||
}
|
||||
|
||||
/** Removes elements that don't match the filter.
|
||||
@ -425,10 +452,10 @@ public:
|
||||
* NOTICE: only column_nullable and predict_column, column_dictionary now support filter_by_selector
|
||||
*/
|
||||
virtual Status filter_by_selector(const uint16_t* sel, size_t sel_size, IColumn* col_ptr) {
|
||||
LOG(FATAL) << get_name()
|
||||
<< " do not support filter_by_selector, only column_nullable, column_dictionary "
|
||||
"and predict_column "
|
||||
"support";
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method filter_by_selector is not supported for {}, only "
|
||||
"column_nullable, column_dictionary and predict_column support",
|
||||
get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -501,14 +528,6 @@ public:
|
||||
void get_indices_of_non_default_rows_impl(IColumn::Offsets64& indices, size_t from,
|
||||
size_t limit) const;
|
||||
|
||||
/// Returns column with @total_size elements.
|
||||
/// In result column values from current column are at positions from @offsets.
|
||||
/// Other values are filled by @default_value.
|
||||
/// @shift means how much rows to skip from the beginning of current column.
|
||||
/// Used to create full column from sparse.
|
||||
virtual Ptr create_with_offsets(const Offsets64& offsets, const Field& default_field,
|
||||
size_t total_rows, size_t shift) const;
|
||||
|
||||
/** Split column to smaller columns. Each value goes to column index, selected by corresponding element of 'selector'.
|
||||
* Selector must contain values from 0 to num_columns - 1.
|
||||
* For default implementation, see scatter_impl.
|
||||
@ -552,7 +571,8 @@ public:
|
||||
/// Columns have equal structure.
|
||||
/// If true - you can use "compare_at", "insert_from", etc. methods.
|
||||
virtual bool structure_equals(const IColumn&) const {
|
||||
LOG(FATAL) << "Method structure_equals is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method structure_equals is not supported for " + get_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -588,10 +608,6 @@ public:
|
||||
|
||||
virtual bool is_hll() const { return false; }
|
||||
|
||||
virtual bool is_variant() const { return false; }
|
||||
|
||||
virtual bool is_quantile_state() const { return false; }
|
||||
|
||||
// true if column has null element
|
||||
virtual bool has_null() const { return false; }
|
||||
|
||||
@ -628,13 +644,15 @@ public:
|
||||
|
||||
/// If is_fixed_and_contiguous, returns the underlying data array, otherwise throws an exception.
|
||||
virtual StringRef get_raw_data() const {
|
||||
LOG(FATAL) << fmt::format("Column {} is not a contiguous block of memory", get_name());
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Column {} is not a contiguous block of memory", get_name());
|
||||
return StringRef {};
|
||||
}
|
||||
|
||||
/// If values_have_fixed_size, returns size of value, otherwise throw an exception.
|
||||
virtual size_t size_of_value_if_fixed() const {
|
||||
LOG(FATAL) << fmt::format("Values of column {} are not fixed size.", get_name());
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Values of column {} are not fixed size.", get_name());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ ColumnArray::ColumnArray(MutableColumnPtr&& nested_column, MutableColumnPtr&& of
|
||||
const ColumnOffsets* offsets_concrete = typeid_cast<const ColumnOffsets*>(offsets.get());
|
||||
|
||||
if (!offsets_concrete) {
|
||||
LOG(FATAL) << "offsets_column must be a ColumnUInt64";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "offsets_column must be a ColumnUInt64");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -101,8 +101,10 @@ ColumnArray::ColumnArray(MutableColumnPtr&& nested_column, MutableColumnPtr&& of
|
||||
|
||||
/// This will also prevent possible overflow in offset.
|
||||
if (data->size() != last_offset) {
|
||||
LOG(FATAL) << "offsets_column has data inconsistent with nested_column " << data->size()
|
||||
<< " " << last_offset;
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"nested_column's size {}, is not consistent with offsets_column's {}",
|
||||
data->size(), last_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +116,8 @@ ColumnArray::ColumnArray(MutableColumnPtr&& nested_column, MutableColumnPtr&& of
|
||||
|
||||
ColumnArray::ColumnArray(MutableColumnPtr&& nested_column) : data(std::move(nested_column)) {
|
||||
if (!data->empty()) {
|
||||
LOG(FATAL) << "Not empty data passed to ColumnArray, but no offsets passed";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Not empty data passed to ColumnArray, but no offsets passed");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -172,8 +175,10 @@ Field ColumnArray::operator[](size_t n) const {
|
||||
size_t size = size_at(n);
|
||||
|
||||
if (size > max_array_size_as_field)
|
||||
LOG(FATAL) << "Array of size " << size << " is too large to be manipulated as single field,"
|
||||
<< "maximum size " << max_array_size_as_field;
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"Array of size {}, is too large to be manipulated as single field, maximum size {}",
|
||||
size, max_array_size_as_field);
|
||||
|
||||
Array res(size);
|
||||
|
||||
@ -187,8 +192,10 @@ void ColumnArray::get(size_t n, Field& res) const {
|
||||
size_t size = size_at(n);
|
||||
|
||||
if (size > max_array_size_as_field)
|
||||
LOG(FATAL) << "Array of size " << size << " is too large to be manipulated as single field,"
|
||||
<< " maximum size " << max_array_size_as_field;
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"Array of size {}, is too large to be manipulated as single field, maximum size {}",
|
||||
size, max_array_size_as_field);
|
||||
|
||||
res = Array(size);
|
||||
Array& res_arr = doris::vectorized::get<Array&>(res);
|
||||
@ -227,8 +234,11 @@ bool ColumnArray::is_default_at(size_t n) const {
|
||||
void ColumnArray::insert_data(const char* pos, size_t length) {
|
||||
/** Similarly - only for arrays of fixed length values.
|
||||
*/
|
||||
if (!data->is_fixed_and_contiguous())
|
||||
LOG(FATAL) << "Method insert_data is not supported for " << get_name();
|
||||
if (!data->is_fixed_and_contiguous()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method insert_data should have_fixed_size, {} is not suitable",
|
||||
get_name());
|
||||
}
|
||||
|
||||
size_t field_size = data->size_of_value_if_fixed();
|
||||
|
||||
@ -240,7 +250,8 @@ void ColumnArray::insert_data(const char* pos, size_t length) {
|
||||
data->insert_data(pos, field_size);
|
||||
|
||||
if (pos != end)
|
||||
LOG(FATAL) << "Incorrect length argument for method ColumnArray::insert_data";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Incorrect length argument for method ColumnArray::insert_data");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -1103,7 +1114,8 @@ ColumnPtr ColumnArray::permute(const Permutation& perm, size_t limit) const {
|
||||
limit = std::min(size, limit);
|
||||
}
|
||||
if (perm.size() < limit) {
|
||||
LOG(FATAL) << "Size of permutation is less than required.";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation is less than required.");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
if (limit == 0) {
|
||||
|
||||
@ -230,7 +230,8 @@ public:
|
||||
const uint32_t* indices_end) override;
|
||||
|
||||
void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "Method replace_column_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR,
|
||||
"Method replace_column_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
void replace_column_data_default(size_t self_row = 0) override {
|
||||
|
||||
@ -50,7 +50,6 @@ public:
|
||||
|
||||
bool is_bitmap() const override { return std::is_same_v<T, BitmapValue>; }
|
||||
bool is_hll() const override { return std::is_same_v<T, HyperLogLog>; }
|
||||
bool is_quantile_state() const override { return std::is_same_v<T, QuantileState>; }
|
||||
|
||||
size_t size() const override { return data.size(); }
|
||||
|
||||
@ -81,7 +80,7 @@ public:
|
||||
} else if constexpr (std::is_same_v<T, QuantileState>) {
|
||||
pvalue->deserialize(Slice(pos, length));
|
||||
} else {
|
||||
LOG(FATAL) << "Unexpected type in column complex";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Unexpected type in column complex");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
@ -176,12 +175,12 @@ public:
|
||||
}
|
||||
|
||||
[[noreturn]] bool get_bool(size_t n) const override {
|
||||
LOG(FATAL) << "get field not implemented";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "get field not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] Int64 get_int(size_t n) const override {
|
||||
LOG(FATAL) << "get field not implemented";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "get field not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -208,12 +207,14 @@ public:
|
||||
// it's impossible to use ComplexType as key , so we don't have to implement them
|
||||
[[noreturn]] StringRef serialize_value_into_arena(size_t n, Arena& arena,
|
||||
char const*& begin) const override {
|
||||
LOG(FATAL) << "serialize_value_into_arena not implemented";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"serialize_value_into_arena not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] const char* deserialize_and_insert_from_arena(const char* pos) override {
|
||||
LOG(FATAL) << "deserialize_and_insert_from_arena not implemented";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"deserialize_and_insert_from_arena not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -365,7 +366,8 @@ ColumnPtr ColumnComplexType<T>::permute(const IColumn::Permutation& perm, size_t
|
||||
limit = limit ? std::min(size, limit) : size;
|
||||
|
||||
if (perm.size() < limit) {
|
||||
LOG(FATAL) << "Size of permutation is less than required.";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation is less than required.");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,8 @@ ColumnConst::ColumnConst(const ColumnPtr& data_, size_t s_) : data(data_), s(s_)
|
||||
}
|
||||
|
||||
if (data->size() != 1) {
|
||||
LOG(FATAL) << fmt::format(
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"Incorrect size of nested column in constructor of ColumnConst: {}, must be 1.",
|
||||
data->size());
|
||||
}
|
||||
@ -86,8 +87,9 @@ ColumnPtr ColumnConst::permute(const Permutation& perm, size_t limit) const {
|
||||
}
|
||||
|
||||
if (perm.size() < limit) {
|
||||
LOG(FATAL) << fmt::format("Size of permutation ({}) is less than required ({})",
|
||||
perm.size(), limit);
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation ({}) is less than required ({})", perm.size(),
|
||||
limit);
|
||||
}
|
||||
|
||||
return ColumnConst::create(data, limit);
|
||||
|
||||
@ -235,7 +235,9 @@ template <typename T>
|
||||
ColumnPtr ColumnDecimal<T>::permute(const IColumn::Permutation& perm, size_t limit) const {
|
||||
size_t size = limit ? std::min(data.size(), limit) : data.size();
|
||||
if (perm.size() < size) {
|
||||
LOG(FATAL) << "Size of permutation is less than required.";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation ({}) is less than required ({})", perm.size(),
|
||||
limit);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -66,35 +66,39 @@ public:
|
||||
size_t size() const override { return _codes.size(); }
|
||||
|
||||
[[noreturn]] StringRef get_data_at(size_t n) const override {
|
||||
LOG(FATAL) << "get_data_at not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get_data_at not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_from(const IColumn& src, size_t n) override {
|
||||
LOG(FATAL) << "insert_from not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert_from not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_range_from(const IColumn& src, size_t start, size_t length) override {
|
||||
LOG(FATAL) << "insert_range_from not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert_range_from not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_indices_from(const IColumn& src, const uint32_t* indices_begin,
|
||||
const uint32_t* indices_end) override {
|
||||
LOG(FATAL) << "insert_indices_from not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert_indices_from not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void pop_back(size_t n) override { LOG(FATAL) << "pop_back not supported in ColumnDictionary"; }
|
||||
|
||||
void update_hash_with_value(size_t n, SipHash& hash) const override {
|
||||
LOG(FATAL) << "update_hash_with_value not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"update_hash_with_value not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_data(const char* pos, size_t /*length*/) override {
|
||||
LOG(FATAL) << "insert_data not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert_data not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -113,7 +117,14 @@ public:
|
||||
|
||||
void get_permutation(bool reverse, size_t limit, int nan_direction_hint,
|
||||
IColumn::Permutation& res) const override {
|
||||
LOG(FATAL) << "get_permutation not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get_permutation not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void pop_back(size_t n) override {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"pop_back not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -127,7 +138,8 @@ public:
|
||||
}
|
||||
|
||||
void insert(const Field& x) override {
|
||||
LOG(FATAL) << "insert not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -142,18 +154,22 @@ public:
|
||||
// it's impossible to use ComplexType as key , so we don't have to implement them
|
||||
[[noreturn]] StringRef serialize_value_into_arena(size_t n, Arena& arena,
|
||||
char const*& begin) const override {
|
||||
LOG(FATAL) << "serialize_value_into_arena not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"serialize_value_into_arena not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] const char* deserialize_and_insert_from_arena(const char* pos) override {
|
||||
LOG(FATAL) << "deserialize_and_insert_from_arena not supported in ColumnDictionary";
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"deserialize_and_insert_from_arena not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] int compare_at(size_t n, size_t m, const IColumn& rhs,
|
||||
int nan_direction_hint) const override {
|
||||
LOG(FATAL) << "compare_at not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"compare_at not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -161,52 +177,61 @@ public:
|
||||
|
||||
void get_indices_of_non_default_rows(IColumn::Offsets64& indices, size_t from,
|
||||
size_t limit) const override {
|
||||
LOG(FATAL) << "get_indices_of_non_default_rows not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get_indices_of_non_default_rows not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
size_t size_of_value_if_fixed() const override { return sizeof(T); }
|
||||
|
||||
[[noreturn]] StringRef get_raw_data() const override {
|
||||
LOG(FATAL) << "get_raw_data not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get_raw_data not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] bool structure_equals(const IColumn& rhs) const override {
|
||||
LOG(FATAL) << "structure_equals not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"structure_equals not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] ColumnPtr filter(const IColumn::Filter& filt,
|
||||
ssize_t result_size_hint) const override {
|
||||
LOG(FATAL) << "filter not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"filter not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] size_t filter(const IColumn::Filter&) override {
|
||||
LOG(FATAL) << "filter not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"filter not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] ColumnPtr permute(const IColumn::Permutation& perm, size_t limit) const override {
|
||||
LOG(FATAL) << "permute not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"permute not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] ColumnPtr replicate(const IColumn::Offsets& replicate_offsets) const override {
|
||||
LOG(FATAL) << "replicate not supported in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"replicate not supported in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void append_data_by_selector(MutableColumnPtr& res,
|
||||
const IColumn::Selector& selector) const override {
|
||||
LOG(FATAL) << "append_data_by_selector is not supported in ColumnDictionary!";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"append_data_by_selector is not supported in ColumnDictionary!");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void append_data_by_selector(MutableColumnPtr& res, const IColumn::Selector& selector,
|
||||
size_t begin, size_t end) const override {
|
||||
LOG(FATAL) << "append_data_by_selector is not supported in ColumnDictionary!";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"append_data_by_selector is not supported in ColumnDictionary!");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -232,7 +257,8 @@ public:
|
||||
}
|
||||
|
||||
void replace_column_data(const IColumn&, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "should not call replace_column_data in ColumnDictionary";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call replace_column_data in ColumnDictionary");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -47,16 +47,17 @@ public:
|
||||
int compare_at(size_t, size_t, const IColumn&, int) const override { return 0; }
|
||||
|
||||
[[noreturn]] Field operator[](size_t) const override {
|
||||
LOG(FATAL) << "Cannot get value from " << get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Cannot get value from {}", get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void get(size_t, Field&) const override {
|
||||
LOG(FATAL) << "Cannot get value from " << get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Cannot get value from {}", get_name());
|
||||
}
|
||||
|
||||
void insert(const Field&) override {
|
||||
LOG(FATAL) << "Cannot insert element into " << get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Cannot insert element into {}",
|
||||
get_name());
|
||||
}
|
||||
|
||||
StringRef get_data_at(size_t) const override { return {}; }
|
||||
@ -98,7 +99,8 @@ public:
|
||||
|
||||
ColumnPtr permute(const Permutation& perm, size_t limit) const override {
|
||||
if (s != perm.size()) {
|
||||
LOG(FATAL) << "Size of permutation doesn't match size of column.";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation doesn't match size of column.");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -122,8 +124,9 @@ public:
|
||||
size_t num_rows = size();
|
||||
|
||||
if (num_rows < selector.size()) {
|
||||
LOG(FATAL) << fmt::format("Size of selector: {}, is larger than size of column:{}",
|
||||
selector.size(), num_rows);
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of selector: {}, is larger than size of column:{}",
|
||||
selector.size(), num_rows);
|
||||
}
|
||||
|
||||
res->reserve(num_rows);
|
||||
@ -136,8 +139,9 @@ public:
|
||||
size_t num_rows = size();
|
||||
|
||||
if (num_rows < selector.size()) {
|
||||
LOG(FATAL) << fmt::format("Size of selector: {}, is larger than size of column:{}",
|
||||
selector.size(), num_rows);
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of selector: {}, is larger than size of column:{}",
|
||||
selector.size(), num_rows);
|
||||
}
|
||||
|
||||
res->reserve(num_rows);
|
||||
@ -148,7 +152,8 @@ public:
|
||||
void addSize(size_t delta) { s += delta; }
|
||||
|
||||
void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "should not call the method in column dummy";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call the method in column dummy");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -38,8 +38,9 @@ void IColumn::append_data_by_selector_impl(MutablePtr& res, const Selector& sele
|
||||
size_t num_rows = size();
|
||||
|
||||
if (num_rows < selector.size()) {
|
||||
LOG(FATAL) << fmt::format("Size of selector: {}, is larger than size of column:{}",
|
||||
selector.size(), num_rows);
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Size of selector: {} is larger than size of column: {}",
|
||||
selector.size(), num_rows);
|
||||
}
|
||||
|
||||
res->reserve(num_rows);
|
||||
|
||||
@ -50,8 +50,8 @@ ColumnMap::ColumnMap(MutableColumnPtr&& keys, MutableColumnPtr&& values, Mutable
|
||||
const COffsets* offsets_concrete = typeid_cast<const COffsets*>(offsets_column.get());
|
||||
|
||||
if (!offsets_concrete) {
|
||||
LOG(FATAL) << "offsets_column must be a ColumnUInt64";
|
||||
__builtin_unreachable();
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"offsets_column must be a ColumnUInt64.");
|
||||
}
|
||||
|
||||
if (!offsets_concrete->empty() && keys_column && values_column) {
|
||||
@ -59,12 +59,16 @@ ColumnMap::ColumnMap(MutableColumnPtr&& keys, MutableColumnPtr&& values, Mutable
|
||||
|
||||
/// This will also prevent possible overflow in offset.
|
||||
if (keys_column->size() != last_offset) {
|
||||
LOG(FATAL) << "offsets_column has data inconsistent with key_column "
|
||||
<< keys_column->size() << " " << last_offset;
|
||||
throw doris::Exception(
|
||||
doris::ErrorCode::INTERNAL_ERROR,
|
||||
"offsets_column size {} has data inconsistent with key_column {}", last_offset,
|
||||
keys_column->size());
|
||||
}
|
||||
if (values_column->size() != last_offset) {
|
||||
LOG(FATAL) << "offsets_column has data inconsistent with value_column "
|
||||
<< values_column->size() << " " << last_offset;
|
||||
throw doris::Exception(
|
||||
doris::ErrorCode::INTERNAL_ERROR,
|
||||
"offsets_column size {} has data inconsistent with value_column {}",
|
||||
last_offset, values_column->size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,9 +110,10 @@ Field ColumnMap::operator[](size_t n) const {
|
||||
size_t element_size = size_at(n);
|
||||
|
||||
if (element_size > max_array_size_as_field) {
|
||||
LOG(FATAL) << "element size " << start_offset
|
||||
<< " is too large to be manipulated as single map field,"
|
||||
<< "maximum size " << max_array_size_as_field;
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"element size {} is too large to be manipulated as single map "
|
||||
"field, maximum size {}",
|
||||
element_size, max_array_size_as_field);
|
||||
}
|
||||
|
||||
Array k(element_size), v(element_size);
|
||||
@ -127,11 +132,13 @@ void ColumnMap::get(size_t n, Field& res) const {
|
||||
}
|
||||
|
||||
StringRef ColumnMap::get_data_at(size_t n) const {
|
||||
LOG(FATAL) << "Method get_data_at is not supported for " << get_name();
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"Method get_data_at is not supported for {}", get_name());
|
||||
}
|
||||
|
||||
void ColumnMap::insert_data(const char*, size_t) {
|
||||
LOG(FATAL) << "Method insert_data is not supported for " << get_name();
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"Method insert_data is not supported for {}", get_name());
|
||||
}
|
||||
|
||||
void ColumnMap::insert(const Field& x) {
|
||||
|
||||
@ -142,7 +142,8 @@ public:
|
||||
}
|
||||
|
||||
void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "Method replace_column_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method replace_column_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
void replace_column_data_default(size_t self_row = 0) override {
|
||||
|
||||
@ -43,7 +43,8 @@ ColumnNullable::ColumnNullable(MutableColumnPtr&& nested_column_, MutableColumnP
|
||||
}
|
||||
|
||||
if (is_column_const(*null_map)) {
|
||||
LOG(FATAL) << "ColumnNullable cannot have constant null map";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"ColumnNullable cannot have constant null map");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
_need_update_has_null = true;
|
||||
@ -571,7 +572,8 @@ void ColumnNullable::apply_null_map_impl(const ColumnUInt8& map) {
|
||||
const NullMap& arr2 = map.get_data();
|
||||
|
||||
if (arr1.size() != arr2.size()) {
|
||||
LOG(FATAL) << "Inconsistent sizes of ColumnNullable objects";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Inconsistent sizes of ColumnNullable objects");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -594,8 +596,8 @@ void ColumnNullable::apply_null_map(const ColumnNullable& other) {
|
||||
|
||||
void ColumnNullable::check_consistency() const {
|
||||
if (null_map->size() != get_nested_column().size()) {
|
||||
LOG(FATAL) << "Logical error: Sizes of nested column and null map of Nullable column are "
|
||||
"not equal";
|
||||
throw Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Sizes of nested column and null map of Nullable column are not equal");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -416,7 +416,12 @@ void ColumnObject::Subcolumn::insert(Field field, FieldInfo info) {
|
||||
}
|
||||
|
||||
void ColumnObject::Subcolumn::insertRangeFrom(const Subcolumn& src, size_t start, size_t length) {
|
||||
assert(start + length <= src.size());
|
||||
if (start + length > src.size()) {
|
||||
throw doris::Exception(
|
||||
ErrorCode::OUT_OF_BOUND,
|
||||
"Invalid range for insertRangeFrom: start={}, length={}, src.size={}", start,
|
||||
length, src.size());
|
||||
}
|
||||
size_t end = start + length;
|
||||
// num_rows += length;
|
||||
if (data.empty()) {
|
||||
@ -439,7 +444,12 @@ void ColumnObject::Subcolumn::insertRangeFrom(const Subcolumn& src, size_t start
|
||||
}
|
||||
auto insert_from_part = [&](const auto& column, const auto& column_type, size_t from,
|
||||
size_t n) {
|
||||
assert(from + n <= column->size());
|
||||
if (from + n > column->size()) {
|
||||
throw doris::Exception(
|
||||
ErrorCode::OUT_OF_BOUND,
|
||||
"Invalid range for insertRangeFrom: from={}, n={}, column.size={}", from, n,
|
||||
column->size());
|
||||
}
|
||||
if (column_type->equals(*least_common_type.get())) {
|
||||
data.back()->insert_range_from(*column, from, n);
|
||||
return;
|
||||
@ -604,7 +614,10 @@ void ColumnObject::Subcolumn::insertManyDefaults(size_t length) {
|
||||
}
|
||||
|
||||
void ColumnObject::Subcolumn::pop_back(size_t n) {
|
||||
assert(n <= size());
|
||||
if (n > size()) {
|
||||
throw doris::Exception(ErrorCode::OUT_OF_BOUND,
|
||||
"Invalid number of elements to pop: {}, size: {}", n, size());
|
||||
}
|
||||
size_t num_removed = 0;
|
||||
for (auto it = data.rbegin(); it != data.rend(); ++it) {
|
||||
if (n == 0) {
|
||||
@ -625,37 +638,38 @@ void ColumnObject::Subcolumn::pop_back(size_t n) {
|
||||
num_of_defaults_in_prefix -= n;
|
||||
}
|
||||
|
||||
Field ColumnObject::Subcolumn::get_last_field() const {
|
||||
if (data.empty()) {
|
||||
return Field();
|
||||
}
|
||||
const auto& last_part = data.back();
|
||||
assert(!last_part->empty());
|
||||
return (*last_part)[last_part->size() - 1];
|
||||
}
|
||||
|
||||
IColumn& ColumnObject::Subcolumn::get_finalized_column() {
|
||||
assert(is_finalized());
|
||||
if (!is_finalized()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Subcolumn is not finalized");
|
||||
}
|
||||
return *data[0];
|
||||
}
|
||||
|
||||
const IColumn& ColumnObject::Subcolumn::get_finalized_column() const {
|
||||
assert(is_finalized());
|
||||
if (!is_finalized()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Subcolumn is not finalized");
|
||||
}
|
||||
return *data[0];
|
||||
}
|
||||
|
||||
const ColumnPtr& ColumnObject::Subcolumn::get_finalized_column_ptr() const {
|
||||
assert(is_finalized());
|
||||
if (!is_finalized()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Subcolumn is not finalized");
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
|
||||
ColumnPtr& ColumnObject::Subcolumn::get_finalized_column_ptr() {
|
||||
assert(is_finalized());
|
||||
if (!is_finalized()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Subcolumn is not finalized");
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
|
||||
void ColumnObject::Subcolumn::remove_nullable() {
|
||||
assert(is_finalized());
|
||||
if (!is_finalized()) {
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR, "Subcolumn is not finalized");
|
||||
}
|
||||
data[0] = doris::vectorized::remove_nullable(data[0]);
|
||||
least_common_type.remove_nullable();
|
||||
}
|
||||
@ -882,19 +896,6 @@ void ColumnObject::get(size_t n, Field& res) const {
|
||||
}
|
||||
}
|
||||
|
||||
Status ColumnObject::try_insert_indices_from(const IColumn& src, const int* indices_begin,
|
||||
const int* indices_end) {
|
||||
for (auto x = indices_begin; x != indices_end; ++x) {
|
||||
if (*x == -1) {
|
||||
ColumnObject::insert_default();
|
||||
} else {
|
||||
ColumnObject::insert_from(src, *x);
|
||||
}
|
||||
}
|
||||
finalize();
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void ColumnObject::insert_range_from(const IColumn& src, size_t start, size_t length) {
|
||||
#ifndef NDEBUG
|
||||
check_consistency();
|
||||
@ -1457,17 +1458,6 @@ ColumnPtr get_base_column_of_array(const ColumnPtr& column) {
|
||||
return column;
|
||||
}
|
||||
|
||||
void ColumnObject::strip_outer_array() {
|
||||
assert(is_finalized());
|
||||
Subcolumns new_subcolumns;
|
||||
for (auto&& entry : subcolumns) {
|
||||
auto base_column = get_base_column_of_array(entry->data.get_finalized_column_ptr());
|
||||
new_subcolumns.add(entry->path, Subcolumn {base_column->assume_mutable(), is_nullable});
|
||||
num_rows = base_column->size();
|
||||
}
|
||||
std::swap(subcolumns, new_subcolumns);
|
||||
}
|
||||
|
||||
ColumnPtr ColumnObject::filter(const Filter& filter, ssize_t count) const {
|
||||
if (!is_finalized()) {
|
||||
auto finalized = clone_finalized();
|
||||
@ -1559,15 +1549,6 @@ void ColumnObject::clear() {
|
||||
_prev_positions.clear();
|
||||
}
|
||||
|
||||
void ColumnObject::revise_to(int target_num_rows) {
|
||||
for (auto&& entry : subcolumns) {
|
||||
if (entry->data.size() > target_num_rows) {
|
||||
entry->data.pop_back(entry->data.size() - target_num_rows);
|
||||
}
|
||||
}
|
||||
num_rows = target_num_rows;
|
||||
}
|
||||
|
||||
void ColumnObject::create_root() {
|
||||
auto type = is_nullable ? make_nullable(std::make_shared<MostCommonType>())
|
||||
: std::make_shared<MostCommonType>();
|
||||
@ -1614,17 +1595,6 @@ DataTypePtr ColumnObject::get_root_type() const {
|
||||
subcolumns.get_root()->data.get_least_common_type()->get_name(), path.get_path()); \
|
||||
}
|
||||
|
||||
Status ColumnObject::extract_root(const PathInData& path) {
|
||||
SANITIZE_ROOT();
|
||||
if (!path.empty()) {
|
||||
MutableColumnPtr extracted;
|
||||
RETURN_IF_ERROR(schema_util::extract(subcolumns.get_root()->data.get_finalized_column_ptr(),
|
||||
path, extracted));
|
||||
subcolumns.get_mutable_root()->data.data[0] = extracted->get_ptr();
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status ColumnObject::extract_root(const PathInData& path, MutableColumnPtr& dst) const {
|
||||
SANITIZE_ROOT();
|
||||
if (!path.empty()) {
|
||||
|
||||
@ -149,9 +149,6 @@ public:
|
||||
|
||||
bool check_if_sparse_column(size_t num_rows);
|
||||
|
||||
/// Returns last inserted field.
|
||||
Field get_last_field() const;
|
||||
|
||||
/// Returns single column if subcolumn in finalizes.
|
||||
/// Otherwise -- undefined behaviour.
|
||||
IColumn& get_finalized_column();
|
||||
@ -289,8 +286,6 @@ public:
|
||||
|
||||
DataTypePtr get_root_type() const;
|
||||
|
||||
bool is_variant() const override { return true; }
|
||||
|
||||
// return null if not found
|
||||
const Subcolumn* get_subcolumn(const PathInData& key) const;
|
||||
|
||||
@ -412,9 +407,6 @@ public:
|
||||
|
||||
void insert_default() override;
|
||||
|
||||
// Revise this column to specified num_rows
|
||||
void revise_to(int num_rows);
|
||||
|
||||
ColumnPtr replicate(const Offsets& offsets) const override;
|
||||
|
||||
void pop_back(size_t length) override;
|
||||
@ -423,9 +415,6 @@ public:
|
||||
|
||||
void get(size_t n, Field& res) const override;
|
||||
|
||||
Status try_insert_indices_from(const IColumn& src, const int* indices_begin,
|
||||
const int* indices_end);
|
||||
|
||||
void update_hash_with_value(size_t n, SipHash& hash) const override;
|
||||
|
||||
ColumnPtr filter(const Filter&, ssize_t) const override;
|
||||
@ -456,15 +445,9 @@ public:
|
||||
|
||||
void for_each_imutable_subcolumn(ImutableColumnCallback callback) const;
|
||||
|
||||
// Extract path from root column and replace root with new extracted column,
|
||||
// root must be jsonb type
|
||||
Status extract_root(const PathInData& path);
|
||||
|
||||
// Extract path from root column and output to dst
|
||||
Status extract_root(const PathInData& path, MutableColumnPtr& dst) const;
|
||||
|
||||
void strip_outer_array();
|
||||
|
||||
bool empty() const;
|
||||
|
||||
// Check if all columns and types are aligned
|
||||
|
||||
@ -295,7 +295,8 @@ ColumnPtr ColumnStr<T>::permute(const IColumn::Permutation& perm, size_t limit)
|
||||
}
|
||||
|
||||
if (perm.size() < limit) {
|
||||
LOG(FATAL) << "Size of permutation is less than required.";
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation is less than required.");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -100,8 +100,9 @@ private:
|
||||
chars(src.chars.begin(), src.chars.end()) {}
|
||||
|
||||
public:
|
||||
void sanity_check() const;
|
||||
bool is_variable_length() const override { return true; }
|
||||
// used in string ut testd
|
||||
void sanity_check() const;
|
||||
const char* get_family_name() const override { return "String"; }
|
||||
|
||||
size_t size() const override { return offsets.size(); }
|
||||
@ -547,7 +548,8 @@ public:
|
||||
}
|
||||
|
||||
void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "Method replace_column_data is not supported for ColumnString";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method replace_column_data is not supported for ColumnString");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +53,8 @@ ColumnStruct::ColumnStruct(MutableColumns&& mutable_columns) {
|
||||
columns.reserve(mutable_columns.size());
|
||||
for (auto& column : mutable_columns) {
|
||||
if (is_column_const(*column)) {
|
||||
LOG(FATAL) << "ColumnStruct cannot have ColumnConst as its element";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"ColumnStruct cannot have ColumnConst as its element");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
columns.push_back(std::move(column));
|
||||
@ -63,7 +64,8 @@ ColumnStruct::ColumnStruct(MutableColumns&& mutable_columns) {
|
||||
ColumnStruct::Ptr ColumnStruct::create(const Columns& columns) {
|
||||
for (const auto& column : columns) {
|
||||
if (is_column_const(*column)) {
|
||||
LOG(FATAL) << "ColumnStruct cannot have ColumnConst as its element";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"ColumnStruct cannot have ColumnConst as its element");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
@ -75,7 +77,8 @@ ColumnStruct::Ptr ColumnStruct::create(const Columns& columns) {
|
||||
ColumnStruct::Ptr ColumnStruct::create(const TupleColumns& tuple_columns) {
|
||||
for (const auto& column : tuple_columns) {
|
||||
if (is_column_const(*column)) {
|
||||
LOG(FATAL) << "ColumnStruct cannot have ColumnConst as its element";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"ColumnStruct cannot have ColumnConst as its element");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
@ -134,8 +137,10 @@ void ColumnStruct::insert(const Field& x) {
|
||||
const auto& tuple = x.get<const Tuple&>();
|
||||
const size_t tuple_size = columns.size();
|
||||
if (tuple.size() != tuple_size) {
|
||||
LOG(FATAL) << "Cannot insert value of different size into tuple. field tuple size"
|
||||
<< tuple.size() << ", columns size " << tuple_size;
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Cannot insert value of different size into tuple. field tuple size "
|
||||
"{}, columns size {}",
|
||||
tuple.size(), tuple_size);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tuple_size; ++i) {
|
||||
@ -148,7 +153,8 @@ void ColumnStruct::insert_from(const IColumn& src_, size_t n) {
|
||||
|
||||
const size_t tuple_size = columns.size();
|
||||
if (src.columns.size() != tuple_size) {
|
||||
LOG(FATAL) << "Cannot insert value of different size into tuple.";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Cannot insert value of different size into tuple.");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -95,11 +95,13 @@ public:
|
||||
|
||||
bool is_default_at(size_t n) const override;
|
||||
[[noreturn]] StringRef get_data_at(size_t n) const override {
|
||||
LOG(FATAL) << "Method get_data_at is not supported for " + get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method get_data_at is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
[[noreturn]] void insert_data(const char* pos, size_t length) override {
|
||||
LOG(FATAL) << "Method insert_data is not supported for " + get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method insert_data is not supported for " + get_name());
|
||||
__builtin_unreachable();
|
||||
}
|
||||
void insert(const Field& x) override;
|
||||
@ -138,7 +140,8 @@ public:
|
||||
return append_data_by_selector_impl<ColumnStruct>(res, selector, begin, end);
|
||||
}
|
||||
void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "Method replace_column_data is not supported for " << get_name();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method replace_column_data is not supported for " + get_name());
|
||||
}
|
||||
|
||||
void replace_column_data_default(size_t self_row = 0) override {
|
||||
|
||||
@ -494,7 +494,9 @@ ColumnPtr ColumnVector<T>::permute(const IColumn::Permutation& perm, size_t limi
|
||||
limit = std::min(size, limit);
|
||||
|
||||
if (perm.size() < limit) {
|
||||
LOG(FATAL) << "Size of permutation is less than required.";
|
||||
throw doris::Exception(doris::ErrorCode::INTERNAL_ERROR,
|
||||
"Size of permutation ({}) is less than required ({})", perm.size(),
|
||||
limit);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
@ -182,7 +182,8 @@ public:
|
||||
data[old_size + i] = begin + i;
|
||||
}
|
||||
} else {
|
||||
LOG(FATAL) << "double column not support insert_range_of_integer";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"double column not support insert_range_of_integer");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,34 +114,41 @@ public:
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
LOG(FATAL) << "should not call get_data_at in predicate column except for string type";
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"should not call get_data_at in predicate column except for string type");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void insert_from(const IColumn& src, size_t n) override {
|
||||
LOG(FATAL) << "insert_from not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call insert_from in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_range_from(const IColumn& src, size_t start, size_t length) override {
|
||||
LOG(FATAL) << "insert_range_from not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call insert_range_from in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void insert_indices_from(const IColumn& src, const uint32_t* indices_begin,
|
||||
const uint32_t* indices_end) override {
|
||||
LOG(FATAL) << "insert_indices_from not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call insert_indices_from in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void pop_back(size_t n) override {
|
||||
LOG(FATAL) << "pop_back not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call pop_back in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void update_hash_with_value(size_t n, SipHash& hash) const override {
|
||||
LOG(FATAL) << "update_hash_with_value not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call update_hash_with_value in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -311,7 +318,8 @@ public:
|
||||
CHECK(destination - org_dst == total_mem_size)
|
||||
<< "Copied size not equal to expected size";
|
||||
} else {
|
||||
LOG(FATAL) << "Method insert_many_binary_data is not supported";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"Method insert_many_binary_data is not supported");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
@ -345,18 +353,20 @@ public:
|
||||
}
|
||||
|
||||
void insert(const Field& x) override {
|
||||
LOG(FATAL) << "insert not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"insert not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] Field operator[](size_t n) const override {
|
||||
LOG(FATAL) << "operator[] not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"operator[] not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void get(size_t n, Field& res) const override {
|
||||
LOG(FATAL) << "get field not supported in PredicateColumnType";
|
||||
__builtin_unreachable();
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get field not supported in PredicateColumnType");
|
||||
}
|
||||
|
||||
[[noreturn]] UInt64 get64(size_t n) const override {
|
||||
@ -375,24 +385,29 @@ public:
|
||||
}
|
||||
|
||||
[[noreturn]] bool get_bool(size_t n) const override {
|
||||
LOG(FATAL) << "get field not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get field not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] Int64 get_int(size_t n) const override {
|
||||
LOG(FATAL) << "get field not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get field not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
// it's impossible to use ComplexType as key , so we don't have to implement them
|
||||
[[noreturn]] StringRef serialize_value_into_arena(size_t n, Arena& arena,
|
||||
char const*& begin) const override {
|
||||
LOG(FATAL) << "serialize_value_into_arena not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"serialize_value_into_arena not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] const char* deserialize_and_insert_from_arena(const char* pos) override {
|
||||
LOG(FATAL) << "deserialize_and_insert_from_arena not supported in PredicateColumnType";
|
||||
throw doris::Exception(
|
||||
ErrorCode::INTERNAL_ERROR,
|
||||
"deserialize_and_insert_from_arena not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -406,28 +421,33 @@ public:
|
||||
size_t size_of_value_if_fixed() const override { return sizeof(T); }
|
||||
|
||||
[[noreturn]] StringRef get_raw_data() const override {
|
||||
LOG(FATAL) << "get_raw_data not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"get_raw_data not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] bool structure_equals(const IColumn& rhs) const override {
|
||||
LOG(FATAL) << "structure_equals not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"structure_equals not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] ColumnPtr filter(const IColumn::Filter& filt,
|
||||
ssize_t result_size_hint) const override {
|
||||
LOG(FATAL) << "filter not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"filter not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] size_t filter(const IColumn::Filter&) override {
|
||||
LOG(FATAL) << "filter not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"filter not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
[[noreturn]] ColumnPtr permute(const IColumn::Permutation& perm, size_t limit) const override {
|
||||
LOG(FATAL) << "permute not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"permute not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -436,18 +456,21 @@ public:
|
||||
const Container& get_data() const { return data; }
|
||||
|
||||
[[noreturn]] ColumnPtr replicate(const IColumn::Offsets& replicate_offsets) const override {
|
||||
LOG(FATAL) << "replicate not supported in PredicateColumnType";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"replicate not supported in PredicateColumnType");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void append_data_by_selector(MutableColumnPtr& res,
|
||||
const IColumn::Selector& selector) const override {
|
||||
LOG(FATAL) << "append_data_by_selector is not supported in PredicateColumnType!";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"append_data_by_selector is not supported in PredicateColumnType!");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
void append_data_by_selector(MutableColumnPtr& res, const IColumn::Selector& selector,
|
||||
size_t begin, size_t end) const override {
|
||||
LOG(FATAL) << "append_data_by_selector is not supported in PredicateColumnType!";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"append_data_by_selector is not supported in PredicateColumnType!");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@ -464,7 +487,8 @@ public:
|
||||
}
|
||||
|
||||
void replace_column_data(const IColumn&, size_t row, size_t self_row = 0) override {
|
||||
LOG(FATAL) << "should not call replace_column_data in predicate column";
|
||||
throw doris::Exception(ErrorCode::INTERNAL_ERROR,
|
||||
"should not call replace_column_data in predicate column");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user