From 003ab903fd795b1acfb8166d9869c8e51d693850 Mon Sep 17 00:00:00 2001 From: Lijia Liu Date: Wed, 8 Jan 2025 19:24:38 +0800 Subject: [PATCH] [fix](planner) fix core when select and filter by slot in old planner (#46541) ### What problem does this PR solve? Problem Summary: In 2.1.7, if a sql parse failed in nereids planner, it will fallback to old planner. and old planner maybe create `SelectNode` with some conjuncts that are not boolean type. Reproduce: Create table sql see #46498 query sql1: select b.c_id from dbgr as b left join (select c.c_id from lo where event_date between 20220500 and 20220600 limit 100 )c on c.c_id LIMIT 200; query sql2: select b.c_id from dbgr as b left join (select c.c_id from lo )c on c.c_id LIMIT 0, 200; Because `select c.c_id`, these sqls will fallback to old planner. Because `on c.c_id` is not boolean type, and be will core. A part of query plan is as follows: | 1:VOlapScanNode | | TABLE: test.lo(lo), PREAGGREGATION: ON | | PREDICATES: (`c`.`c_id` AND (`test`.`lo`.`__DORIS_DELETE_SIGN__` = 0)) | | partitions=1/3 (p_202206) | | tablets=2/2, tabletList=89678,89680 | | cardinality=46, avgRowSize=165.54349, numNodes=1 | | pushAggOp=NONE | +-----------------------------------------------------------------------------+ A fatal log is as follows: F20241219 23:13:23.457937 33282 assert_cast.h:58] Bad cast from type:doris::vectorized::ColumnVector to doris::vectorized::ColumnVector *** Check failure stack trace: *** @ 0x55bfa043b956 google::LogMessageFatal::~LogMessageFatal() @ 0x55bf6f3bc070 assert_cast<>() @ 0x55bf8978d767 doris::vectorized::VExprContext::execute_conjuncts() @ 0x55bf8978c463 doris::vectorized::VExprContext::execute_conjuncts_and_filter_block() @ 0x55bf8978bf72 doris::vectorized::VExprContext::filter_block() @ 0x55bfa035b8e4 doris::pipeline::SelectOperatorX::pull() @ 0x55bf9fee2b62 doris::pipeline::StreamingOperatorX<>::get_block() @ 0x55bf9feab54b doris::pipeline::OperatorXBase::get_block_after_projects() @ 0x55bfa03dd07c doris::pipeline::PipelineXTask::execute() @ 0x55bfa0413e85 doris::pipeline::TaskScheduler::_do_work() @ 0x55bfa0417dcb doris::pipeline::TaskScheduler::start()::$_0::operator()() @ 0x55bfa0417d55 std::__invoke_impl<>() @ 0x55bfa0417d05 _ZSt10__invoke_rIvRZN5doris8pipeline13TaskScheduler5startEvE3$_0JEENSt9enable_ifIX16is_invocable_r_vIT_T0_DpT1_EES6_E4typeEO S7_DpOS8_ @ 0x55bfa0417bcd std::_Function_handler<>::_M_invoke() @ 0x55bf6e6c9b63 std::function<>::operator()() @ 0x55bf7289e209 doris::FunctionRunnable::run() @ 0x55bf728899c0 doris::ThreadPool::dispatch_thread() @ 0x55bf728b0c24 std::__invoke_impl<>() @ 0x55bf728b0afd std::__invoke<>() @ 0x55bf728b0a85 _ZNSt5_BindIFMN5doris10ThreadPoolEFvvEPS1_EE6__callIvJEJLm0EEEET_OSt5tupleIJDpT0_EESt12_Index_tupleIJXspT1_EEE @ 0x55bf728b092e std::_Bind<>::operator()<>() @ 0x55bf728b0845 std::__invoke_impl<>() @ 0x55bf728b07e5 _ZSt10__invoke_rIvRSt5_BindIFMN5doris10ThreadPoolEFvvEPS2_EEJEENSt9enable_ifIX16is_invocable_r_vIT_T0_DpT1_EESA_E4typeEOSB_D pOSC_ @ 0x55bf728b048d std::_Function_handler<>::_M_invoke() @ 0x55bf6e6c9b63 std::function<>::operator()() @ 0x55bf728521fc doris::Thread::supervise_thread() @ 0x7f4260614ea5 start_thread @ 0x7f42610439fd __clone @ (nil) (unknown) And another: F20250108 13:07:05.275424 184257 assert_cast.h:58] Bad cast from type:doris::vectorized::ColumnVector to doris::vectorized::ColumnVector 0# doris::signal::(anonymous namespace)::FailureSignalHandler(int, siginfo_t*, void*) at /root/tc/be/src/common/signal_handler.h:421 1# 0x00007FB73FB31400 in /lib64/libc.so.6 2# __GI_raise in /lib64/libc.so.6 3# abort in /lib64/libc.so.6 4# 0x000055CDAAF0090D in /usr/local/service/doris/lib/be/doris_be 5# google::LogMessage::SendToLog() in /usr/local/service/doris/lib/be/doris_be 6# google::LogMessage::Flush() in /usr/local/service/doris/lib/be/doris_be 7# google::LogMessageFatal::~LogMessageFatal() in /usr/local/service/doris/lib/be/doris_be 8# doris::vectorized::ColumnVector const& assert_cast const&, doris::vec torized::IColumn const&>(doris::vectorized::IColumn const&) in /usr/local/service/doris/lib/be/doris_be 9# doris::vectorized::VExprContext::execute_conjuncts(std::vector, std::allocator > > const&, std::vector, 16ul, 16ul>*, std::allocator, 16ul, 16ul>*> > const*, bool, doris::vectorized::Block*, doris::vectorized::PODArray, 16ul, 16ul>*, bool*) at /root/tc/be/src/vec/exprs/vexpr_context .cpp:181 10# doris::vectorized::VExprContext::execute_conjuncts_and_filter_block(std::vector, s td::allocator > > const&, doris::vectorized::Block*, std::vector >&, int, doris::vectorized::PODArray, 16ul, 16ul>&) at /root/tc/be/src/vec/exprs/vexpr_context.cpp:324 11# doris::segment_v2::SegmentIterator::_execute_common_expr(unsigned short*, unsigned short&, doris::vectorized::Block*) at /root/tc/b e/src/olap/rowset/segment_v2/segment_iterator.cpp:2274 12# doris::segment_v2::SegmentIterator::_next_batch_internal(doris::vectorized::Block*) at /root/tc/be/src/olap/rowset/segment_v2/segment_iterator.cpp:2178 13# doris::segment_v2::SegmentIterator::next_batch(doris::vectorized::Block*)::$_0::operator()() const at /root/tc/be/src/olap/rowset/segment_v2/segment_iterator.cpp:1914 14# doris::segment_v2::SegmentIterator::next_batch(doris::vectorized::Block*) at /root/tc/be/src/olap/rowset/segment_v2/segment_iterator.cpp:1913 15# doris::segment_v2::LazyInitSegmentIterator::next_batch(doris::vectorized::Block*) in /usr/local/service/doris/lib/be/doris_be 16# doris::BetaRowsetReader::next_block(doris::vectorized::Block*) at /root/tc/be/src/olap/rowset/beta_rowset_reader.cpp:348 17# doris::vectorized::VCollectIterator::Level0Iterator::_refresh() in /usr/local/service/doris/lib/be/doris_be 18# doris::vectorized::VCollectIterator::Level0Iterator::refresh_current_row() at /root/tc/be/src/vec/olap/vcollect_iterator.cpp:511 19# doris::vectorized::VCollectIterator::Level0Iterator::ensure_first_row_ref() at /root/tc/be/src/vec/olap/vcollect_iterator.cpp:482 20# doris::vectorized::VCollectIterator::Level1Iterator::ensure_first_row_ref() at /root/tc/be/src/vec/olap/vcollect_iterator.cpp:697 21# doris::vectorized::VCollectIterator::build_heap(std::vector, std::allocator > >&) at /root/tc/be/src/vec/olap/vcollect_iterator.cpp:186 22# doris::vectorized::BlockReader::_init_collect_iter(doris::TabletReader::ReaderParams const&) at /root/tc/be/src/vec/olap/block_reader.cpp:139 23# doris::vectorized::BlockReader::init(doris::TabletReader::ReaderParams const&) at /root/tc/be/src/vec/olap/block_reader.cpp:211 24# doris::vectorized::NewOlapScanner::open(doris::RuntimeState*) at /root/tc/be/src/vec/exec/scan/new_olap_scanner.cpp:227 25# doris::vectorized::ScannerScheduler::_scanner_scan(std::shared_ptr, std::shared_ptr) at /root/tc/be/src/vec/exec/scan/scanner_scheduler.cpp:259 26# doris::vectorized::ScannerScheduler::submit(std::shared_ptr, std::shared_ptr)::$_1::operator()() const::{lambda()#1}::operator()() const::{lambda()#2}::operator()() const at /root/tc/be/src/vec/exec/scan/scanner_scheduler.cpp:180 ... --------- Co-authored-by: liutang123 --- .../org/apache/doris/planner/PlanNode.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java index 73768435154b76..c83cd9cde99b99 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java @@ -34,6 +34,7 @@ import org.apache.doris.analysis.TupleId; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.OlapTable; +import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; import org.apache.doris.common.Id; import org.apache.doris.common.NotImplementedException; @@ -59,6 +60,8 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.commons.collections.CollectionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.Collection; @@ -89,6 +92,7 @@ * its children (= are bound by tupleIds). */ public abstract class PlanNode extends TreeNode implements PlanStats { + private static final Logger LOG = LogManager.getLogger(PlanNode.class); protected String planNodeName; @@ -207,6 +211,7 @@ protected PlanNode(PlanNodeId id, PlanNode node, String planNodeName, Statistica this.tblRefIds = Lists.newArrayList(node.tblRefIds); this.nullableTupleIds = Sets.newHashSet(node.nullableTupleIds); this.conjuncts = Expr.cloneList(node.conjuncts, null); + this.cardinality = -1; this.compactData = node.compactData; this.planNodeName = "V" + planNodeName; @@ -806,6 +811,21 @@ public void init() throws UserException {} public void init(Analyzer analyzer) throws UserException { assignConjuncts(analyzer); createDefaultSmap(analyzer); + castConjuncts(); + } + + private void castConjuncts() throws AnalysisException { + for (int i = 0; i < conjuncts.size(); ++i) { + Expr expr = conjuncts.get(i); + if (!expr.getType().isBoolean()) { + try { + conjuncts.set(i, expr.castTo(Type.BOOLEAN)); + } catch (AnalysisException e) { + LOG.warn("{} is not boolean and can not be cast to boolean", expr.toSql(), e); + throw new AnalysisException("conjuncts " + expr.toSql() + " is not boolean"); + } + } + } } /**