diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index aa71cee0752935a6bd2cd6751faeef5eff554b0c..ef5526ca13e15881b4955918495ffdd66e9bbf61 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -73,3 +73,33 @@ find_in_set(binary 'a', 'A,B,C') select find_in_set('1','3,1,'); find_in_set('1','3,1,') 2 +End of 4.1 tests +SELECT INTERVAL(0.0, NULL); +INTERVAL(0.0, NULL) +1 +SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL)); +INTERVAL(0.0, CAST(NULL AS DECIMAL)) +1 +SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL)); +INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL)) +1 +SELECT INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) +8 +SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), +CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), +CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL)); +INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), +CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), +CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL)) +8 +SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL)); +INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), +CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL)) +8 +End of 5.0 tests diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index 710b9b90a05cdba04027e4acb49fea0970dc51dc..e4fde6e0e0ea36eaf39baea52c1cc6c7602528bf 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -54,4 +54,21 @@ select find_in_set(binary 'a', 'A,B,C'); # select find_in_set('1','3,1,'); -# End of 4.1 tests +--echo End of 4.1 tests + +# +# Bug #32560: crash with interval function and count(*) +# +SELECT INTERVAL(0.0, NULL); +SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL)); +SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL)); +SELECT INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), + CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), + CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL)); +SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), + CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), + CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL), + CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL)); + +--echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 85ec8fa40d6001b2a06c8093faea24f36404d0a1..b608da958cc3bbb4f70ea87d7a8261ffd84dc144 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1638,24 +1638,27 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const void Item_func_interval::fix_length_and_dec() { + uint rows= row->cols(); + use_decimal_comparison= (row->element_index(0)->result_type() == DECIMAL_RESULT) || (row->element_index(0)->result_type() == INT_RESULT); - if (row->cols() > 8) + if (rows > 8) { - bool consts=1; + bool not_null_consts= TRUE; - for (uint i=1 ; consts && i < row->cols() ; i++) + for (uint i= 1; not_null_consts && i < rows; i++) { - consts&= row->element_index(i)->const_item(); + Item *el= row->element_index(i); + not_null_consts&= el->const_item() & !el->is_null(); } - if (consts && + if (not_null_consts && (intervals= - (interval_range*) sql_alloc(sizeof(interval_range)*(row->cols()-1)))) + (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1)))) { if (use_decimal_comparison) { - for (uint i=1 ; i < row->cols(); i++) + for (uint i= 1; i < rows; i++) { Item *el= row->element_index(i); interval_range *range= intervals + (i-1); @@ -1680,7 +1683,7 @@ void Item_func_interval::fix_length_and_dec() } else { - for (uint i=1 ; i < row->cols(); i++) + for (uint i= 1; i < rows; i++) { intervals[i-1].dbl= row->element_index(i)->val_real(); } @@ -1771,12 +1774,22 @@ longlong Item_func_interval::val_int() ((el->result_type() == DECIMAL_RESULT) || (el->result_type() == INT_RESULT))) { - my_decimal e_dec_buf, *e_dec= row->element_index(i)->val_decimal(&e_dec_buf); + my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf); + /* Skip NULL ranges. */ + if (el->null_value) + continue; if (my_decimal_cmp(e_dec, dec) > 0) - return i-1; + return i - 1; + } + else + { + double val= el->val_real(); + /* Skip NULL ranges. */ + if (el->null_value) + continue; + if (val > value) + return i - 1; } - else if (row->element_index(i)->val_real() > value) - return i-1; } return i-1; }