[Fix](array-type) bugfix for array column with delete condition (#13361)

Fix for SQL with array column:
delete from tbl where c_array is null;

more info please refer to #13360

Co-authored-by: cambyzju <zhuxiaoli01@baidu.com>
This commit is contained in:
camby
2022-10-21 09:29:02 +08:00
committed by GitHub
parent 27d84eafc5
commit 1f7829e099
7 changed files with 78 additions and 8 deletions

View File

@ -1081,8 +1081,8 @@ Status SegmentIterator::next_batch(vectorized::Block* block) {
auto cid = _schema.column_id(i);
auto column_desc = _schema.column(cid);
if (_is_pred_column[cid]) {
_current_return_columns[cid] = Schema::get_predicate_column_nullable_ptr(
column_desc->type(), column_desc->is_nullable());
_current_return_columns[cid] =
Schema::get_predicate_column_nullable_ptr(*column_desc);
_current_return_columns[cid]->reserve(_opts.block_row_max);
} else if (i >= block->columns()) {
// if i >= block->columns means the column and not the pred_column means `column i` is

View File

@ -114,10 +114,13 @@ vectorized::DataTypePtr Schema::get_data_type_ptr(const Field& field) {
return vectorized::DataTypeFactory::instance().create_data_type(field);
}
vectorized::IColumn::MutablePtr Schema::get_predicate_column_nullable_ptr(FieldType type,
bool is_null) {
vectorized::IColumn::MutablePtr ptr = Schema::get_predicate_column_ptr(type);
if (is_null) {
vectorized::IColumn::MutablePtr Schema::get_predicate_column_nullable_ptr(const Field& field) {
if (UNLIKELY(field.type() == OLAP_FIELD_TYPE_ARRAY)) {
return get_data_type_ptr(field)->create_column();
}
vectorized::IColumn::MutablePtr ptr = Schema::get_predicate_column_ptr(field.type());
if (field.is_nullable()) {
return doris::vectorized::ColumnNullable::create(std::move(ptr),
doris::vectorized::ColumnUInt8::create());
}

View File

@ -112,8 +112,7 @@ public:
static vectorized::IColumn::MutablePtr get_predicate_column_ptr(FieldType type);
static vectorized::IColumn::MutablePtr get_predicate_column_nullable_ptr(FieldType type,
bool is_null = false);
static vectorized::IColumn::MutablePtr get_predicate_column_nullable_ptr(const Field& field);
const std::vector<Field*>& columns() const { return _cols; }

View File

@ -503,6 +503,38 @@ void ColumnArray::insert_indices_from(const IColumn& src, const int* indices_beg
}
}
Status ColumnArray::filter_by_selector(const uint16_t* sel, size_t sel_size, IColumn* col_ptr) {
auto to = reinterpret_cast<vectorized::ColumnArray*>(col_ptr);
auto& to_offsets = to->get_offsets();
size_t element_size = 0;
size_t max_offset = 0;
for (size_t i = 0; i < sel_size; ++i) {
element_size += size_at(sel[i]);
max_offset = std::max(max_offset, offset_at(sel[i]));
}
if (max_offset > std::numeric_limits<uint16_t>::max()) {
return Status::IOError("array elements too large than uint16_t::max");
}
to_offsets.reserve(to_offsets.size() + sel_size);
auto nested_sel = std::make_unique<uint16_t[]>(element_size);
size_t nested_sel_size = 0;
for (size_t i = 0; i < sel_size; ++i) {
auto row_off = offset_at(sel[i]);
auto row_size = size_at(sel[i]);
to_offsets.push_back(to_offsets.back() + row_size);
for (auto j = 0; j < row_size; ++j) {
nested_sel[nested_sel_size++] = row_off + j;
}
}
if (nested_sel_size > 0) {
return data->filter_by_selector(nested_sel.get(), nested_sel_size, &to->get_data());
}
return Status::OK();
}
ColumnPtr ColumnArray::replicate(const IColumn::Offsets& replicate_offsets) const {
if (replicate_offsets.empty()) return clone_empty();

View File

@ -176,6 +176,8 @@ public:
offsets->clear();
}
Status filter_by_selector(const uint16_t* sel, size_t sel_size, IColumn* col_ptr) override;
private:
WrappedPtr data;
WrappedPtr offsets;

View File

@ -0,0 +1,5 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !sql --
2 [12, 3]
3 []

View File

@ -0,0 +1,29 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
suite("test_array_column_delete") {
def tableName = "test_array_column_delete"
sql """ SET enable_vectorized_engine = TRUE; """
sql "ADMIN SET FRONTEND CONFIG ('enable_array_type' = 'true')"
sql """ DROP TABLE IF EXISTS ${tableName}; """
sql """ CREATE TABLE ${tableName} (id INT NULL, c_array ARRAY<INT> NULL) ENGINE=OLAP DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 4 PROPERTIES ( "replication_allocation" = "tag.location.default: 1","in_memory" = "false","storage_format" = "V2") """
sql """ insert into ${tableName} values(1, NULL),(2,[12,3]),(3,[]),(4,NULL),(5,NULL) """
sql """ DELETE FROM ${tableName} WHERE c_array is NULL """
qt_sql """ SELECT * FROM ${tableName} order by id """
}