Skip to content

Commit 4869291

Browse files
Catalin Besleagadahlerlend
authored andcommitted
Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
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
1 parent 755bffa commit 4869291

File tree

7 files changed

+61
-20
lines changed

7 files changed

+61
-20
lines changed

mysql-test/r/func_like.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,3 +404,16 @@ DELETE FROM t1 WHERE
404404
) LIKE (c1);
405405
ERROR 22007: Incorrect datetime value: '42'
406406
DROP TABLE t1;
407+
#
408+
# Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
409+
#
410+
CREATE TABLE t(col1 DATE);
411+
INSERT INTO t(col1) VALUES('2019-06-13'), ('2019-07-13');
412+
SELECT * FROM t WHERE col1 LIKE '2019%';
413+
col1
414+
2019-06-13
415+
2019-07-13
416+
SELECT * FROM t WHERE col1 LIKE '2019-06-1%';
417+
col1
418+
2019-06-13
419+
DROP TABLE t;

mysql-test/r/type_temporal_fractional.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15587,11 +15587,11 @@ s1
1558715587
1000-00-01 00:00:00
1558815588
1000-00-01 00:00:00
1558915589
DROP TABLE t1;
15590-
SELECT BINARY SYSDATE(6) LIKE '____-__-__ __:__:__.______';
15591-
BINARY SYSDATE(6) LIKE '____-__-__ __:__:__.______'
15590+
SELECT SYSDATE(6) LIKE '____-__-__ __:__:__.______';
15591+
SYSDATE(6) LIKE '____-__-__ __:__:__.______'
1559215592
1
15593-
SELECT BINARY SYSDATE(6) NOT LIKE '%.000000' || BINARY SYSDATE(6) NOT LIKE '%.000000';
15594-
BINARY SYSDATE(6) NOT LIKE '%.000000' || BINARY SYSDATE(6) NOT LIKE '%.000000'
15593+
SELECT SYSDATE(6) NOT LIKE '%.000000' || SYSDATE(6) NOT LIKE '%.000000';
15594+
SYSDATE(6) NOT LIKE '%.000000' || SYSDATE(6) NOT LIKE '%.000000'
1559515595
1
1559615596
Warnings:
1559715597
Warning 1287 '|| as a synonym for OR' is deprecated and will be removed in a future release. Please use OR instead

mysql-test/t/func_like.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,13 @@ DELETE FROM t1 WHERE
316316
(SELECT * WHERE '520:33:32.77' < (c1 - INTERVAL(1) MONTH))
317317
) LIKE (c1);
318318
DROP TABLE t1;
319+
320+
--echo #
321+
--echo # Bug#29904751: LIKE CONDITION FOR DATE COLUMN RETURNS ERROR
322+
--echo #
323+
CREATE TABLE t(col1 DATE);
324+
INSERT INTO t(col1) VALUES('2019-06-13'), ('2019-07-13');
325+
SELECT * FROM t WHERE col1 LIKE '2019%';
326+
SELECT * FROM t WHERE col1 LIKE '2019-06-1%';
327+
DROP TABLE t;
328+

mysql-test/t/type_temporal_fractional.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6231,8 +6231,8 @@ DROP TABLE t1;
62316231

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

62376237
CREATE TABLE t1 (s1 DATETIME(2));
62386238
INSERT INTO t1 VALUES ('1970-01-01 11:11:11.1234');

sql/item_cmpfunc.cc

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -639,14 +639,6 @@ bool Item_bool_func2::resolve_type(THD *thd) {
639639

640640
args[0]->cmp_context = args[1]->cmp_context =
641641
item_cmp_type(args[0]->result_type(), args[1]->result_type());
642-
// Make a special case of compare with fields to get nicer DATE comparisons
643-
644-
if (functype() == LIKE_FUNC) // Disable conversion in case of LIKE function.
645-
{
646-
if (set_cmp_func()) DBUG_RETURN(true);
647-
648-
DBUG_RETURN(false);
649-
}
650642

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

656+
// Make a special case of compare with fields to get nicer DATE comparisons
664657
if (!thd->lex->is_ps_or_view_context_analysis()) {
665658
bool cvt1, cvt2;
666659
if (convert_constant_arg(thd, args[0], &args[1], &cvt1) ||
667660
convert_constant_arg(thd, args[1], &args[0], &cvt2))
668661
DBUG_RETURN(true);
669662
if (cvt1 || cvt2) DBUG_RETURN(false);
670663
}
671-
if (set_cmp_func()) DBUG_RETURN(true);
672-
DBUG_RETURN(false);
664+
DBUG_RETURN(set_cmp_func());
665+
}
666+
667+
bool Item_func_like::resolve_type(THD *) {
668+
// Function returns 0 or 1
669+
max_length = 1;
670+
671+
/*
672+
See agg_item_charsets() in item.cc for comments
673+
on character set and collation aggregation.
674+
*/
675+
if (args[0]->result_type() == STRING_RESULT &&
676+
args[1]->result_type() == STRING_RESULT) {
677+
if (agg_arg_charsets_for_comparison(cmp.cmp_collation, args, 2))
678+
return true;
679+
} else if (args[1]->result_type() == STRING_RESULT) {
680+
cmp.cmp_collation = args[1]->collation;
681+
} else {
682+
cmp.cmp_collation = args[0]->collation;
683+
}
684+
685+
// LIKE is always carried out as string operation
686+
args[0]->cmp_context = STRING_RESULT;
687+
args[1]->cmp_context = STRING_RESULT;
688+
689+
return false;
673690
}
674691

675692
void Arg_comparator::cleanup() {
@@ -5704,15 +5721,15 @@ longlong Item_func_like::val_int() {
57045721

57055722
String *res = args[0]->val_str(&cmp.value1);
57065723
if (args[0]->null_value) {
5707-
null_value = 1;
5724+
null_value = true;
57085725
return 0;
57095726
}
57105727
String *res2 = args[1]->val_str(&cmp.value2);
57115728
if (args[1]->null_value) {
5712-
null_value = 1;
5729+
null_value = true;
57135730
return 0;
57145731
}
5715-
null_value = 0;
5732+
null_value = false;
57165733
if (current_thd->is_error()) return 0;
57175734

57185735
return my_wildcmp(cmp.cmp_collation.collation, res->ptr(),

sql/item_cmpfunc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,7 @@ class Item_func_like final : public Item_bool_func2 {
20262026
cond_result eq_cmp_result() const override { return COND_TRUE; }
20272027
const char *func_name() const override { return "like"; }
20282028
bool fix_fields(THD *thd, Item **ref) override;
2029+
bool resolve_type(THD *) override;
20292030
void cleanup() override;
20302031
/**
20312032
@retval true non default escape char specified

sql/opt_range.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7615,7 +7615,7 @@ static SEL_ROOT *get_mm_leaf(RANGE_OPT_PARAM *param, Item *conf_func,
76157615
max_str = min_str + length;
76167616
if (maybe_null) max_str[0] = min_str[0] = 0;
76177617

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

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

0 commit comments

Comments
 (0)