This is an automated email from the ASF dual-hosted git repository. lihaopeng pushed a commit to branch vectorized in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
commit 24e1d64a6b26be2f97477d39d87caed8ee0f5f8e Author: HappenLee <happen...@hotmail.com> AuthorDate: Wed Jan 5 23:56:22 2022 -0600 [Bug] Fix bug of cast expr nullable and ifnull function (#7626) Co-authored-by: lihaopeng <lihaop...@baidu.com> --- be/src/runtime/descriptors.h | 1 - be/src/runtime/fold_constant_executor.cpp | 8 ++-- be/src/vec/exec/join/vhash_join_node.cpp | 2 +- be/src/vec/exec/vunion_node.cpp | 2 + be/src/vec/functions/function.cpp | 2 +- .../function_date_or_datetime_computation.h | 4 +- be/src/vec/functions/function_ifnull.h | 43 ++++++++++++---------- be/src/vec/sink/vtabet_sink.cpp | 1 + .../java/org/apache/doris/analysis/CastExpr.java | 7 ++++ .../apache/doris/analysis/FunctionCallExpr.java | 2 +- .../apache/doris/rewrite/FoldConstantsRule.java | 9 ++++- 11 files changed, 51 insertions(+), 30 deletions(-) diff --git a/be/src/runtime/descriptors.h b/be/src/runtime/descriptors.h index 97f9712..ad43209 100644 --- a/be/src/runtime/descriptors.h +++ b/be/src/runtime/descriptors.h @@ -381,7 +381,6 @@ public: int get_row_size() const; int num_materialized_slots() const { - DCHECK(_num_materialized_slots != 0); return _num_materialized_slots; } diff --git a/be/src/runtime/fold_constant_executor.cpp b/be/src/runtime/fold_constant_executor.cpp index 9781c2f..f093c04 100644 --- a/be/src/runtime/fold_constant_executor.cpp +++ b/be/src/runtime/fold_constant_executor.cpp @@ -127,9 +127,11 @@ Status FoldConstantExecutor::fold_constant_vexpr( } vectorized::Block tmp_block; + tmp_block.insert({vectorized::ColumnUInt8::create(1), + std::make_shared<vectorized::DataTypeUInt8>(), ""}); int result_column = -1; // calc vexpr - ctx->execute(&tmp_block, &result_column); + RETURN_IF_ERROR(ctx->execute(&tmp_block, &result_column)); DCHECK(result_column != -1); PrimitiveType root_type = ctx->root()->type().type; // covert to thrift type @@ -139,7 +141,7 @@ Status FoldConstantExecutor::fold_constant_vexpr( PExprResult expr_result; string result; const auto& column_ptr = tmp_block.get_by_position(result_column).column; - if (column_ptr->is_nullable() && column_ptr->is_null_at(0)) { + if (column_ptr->is_null_at(0)) { expr_result.set_success(false); } else { expr_result.set_success(true); @@ -194,7 +196,7 @@ Status FoldConstantExecutor::_init(const TQueryGlobals& query_globals) { template <typename Context> Status FoldConstantExecutor::_prepare_and_open(Context* ctx) { - ctx->prepare(_runtime_state.get(), RowDescriptor(), _mem_tracker); + RETURN_IF_ERROR(ctx->prepare(_runtime_state.get(), RowDescriptor(), _mem_tracker)); return ctx->open(_runtime_state.get()); } diff --git a/be/src/vec/exec/join/vhash_join_node.cpp b/be/src/vec/exec/join/vhash_join_node.cpp index 7606783..4533cae 100644 --- a/be/src/vec/exec/join/vhash_join_node.cpp +++ b/be/src/vec/exec/join/vhash_join_node.cpp @@ -133,7 +133,7 @@ struct ProcessRuntimeFilterBuild { RETURN_IF_ERROR(runtime_filter_slots->init(state, hash_table_ctx.hash_table.get_size())); - if (!runtime_filter_slots->empty()) { + if (!runtime_filter_slots->empty() && !_join_node->_inserted_rows.empty()) { { SCOPED_TIMER(_join_node->_push_compute_timer); runtime_filter_slots->insert(_join_node->_inserted_rows); diff --git a/be/src/vec/exec/vunion_node.cpp b/be/src/vec/exec/vunion_node.cpp index 122eafa..1fa4da4 100644 --- a/be/src/vec/exec/vunion_node.cpp +++ b/be/src/vec/exec/vunion_node.cpp @@ -181,6 +181,8 @@ Status VUnionNode::get_next_const(RuntimeState* state, Block* block) { MutableBlock(Block(VectorizedUtils::create_columns_with_type_and_name(row_desc()))); for (; _const_expr_list_idx < _const_expr_lists.size(); ++_const_expr_list_idx) { Block tmp_block; + tmp_block.insert({vectorized::ColumnUInt8::create(1), + std::make_shared<vectorized::DataTypeUInt8>(), ""}); int const_expr_lists_size = _const_expr_lists[_const_expr_list_idx].size(); std::vector<int> result_list(const_expr_lists_size); for (size_t i = 0; i < const_expr_lists_size; ++i) { diff --git a/be/src/vec/functions/function.cpp b/be/src/vec/functions/function.cpp index d3a910e..9ed3edb 100644 --- a/be/src/vec/functions/function.cpp +++ b/be/src/vec/functions/function.cpp @@ -66,7 +66,7 @@ ColumnPtr wrap_in_nullable(const ColumnPtr& src, const Block& block, const Colum null_map_column->clone_resized(null_map_column->size()); } else { MutableColumnPtr mutable_result_null_map_column = - (*std::move(result_null_map_column)).mutate(); + (*std::move(result_null_map_column)).assume_mutable(); NullMap& result_null_map = assert_cast<ColumnUInt8&>(*mutable_result_null_map_column).get_data(); diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h b/be/src/vec/functions/function_date_or_datetime_computation.h index 33c7588..607039c 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -434,11 +434,11 @@ struct CurrentDateImpl { template<typename FunctionName> struct CurrentTimeImpl { - using ReturnType = DataTypeInt64; + using ReturnType = DataTypeFloat64; static constexpr auto name = FunctionName::name; static Status execute(FunctionContext* context, Block& block, size_t result, size_t input_rows_count) { - auto col_to = ColumnVector<Int64>::create(); + auto col_to = ColumnVector<Float64>::create(); VecDateTimeValue dtv; if (dtv.from_unixtime(context->impl()->state()->timestamp_ms() / 1000, context->impl()->state()->timezone_obj())) { diff --git a/be/src/vec/functions/function_ifnull.h b/be/src/vec/functions/function_ifnull.h index b18de80..26fe18c 100644 --- a/be/src/vec/functions/function_ifnull.h +++ b/be/src/vec/functions/function_ifnull.h @@ -42,6 +42,9 @@ public: bool use_default_implementation_for_constants() const override { return false; } DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + if (!arguments[0]->is_nullable() && arguments[1]->is_nullable()) { + return reinterpret_cast<const DataTypeNullable*>(arguments[1].get())->get_nested_type(); + } return arguments[1]; } @@ -55,42 +58,42 @@ public: block.get_by_position(result).column = block.get_by_position(arguments[1]).column; return Status::OK(); } - const ColumnWithTypeAndName new_result_column { - block.get_by_position(result), + + ColumnWithTypeAndName null_column_arg0 { + nullptr, std::make_shared<DataTypeUInt8>(),"" }; - const ColumnWithTypeAndName new_column { - col_left, + ColumnWithTypeAndName nested_column_arg0 { + nullptr, col_left.type, "" }; + /// implement isnull(col_left) logic if (auto* nullable = check_and_get_column<ColumnNullable>(*col_left.column)) { - block.get_by_position(arguments[0]).column = nullable->get_null_map_column_ptr(); + null_column_arg0.column = nullable->get_null_map_column_ptr(); + nested_column_arg0.column = nullable->get_nested_column_ptr(); + nested_column_arg0.type = reinterpret_cast<const DataTypeNullable*>( + nested_column_arg0.type.get())->get_nested_type(); } else { block.get_by_position(result).column = col_left.column; return Status::OK(); } const ColumnsWithTypeAndName if_columns { - block.get_by_position(arguments[0]), + null_column_arg0, block.get_by_position(arguments[1]), - new_column, + nested_column_arg0 }; Block temporary_block( - {block.get_by_position(arguments[0]), - block.get_by_position(arguments[1]), - new_column, - new_result_column + { + null_column_arg0, + block.get_by_position(arguments[1]), + nested_column_arg0, + block.get_by_position(result), }); - auto func_if = SimpleFunctionFactory::instance().get_function("if", if_columns, make_nullable(new_result_column.type)); + + auto func_if = SimpleFunctionFactory::instance().get_function("if", if_columns, block.get_by_position(result).type); func_if->execute(context, temporary_block, {0, 1, 2}, 3, input_rows_count); - /// need to handle nullable type and not nullable type differently, - /// because `IF` function always return nullable type, but result type is not always - if (block.get_by_position(result).type->is_nullable()) { - block.get_by_position(result).column = temporary_block.get_by_position(3).column; - } else { - auto cols = check_and_get_column<ColumnNullable>(temporary_block.get_by_position(3).column.get()); - block.replace_by_position(result, std::move(cols->get_nested_column_ptr())); - } + block.get_by_position(result).column = temporary_block.get_by_position(3).column; return Status::OK(); } }; diff --git a/be/src/vec/sink/vtabet_sink.cpp b/be/src/vec/sink/vtabet_sink.cpp index 685f017..3b09cae 100644 --- a/be/src/vec/sink/vtabet_sink.cpp +++ b/be/src/vec/sink/vtabet_sink.cpp @@ -129,6 +129,7 @@ int VOlapTableSink::_validate_data(doris::RuntimeState* state, doris::vectorized for (int i = 0; i < _output_tuple_desc->slots().size(); ++i) { SlotDescriptor* desc = _output_tuple_desc->slots()[i]; + block->get_by_position(i).column = block->get_by_position(i).column->convert_to_full_column_if_const(); const auto& column = block->get_by_position(i).column; if (desc->is_nullable() && desc->type() == TYPE_OBJECT) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java index f071e0f..2a629f9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -451,4 +451,11 @@ public class CastExpr extends Expr { } return -1; } + + @Override + public boolean isNullable() { + return children.get(0).isNullable() || + (children.get(0).getType().isStringType() && !getType().isStringType()) || + (!children.get(0).getType().isDateType() && getType().isDateType()); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index f6a350a..6fa7c69 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -1053,7 +1053,7 @@ public class FunctionCallExpr extends Expr { // TODO: we can't correctly determine const-ness before analyzing 'fn_'. We should // rework logic so that we do not call this function on unanalyzed exprs. // Aggregate functions are never constant. - if (fn instanceof AggregateFunction) return false; + if (fn instanceof AggregateFunction || fn == null) return false; final String fnName = this.fnName.getFunction(); // Non-deterministic functions are never constant. diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java index 8eaac29..628740a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java @@ -27,6 +27,7 @@ import org.apache.doris.analysis.LiteralExpr; import org.apache.doris.analysis.NullLiteral; import org.apache.doris.analysis.SysVariableDesc; import org.apache.doris.catalog.Catalog; +import org.apache.doris.catalog.Function; import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; @@ -194,6 +195,12 @@ public class FoldConstantsRule implements ExprRewriteRule { Analyzer analyzer, Map<String, Expr> sysVarMap, Map<String, Expr> infoFnMap) throws AnalysisException { if (expr.isConstant()) { + if (VectorizedUtil.isVectorized()) { + Function fn = expr.getFn(); + if (fn != null && (fn.functionName().equalsIgnoreCase("curtime") || + fn.functionName().equalsIgnoreCase("current_time"))) + return; + } // Do not constant fold cast(null as dataType) because we cannot preserve the // cast-to-types and that can lead to query failures, e.g., CTAS if (expr instanceof CastExpr) { @@ -216,7 +223,7 @@ public class FoldConstantsRule implements ExprRewriteRule { getInfoFnExpr(expr, infoFnMap); return; } - constExprMap.put(expr.getId().toString(),expr.treeToThrift()); + constExprMap.put(expr.getId().toString(), expr.treeToThrift()); oriConstMap.put(expr.getId().toString(), expr); } else { recursiveGetChildrenConstExpr(expr, constExprMap, oriConstMap, analyzer, sysVarMap, infoFnMap); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org