Skip to content

Commit

Permalink
Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
Browse files Browse the repository at this point in the history
Item_func_like inherits resolve_type from Item_bool_func2 but does not
have much in common with it's parent since every comparison must be done
as strings. Also the call to set_cmp_func() is unnecesary and results in
an error when comparing temporal types with strings.
This patch fixes this error by overriding resolve_type in
Item_func_like, and by omitting the call to set_cmp_func.

Change-Id: I1cea9d5fcf54f3539016aed4cdb77501a547a5ed
  • Loading branch information
Catalin Besleaga authored and dahlerlend committed Jun 25, 2019
1 parent 755bffa commit 4869291
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 20 deletions.
13 changes: 13 additions & 0 deletions mysql-test/r/func_like.result
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,16 @@ DELETE FROM t1 WHERE
) LIKE (c1);
ERROR 22007: Incorrect datetime value: '42'
DROP TABLE t1;
#
# Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
#
CREATE TABLE t(col1 DATE);
INSERT INTO t(col1) VALUES('2019-06-13'), ('2019-07-13');
SELECT * FROM t WHERE col1 LIKE '2019%';
col1
2019-06-13
2019-07-13
SELECT * FROM t WHERE col1 LIKE '2019-06-1%';
col1
2019-06-13
DROP TABLE t;
8 changes: 4 additions & 4 deletions mysql-test/r/type_temporal_fractional.result
Original file line number Diff line number Diff line change
Expand Up @@ -15587,11 +15587,11 @@ s1
1000-00-01 00:00:00
1000-00-01 00:00:00
DROP TABLE t1;
SELECT BINARY SYSDATE(6) LIKE '____-__-__ __:__:__.______';
BINARY SYSDATE(6) LIKE '____-__-__ __:__:__.______'
SELECT SYSDATE(6) LIKE '____-__-__ __:__:__.______';
SYSDATE(6) LIKE '____-__-__ __:__:__.______'
1
SELECT BINARY SYSDATE(6) NOT LIKE '%.000000' || BINARY SYSDATE(6) NOT LIKE '%.000000';
BINARY SYSDATE(6) NOT LIKE '%.000000' || BINARY SYSDATE(6) NOT LIKE '%.000000'
SELECT SYSDATE(6) NOT LIKE '%.000000' || SYSDATE(6) NOT LIKE '%.000000';
SYSDATE(6) NOT LIKE '%.000000' || SYSDATE(6) NOT LIKE '%.000000'
1
Warnings:
Warning 1287 '|| as a synonym for OR' is deprecated and will be removed in a future release. Please use OR instead
Expand Down
10 changes: 10 additions & 0 deletions mysql-test/t/func_like.test
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,13 @@ DELETE FROM t1 WHERE
(SELECT * WHERE '520:33:32.77' < (c1 - INTERVAL(1) MONTH))
) LIKE (c1);
DROP TABLE t1;

--echo #
--echo # Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
--echo #
CREATE TABLE t(col1 DATE);
INSERT INTO t(col1) VALUES('2019-06-13'), ('2019-07-13');
SELECT * FROM t WHERE col1 LIKE '2019%';
SELECT * FROM t WHERE col1 LIKE '2019-06-1%';
DROP TABLE t;

4 changes: 2 additions & 2 deletions mysql-test/t/type_temporal_fractional.test
Original file line number Diff line number Diff line change
Expand Up @@ -6231,8 +6231,8 @@ DROP TABLE t1;

# SYSDATE(n) post-decimal digits are not zeros
# Disable warnings, see Bug#61216: Incorrect warning for "datetime LIKE string"
SELECT BINARY SYSDATE(6) LIKE '____-__-__ __:__:__.______';
SELECT BINARY SYSDATE(6) NOT LIKE '%.000000' || BINARY SYSDATE(6) NOT LIKE '%.000000';
SELECT SYSDATE(6) LIKE '____-__-__ __:__:__.______';
SELECT SYSDATE(6) NOT LIKE '%.000000' || SYSDATE(6) NOT LIKE '%.000000';

CREATE TABLE t1 (s1 DATETIME(2));
INSERT INTO t1 VALUES ('1970-01-01 11:11:11.1234');
Expand Down
43 changes: 30 additions & 13 deletions sql/item_cmpfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -639,14 +639,6 @@ bool Item_bool_func2::resolve_type(THD *thd) {

args[0]->cmp_context = args[1]->cmp_context =
item_cmp_type(args[0]->result_type(), args[1]->result_type());
// Make a special case of compare with fields to get nicer DATE comparisons

if (functype() == LIKE_FUNC) // Disable conversion in case of LIKE function.
{
if (set_cmp_func()) DBUG_RETURN(true);

DBUG_RETURN(false);
}

/*
Geometry item cannot participate in an arithmetic or string comparison or
Expand All @@ -661,15 +653,40 @@ bool Item_bool_func2::resolve_type(THD *thd) {
reject_geometry_args(arg_count, args, this))
DBUG_RETURN(true);

// Make a special case of compare with fields to get nicer DATE comparisons
if (!thd->lex->is_ps_or_view_context_analysis()) {
bool cvt1, cvt2;
if (convert_constant_arg(thd, args[0], &args[1], &cvt1) ||
convert_constant_arg(thd, args[1], &args[0], &cvt2))
DBUG_RETURN(true);
if (cvt1 || cvt2) DBUG_RETURN(false);
}
if (set_cmp_func()) DBUG_RETURN(true);
DBUG_RETURN(false);
DBUG_RETURN(set_cmp_func());
}

bool Item_func_like::resolve_type(THD *) {
// Function returns 0 or 1
max_length = 1;

/*
See agg_item_charsets() in item.cc for comments
on character set and collation aggregation.
*/
if (args[0]->result_type() == STRING_RESULT &&
args[1]->result_type() == STRING_RESULT) {
if (agg_arg_charsets_for_comparison(cmp.cmp_collation, args, 2))
return true;
} else if (args[1]->result_type() == STRING_RESULT) {
cmp.cmp_collation = args[1]->collation;
} else {
cmp.cmp_collation = args[0]->collation;
}

// LIKE is always carried out as string operation
args[0]->cmp_context = STRING_RESULT;
args[1]->cmp_context = STRING_RESULT;

return false;
}

void Arg_comparator::cleanup() {
Expand Down Expand Up @@ -5704,15 +5721,15 @@ longlong Item_func_like::val_int() {

String *res = args[0]->val_str(&cmp.value1);
if (args[0]->null_value) {
null_value = 1;
null_value = true;
return 0;
}
String *res2 = args[1]->val_str(&cmp.value2);
if (args[1]->null_value) {
null_value = 1;
null_value = true;
return 0;
}
null_value = 0;
null_value = false;
if (current_thd->is_error()) return 0;

return my_wildcmp(cmp.cmp_collation.collation, res->ptr(),
Expand Down
1 change: 1 addition & 0 deletions sql/item_cmpfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,7 @@ class Item_func_like final : public Item_bool_func2 {
cond_result eq_cmp_result() const override { return COND_TRUE; }
const char *func_name() const override { return "like"; }
bool fix_fields(THD *thd, Item **ref) override;
bool resolve_type(THD *) override;
void cleanup() override;
/**
@retval true non default escape char specified
Expand Down
2 changes: 1 addition & 1 deletion sql/opt_range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7615,7 +7615,7 @@ static SEL_ROOT *get_mm_leaf(RANGE_OPT_PARAM *param, Item *conf_func,
max_str = min_str + length;
if (maybe_null) max_str[0] = min_str[0] = 0;

Item_func_like *like_func = static_cast<Item_func_like *>(param->cond);
Item_func_like *like_func = down_cast<Item_func_like *>(param->cond);

// We can only optimize with LIKE if the escape string is known.
if (!like_func->escape_is_evaluated()) goto end;
Expand Down

0 comments on commit 4869291

Please sign in to comment.