Description:
From Tencent CDB group, casazhang
hi, something go wrong with an application online, finally we found that gtid_subset should reset null_value to false, otherwise records will be lost when scanning multiple records.
How to repeat:
create table t1 ( c1 int, c2 text);
insert into t1 values (1, '{\"time\":\"2022-09-18 17:18:12\"}');
insert into t1 values (2, '{\"time\":\"2022-09-19 17:18:12\", \"gtid_set_column\":\"c55be2ea-14fc-12ec-a970-043f72e646cf:1-6667608119\"}');
insert into t1 values (3, '{\"time\":\"2022-09-20 17:18:12\"}');
insert into t1 values (4, '{\"time\":\"2022-09-21 17:18:12\", \"gtid_set_column\":\"c55be2ea-14fc-12ec-a970-043f72e646cf:1-6667608114\"}');
insert into t1 values (5, '{\"time\":\"2022-09-22 17:18:12\"}');
insert into t1 values (6, '{\"time\":\"2022-09-23 17:18:12\", \"gtid_set_column\":\"03465097-563b-12ec-a4cb-0c42a14d69f3:1-234648230\"}');
insert into t1 values (7, '{\"time\":\"2022-09-24 17:18:12\"}');
select t1.c1 from t1 where gtid_subset(trim('"' from json_extract(t1.c2, '$.gtid_set_column')), "03465097-563b-12ec-a4cb-0c42a14d69f3:1-234648290") = 0;
drop table t1;
the result should be as follows:
mysql> select t1.c1 from t1 where gtid_subset(trim('"' from json_extract(t1.c2, '$.gtid_set_column')), "03465097-563b-12ec-a4cb-0c42a14d69f3:1-234648290") = 0;
+------+
| c1 |
+------+
| 2 |
| 4 |
+------+
2 rows in set (0.00 sec)
but, it return 0 rows.
Suggested fix:
longlong Item_func_gtid_subset::val_int()
{
DBUG_ENTER("Item_func_gtid_subset::val_int()");
- if (args[0]->null_value || args[1]->null_value)
- {
- null_value= true;
- DBUG_RETURN(0);
- }
String *string1, *string2;
const char *charp1, *charp2;
int ret= 1;
enum_return_status status;
- // get strings without lock
- if ((string1= args[0]->val_str(&buf1)) != NULL &&
- (charp1= string1->c_ptr_safe()) != NULL &&
- (string2= args[1]->val_str(&buf2)) != NULL &&
- (charp2= string2->c_ptr_safe()) != NULL)
+ null_value= false;
+ if ((string1 = args[0]->val_str(&buf1)) == NULL ||
+ (string2 = args[1]->val_str(&buf2)) == NULL)
{
+ null_value = true;
+ ret = 0;
+ } else if ((charp1= string1->c_ptr_safe()) != NULL &&
+ (charp2= string2->c_ptr_safe()) != NULL)
+ { // get strings without lock