Skip to content

Commit

Permalink
[Fix](array-type) bugfix for array column with delete condition (#13361)
Browse files Browse the repository at this point in the history
Fix for SQL with array column:
delete from tbl where c_array is null;

more info please refer to #13360

Co-authored-by: cambyzju <[email protected]>
  • Loading branch information
cambyzju and cambyzju authored Oct 21, 2022
1 parent 27d84ea commit 1f7829e
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 8 deletions.
4 changes: 2 additions & 2 deletions be/src/olap/rowset/segment_v2/segment_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions be/src/olap/schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
3 changes: 1 addition & 2 deletions be/src/olap/schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ class Schema {

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; }

Expand Down
32 changes: 32 additions & 0 deletions be/src/vec/columns/column_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
2 changes: 2 additions & 0 deletions be/src/vec/columns/column_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ class ColumnArray final : public COWHelper<IColumn, ColumnArray> {
offsets->clear();
}

Status filter_by_selector(const uint16_t* sel, size_t sel_size, IColumn* col_ptr) override;

private:
WrappedPtr data;
WrappedPtr offsets;
Expand Down
5 changes: 5 additions & 0 deletions regression-test/data/delete_p0/test_array_column_delete.out
Original file line number Diff line number Diff line change
@@ -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 []

29 changes: 29 additions & 0 deletions regression-test/suites/delete_p0/test_array_column_delete.groovy
Original file line number Diff line number Diff line change
@@ -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 """
}

0 comments on commit 1f7829e

Please sign in to comment.