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
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