diff --git a/be/src/vec/core/block.cpp b/be/src/vec/core/block.cpp index 29c6d21bb78eb78..bb37b2130c094a9 100644 --- a/be/src/vec/core/block.cpp +++ b/be/src/vec/core/block.cpp @@ -53,6 +53,7 @@ #include "vec/columns/columns_number.h" #include "vec/common/assert_cast.h" #include "vec/data_types/data_type_factory.hpp" +#include "vec/data_types/data_type_nullable.h" class SipHash; @@ -476,7 +477,7 @@ std::string Block::dump_types() const { return out; } -std::string Block::dump_data(size_t begin, size_t row_limit) const { +std::string Block::dump_data(size_t begin, size_t row_limit, bool allow_null_mismatch) const { std::vector headers; std::vector headers_size; for (const auto& it : data) { @@ -515,7 +516,14 @@ std::string Block::dump_data(size_t begin, size_t row_limit) const { } std::string s; if (data[i].column) { - s = data[i].to_string(row_num); + if (data[i].type->is_nullable() && !data[i].column->is_nullable()) { + assert(allow_null_mismatch); + s = assert_cast(data[i].type.get()) + ->get_nested_type() + ->to_string(*data[i].column, row_num); + } else { + s = data[i].to_string(row_num); + } } if (s.length() > headers_size[i]) { s = s.substr(0, headers_size[i] - 3) + "..."; diff --git a/be/src/vec/core/block.h b/be/src/vec/core/block.h index a8a4d07b49d0a0d..0055ceca23b3850 100644 --- a/be/src/vec/core/block.h +++ b/be/src/vec/core/block.h @@ -255,14 +255,20 @@ class Block { bool empty() const { return rows() == 0; } - /** Updates SipHash of the Block, using update method of columns. + /** + * Updates SipHash of the Block, using update method of columns. * Returns hash for block, that could be used to differentiate blocks * with same structure, but different data. */ void update_hash(SipHash& hash) const; - /** Get block data in string. */ - std::string dump_data(size_t begin = 0, size_t row_limit = 100) const; + /** + * Get block data in string. + * If code is in default_implementation_for_nulls or something likely, type and column's nullity could + * temporarily be not same. set allow_null_mismatch to true to dump it correctly. + */ + std::string dump_data(size_t begin = 0, size_t row_limit = 100, + bool allow_null_mismatch = false) const; static std::string dump_column(ColumnPtr col, DataTypePtr type) { ColumnWithTypeAndName type_name {col, type, ""}; diff --git a/be/src/vec/functions/function.cpp b/be/src/vec/functions/function.cpp index cfc6a39f397c58f..1fea4c70fc1753e 100644 --- a/be/src/vec/functions/function.cpp +++ b/be/src/vec/functions/function.cpp @@ -216,7 +216,8 @@ Status PreparedFunctionImpl::default_implementation_for_nulls( } RETURN_IF_ERROR(execute_without_low_cardinality_columns(context, block, new_args, result, block.rows(), dry_run)); - // after run with nested, wrap them in null. + // After run with nested, wrap them in null. Before this, block.get_by_position(result).type + // is not compatible with get_by_position(result).column block.get_by_position(result).column = wrap_in_nullable( block.get_by_position(result).column, block, args, result, input_rows_count); diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java index 24b384d445357f4..8945f85ea424c14 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SortNode.java @@ -196,6 +196,19 @@ public String getNodeExplainString(String detailPrefix, TExplainLevel detailLeve if (useTwoPhaseReadOpt) { output.append(detailPrefix + "OPT TWO PHASE\n"); } + + output.append(detailPrefix + "algorithm: "); + boolean isFixedLength = info.getOrderingExprs().stream().allMatch(e -> !e.getType().isStringType() + && !e.getType().isCollectionType()); + if (limit > 0 && limit + offset < 1024 && (useTwoPhaseReadOpt || hasRuntimePredicate + || isFixedLength)) { + output.append("heap sort\n"); + } else if (limit > 0 && !isFixedLength && limit + offset < 256) { + output.append("topn sort\n"); + } else { + output.append("full sort\n"); + } + output.append(detailPrefix).append("offset: ").append(offset).append("\n"); return output.toString(); }