@@ -2140,8 +2140,12 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21402140 }
21412141
21422142 auto conjunction = getConjunctionNodes (predicate, allowed_nodes);
2143- if (conjunction.rejected .size () == 1 && WhichDataType{removeNullable (conjunction.rejected .front ()->result_type )}.isFloat ())
2143+ if (conjunction.rejected .size () == 1 && !conjunction.rejected .front ()->result_type ->equals (*predicate->result_type )
2144+ && conjunction.allowed .front ()->type == ActionType::COLUMN)
2145+ {
2146+ // No further optimization can be done
21442147 return nullptr ;
2148+ }
21452149
21462150 auto actions = cloneActionsForConjunction (conjunction.allowed , all_inputs);
21472151 if (!actions)
@@ -2191,64 +2195,36 @@ ActionsDAGPtr ActionsDAG::cloneActionsForFilterPushDown(
21912195 else
21922196 {
21932197 // / Predicate is conjunction, where both allowed and rejected sets are not empty.
2194- // / Replace this node to conjunction of rejected predicates.
21952198
21962199 NodeRawConstPtrs new_children = std::move (conjunction.rejected );
21972200
2198- if (new_children.size () == 1 )
2201+ if (new_children.size () == 1 && new_children. front ()-> result_type -> equals (*predicate-> result_type ) )
21992202 {
2200- // / Rejected set has only one predicate.
2201- if (new_children.front ()->result_type ->equals (*predicate->result_type ))
2202- {
2203- // / If it's type is same, just add alias.
2204- Node node;
2205- node.type = ActionType::ALIAS;
2206- node.result_name = predicate->result_name ;
2207- node.result_type = predicate->result_type ;
2208- node.children .swap (new_children);
2209- *predicate = std::move (node);
2210- }
2211- else if (!WhichDataType{removeNullable (new_children.front ()->result_type )}.isFloat ())
2212- {
2213- // / If type is different, cast column.
2214- // / This case is possible, cause AND can use any numeric type as argument.
2215- // / But casting floats to UInt8 or Bool produces different results.
2216- // / so we can't apply this optimization to them.
2217- Node node;
2218- node.type = ActionType::COLUMN;
2219- node.result_name = predicate->result_type ->getName ();
2220- node.column = DataTypeString ().createColumnConst (0 , node.result_name );
2221- node.result_type = std::make_shared<DataTypeString>();
2222-
2223- const auto * right_arg = &nodes.emplace_back (std::move (node));
2224- const auto * left_arg = new_children.front ();
2225-
2226- predicate->children = {left_arg, right_arg};
2227- auto arguments = prepareFunctionArguments (predicate->children );
2228-
2229- FunctionOverloadResolverPtr func_builder_cast = CastInternalOverloadResolver<CastType::nonAccurate>::createImpl ();
2230-
2231- predicate->function_base = func_builder_cast->build (arguments);
2232- predicate->function = predicate->function_base ->prepare (arguments);
2233- }
2203+ // / Rejected set has only one predicate. And the type is the same as the result_type.
2204+ // / Just add alias.
2205+ Node node;
2206+ node.type = ActionType::ALIAS;
2207+ node.result_name = predicate->result_name ;
2208+ node.result_type = predicate->result_type ;
2209+ node.children .swap (new_children);
2210+ *predicate = std::move (node);
22342211 }
22352212 else
22362213 {
2237- // / Predicate is function AND, which still have more then one argument.
2238- // / Or there is only one argument that is a float and we can't just
2239- // / remove the AND.
2214+ // / Predicate is function AND, which still have more then one argument
2215+ // / or it has one argument of the wrong type.
22402216 // / Just update children and rebuild it.
2241- predicate->children .swap (new_children);
2242- if (WhichDataType{removeNullable (predicate->children .front ()->result_type )}.isFloat ())
2217+ if (new_children.size () == 1 )
22432218 {
22442219 Node node;
22452220 node.type = ActionType::COLUMN;
22462221 node.result_name = " 1" ;
22472222 node.column = DataTypeUInt8 ().createColumnConst (0 , 1u );
22482223 node.result_type = std::make_shared<DataTypeUInt8>();
22492224 const auto * const_col = &nodes.emplace_back (std::move (node));
2250- predicate-> children .emplace_back (const_col);
2225+ new_children .emplace_back (const_col);
22512226 }
2227+ predicate->children .swap (new_children);
22522228 auto arguments = prepareFunctionArguments (predicate->children );
22532229
22542230 FunctionOverloadResolverPtr func_builder_and = std::make_unique<FunctionToOverloadResolverAdaptor>(std::make_shared<FunctionAnd>());
0 commit comments