mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query
Search conditions were evaluated using val_int(), which was wrong. Fixing the code to use val_bool() instead. Details: - Adding a new item_base_t::IS_COND flag which marks Items used as <search condition> in WHERE, HAVING, JOIN ON, CASE WHEN clauses. The flag is at the parse time. These expressions must be evaluated using val_bool() rather than val_int(). Note, the optimizer creates more Items which are used as search conditions. Most of these items are not marked with IS_COND yet. This is OK for now, but eventually these Items can also be fixed to have the flag. - Adding a method Item::is_cond() which tests if the Item has the IS_COND flag. - Implementing Item_cache_bool. It evaluates the cached expression using val_bool() rather than val_int(). Overriding Type_handler_bool::Item_get_cache() to create Item_cache_bool. - Implementing Item::save_bool_in_field(). It uses val_bool() rather than val_int() to evaluate the expression. - Implementing Type_handler_bool::Item_save_in_field() using Item::save_bool_in_field(). - Fixing all Item_bool_func descendants to implement a virtual val_bool() rather than a virtual val_int(). - To find places where val_int() should be fixed to val_bool(), a few DBUG_ASSERT(!is_cond()) where added into val_int() implementations of selected (most frequent) classes: Item_field Item_str_func Item_datefunc Item_timefunc Item_datetimefunc Item_cache_bool Item_bool_func Item_func_hybrid_field_type Item_basic_constant descendants - Fixing all places where DBUG_ASSERT() happened during an "mtr" run to use val_bool() instead of val_int().
This commit is contained in:
committed by
Oleksandr Byelkin
parent
6f6c1911dc
commit
a931da82fa
@@ -3212,7 +3212,7 @@ int JOIN::optimize_stage2()
|
||||
having->update_used_tables();
|
||||
if (having->const_item() && !having->is_expensive())
|
||||
{
|
||||
if (!having->val_int())
|
||||
if (!having->val_bool())
|
||||
{
|
||||
having= const_cast<Item_bool_static*>(&Item_false);
|
||||
zero_result_cause= "Impossible HAVING noticed after reading const tables";
|
||||
@@ -4791,8 +4791,8 @@ void JOIN::exec_inner()
|
||||
DBUG_ASSERT(error == 0);
|
||||
if (cond_value != Item::COND_FALSE &&
|
||||
having_value != Item::COND_FALSE &&
|
||||
(!conds || conds->val_int()) &&
|
||||
(!having || having->val_int()))
|
||||
(!conds || conds->val_bool()) &&
|
||||
(!having || having->val_bool()))
|
||||
{
|
||||
if (do_send_rows &&
|
||||
(procedure ? (procedure->send_row(procedure_fields_list) ||
|
||||
@@ -4825,11 +4825,11 @@ void JOIN::exec_inner()
|
||||
*/
|
||||
if (!zero_result_cause &&
|
||||
exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
|
||||
!exec_const_cond->val_int())
|
||||
!exec_const_cond->val_bool())
|
||||
zero_result_cause= "Impossible WHERE noticed after reading const tables";
|
||||
|
||||
/*
|
||||
We've called exec_const_cond->val_int(). This may have caused an error.
|
||||
We've called exec_const_cond->val_bool(). This may have caused an error.
|
||||
*/
|
||||
if (unlikely(thd->is_error()))
|
||||
{
|
||||
@@ -12846,7 +12846,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
bool const_cond_result;
|
||||
{
|
||||
Json_writer_array a(thd, "computing_condition");
|
||||
const_cond_result= const_cond->val_int() != 0;
|
||||
const_cond_result= const_cond->val_bool() != 0;
|
||||
}
|
||||
if (!const_cond_result)
|
||||
{
|
||||
@@ -15992,7 +15992,7 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> *tables,
|
||||
join->no_rows_in_result_called= 1;
|
||||
while ((item= it++))
|
||||
item->no_rows_in_result();
|
||||
if (having && having->val_int() == 0)
|
||||
if (having && having->val_bool() == false)
|
||||
send_row=0;
|
||||
}
|
||||
|
||||
@@ -17338,6 +17338,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
|
||||
return 0;
|
||||
eq_item->eval_not_null_tables(0);
|
||||
eq_item->quick_fix_field();
|
||||
eq_item->base_flags|= item_base_t::IS_COND;
|
||||
}
|
||||
current_sjm= field_sjm;
|
||||
}
|
||||
@@ -21780,7 +21781,7 @@ do_select(JOIN *join, Procedure *procedure)
|
||||
sufficient to check only the condition pseudo_bits_cond.
|
||||
*/
|
||||
DBUG_ASSERT(join->outer_ref_cond == NULL);
|
||||
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
|
||||
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_bool())
|
||||
{
|
||||
// HAVING will be checked by end_select
|
||||
error= (*end_select)(join, 0, 0);
|
||||
@@ -21841,7 +21842,7 @@ do_select(JOIN *join, Procedure *procedure)
|
||||
|
||||
JOIN_TAB *join_tab= join->join_tab +
|
||||
(join->tables_list ? join->const_tables : 0);
|
||||
if (join->outer_ref_cond && !join->outer_ref_cond->val_int())
|
||||
if (join->outer_ref_cond && !join->outer_ref_cond->val_bool())
|
||||
error= NESTED_LOOP_NO_MORE_ROWS;
|
||||
else
|
||||
error= join->first_select(join,join_tab,0);
|
||||
@@ -22419,7 +22420,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
||||
|
||||
if (select_cond)
|
||||
{
|
||||
select_cond_result= MY_TEST(select_cond->val_int());
|
||||
select_cond_result= MY_TEST(select_cond->val_bool());
|
||||
|
||||
/* check for errors evaluating the condition */
|
||||
if (unlikely(join->thd->is_error()))
|
||||
@@ -22815,7 +22816,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos)
|
||||
(*tab->on_expr_ref)->update_used_tables();
|
||||
DBUG_ASSERT((*tab->on_expr_ref)->const_item());
|
||||
#endif
|
||||
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0)))
|
||||
if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_bool() == 0)))
|
||||
mark_as_null_row(table);
|
||||
}
|
||||
if (!table->null_row && ! tab->join->mixed_implicit_grouping)
|
||||
@@ -23571,7 +23572,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
/* Copy non-aggregated fields when loose index scan is used. */
|
||||
copy_fields(&join->tmp_table_param);
|
||||
}
|
||||
if (join->having && join->having->val_int() == 0)
|
||||
if (join->having && join->having->val_bool() == 0)
|
||||
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
|
||||
if (join->procedure)
|
||||
{
|
||||
@@ -23762,7 +23763,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
while ((item= it++))
|
||||
item->no_rows_in_result();
|
||||
}
|
||||
if (join->having && join->having->val_int() == 0)
|
||||
if (join->having && join->having->val_bool() == 0)// TODO: tests
|
||||
error= -1; // Didn't satisfy having
|
||||
else
|
||||
{
|
||||
@@ -23872,7 +23873,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
|
||||
if (likely(!join_tab->having || join_tab->having->val_int()))
|
||||
if (likely(!join_tab->having || join_tab->having->val_bool()))
|
||||
{
|
||||
int error;
|
||||
join->found_records++;
|
||||
@@ -24123,7 +24124,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
}
|
||||
copy_sum_funcs(join->sum_funcs,
|
||||
join->sum_funcs_end[send_group_parts]);
|
||||
if (!join_tab->having || join_tab->having->val_int())
|
||||
if (!join_tab->having || join_tab->having->val_bool())
|
||||
{
|
||||
int error= table->file->ha_write_tmp_row(table->record[0]);
|
||||
if (unlikely(error) &&
|
||||
@@ -26126,7 +26127,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
|
||||
break;
|
||||
goto err;
|
||||
}
|
||||
if (having && !having->val_int())
|
||||
if (having && !having->val_bool())
|
||||
{
|
||||
if (unlikely((error= file->ha_delete_row(record))))
|
||||
goto err;
|
||||
@@ -26264,7 +26265,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||
break;
|
||||
goto err;
|
||||
}
|
||||
if (having && !having->val_int())
|
||||
if (having && !having->val_bool())
|
||||
{
|
||||
if (unlikely((error= file->ha_delete_row(record))))
|
||||
goto err;
|
||||
@@ -28401,7 +28402,7 @@ int JOIN::rollup_send_data(uint idx)
|
||||
int res= 0;
|
||||
/* Get reference pointers to sum functions in place */
|
||||
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
|
||||
if ((!having || having->val_int()))
|
||||
if ((!having || having->val_bool()))
|
||||
{
|
||||
if (send_records < unit->lim.get_select_limit() && do_send_rows &&
|
||||
(res= result->send_data_with_check(rollup.fields[i],
|
||||
|
Reference in New Issue
Block a user