MDEV-16865 InnoDB fts_query() ignores KILL

The functions fts_ast_visit() and fts_query() inside
InnoDB FULLTEXT INDEX query processing are not checking
for THD::killed (trx_is_interrupted()), like anything
that potentially takes a long time should do.

This is a port of the following change from MySQL 5.7.23,
with a completely rewritten test case.

commit c58c6f8f66ddd0357ecd0c99646aa6bf1dae49c8
Author: Aakanksha Verma <aakanksha.verma@oracle.com>
Date:   Fri May 4 15:53:13 2018 +0530

Bug #27155294 MAX_EXECUTION_TIME NOT INTERUPTED WITH FULLTEXT SEARCH USING MECAB
This commit is contained in:
Marko Mäkelä 2018-07-31 16:12:38 +03:00
parent b3e95086e1
commit a7f84f09bf
8 changed files with 92 additions and 6 deletions

View File

@ -0,0 +1,6 @@
CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB;
COMMIT;
SELECT COUNT(*) FROM t1
WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE);
KILL QUERY @id;
DROP TABLE t1;

View File

@ -0,0 +1,30 @@
--source include/have_innodb.inc
CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB;
--disable_query_log
BEGIN;
let $n=1000;
while ($n) {
INSERT INTO t1 VALUES('foo bar','boo far');
dec $n;
}
--enable_query_log
COMMIT;
let $id = `SELECT CONNECTION_ID()`;
send SELECT COUNT(*) FROM t1
WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE);
connect (con1,localhost,root,,);
let $ignore= `SELECT @id := $ID`;
KILL QUERY @id;
disconnect con1;
connection default;
# The following would return a result set if the KILL was not fast enough.
--disable_result_log
--error 0,ER_QUERY_INTERRUPTED,HA_ERR_ABORTED_BY_USER
reap;
--enable_result_log
DROP TABLE t1;

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -27,6 +28,7 @@ Created 2007/3/16 Sunny Bains.
#include "fts0ast.h" #include "fts0ast.h"
#include "fts0pars.h" #include "fts0pars.h"
#include "fts0fts.h" #include "fts0fts.h"
#include "row0sel.h"
/* The FTS ast visit pass. */ /* The FTS ast visit pass. */
enum fts_ast_visit_pass_t { enum fts_ast_visit_pass_t {
@ -498,6 +500,7 @@ fts_ast_visit(
bool revisit = false; bool revisit = false;
bool will_be_ignored = false; bool will_be_ignored = false;
fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST; fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST;
const trx_t* trx = node->trx;
start_node = node->list.head; start_node = node->list.head;
@ -596,6 +599,10 @@ fts_ast_visit(
} }
} }
if (trx_is_interrupted(trx)) {
return DB_INTERRUPTED;
}
if (revisit) { if (revisit) {
/* Exist pass processes the skipped FTS_EXIST operation. */ /* Exist pass processes the skipped FTS_EXIST operation. */
for (node = start_node; for (node = start_node;

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -3970,6 +3970,7 @@ fts_query(
/* Parse the input query string. */ /* Parse the input query string. */
if (fts_query_parse(&query, lc_query_str, result_len)) { if (fts_query_parse(&query, lc_query_str, result_len)) {
fts_ast_node_t* ast = query.root; fts_ast_node_t* ast = query.root;
ast->trx = trx;
/* Optimize query to check if it's a single term */ /* Optimize query to check if it's a single term */
fts_query_can_optimize(&query, flags); fts_query_can_optimize(&query, flags);
@ -3983,6 +3984,11 @@ fts_query(
query.error = fts_ast_visit( query.error = fts_ast_visit(
FTS_NONE, ast, fts_query_visitor, FTS_NONE, ast, fts_query_visitor,
&query, &will_be_ignored); &query, &will_be_ignored);
if (query.error == DB_INTERRUPTED) {
error = DB_INTERRUPTED;
ut_free(lc_query_str);
goto func_exit;
}
/* If query expansion is requested, extend the search /* If query expansion is requested, extend the search
with first search pass result */ with first search pass result */
@ -4010,6 +4016,15 @@ fts_query(
memset(*result, 0, sizeof(**result)); memset(*result, 0, sizeof(**result));
} }
if (trx_is_interrupted(trx)) {
error = DB_INTERRUPTED;
ut_free(lc_query_str);
if (result != NULL) {
fts_query_free_result(*result);
}
goto func_exit;
}
ut_free(lc_query_str); ut_free(lc_query_str);
if (fts_enable_diag_print && (*result)) { if (fts_enable_diag_print && (*result)) {

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -314,6 +315,8 @@ struct fts_ast_node_t {
fts_ast_node_t* next_alloc; /*!< For tracking allocations */ fts_ast_node_t* next_alloc; /*!< For tracking allocations */
bool visited; /*!< whether this node is bool visited; /*!< whether this node is
already processed */ already processed */
/** current transaction */
const trx_t* trx;
}; };
/* To track state during parsing */ /* To track state during parsing */

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -27,6 +28,7 @@ Created 2007/3/16 Sunny Bains.
#include "fts0ast.h" #include "fts0ast.h"
#include "fts0pars.h" #include "fts0pars.h"
#include "fts0fts.h" #include "fts0fts.h"
#include "row0sel.h"
/* The FTS ast visit pass. */ /* The FTS ast visit pass. */
enum fts_ast_visit_pass_t { enum fts_ast_visit_pass_t {
@ -498,6 +500,7 @@ fts_ast_visit(
bool revisit = false; bool revisit = false;
bool will_be_ignored = false; bool will_be_ignored = false;
fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST; fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST;
const trx_t* trx = node->trx;
start_node = node->list.head; start_node = node->list.head;
@ -596,6 +599,10 @@ fts_ast_visit(
} }
} }
if (trx_is_interrupted(trx)) {
return DB_INTERRUPTED;
}
if (revisit) { if (revisit) {
/* Exist pass processes the skipped FTS_EXIST operation. */ /* Exist pass processes the skipped FTS_EXIST operation. */
for (node = start_node; for (node = start_node;

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -3989,6 +3989,7 @@ fts_query(
/* Parse the input query string. */ /* Parse the input query string. */
if (fts_query_parse(&query, lc_query_str, result_len)) { if (fts_query_parse(&query, lc_query_str, result_len)) {
fts_ast_node_t* ast = query.root; fts_ast_node_t* ast = query.root;
ast->trx = trx;
/* Optimize query to check if it's a single term */ /* Optimize query to check if it's a single term */
fts_query_can_optimize(&query, flags); fts_query_can_optimize(&query, flags);
@ -4002,6 +4003,11 @@ fts_query(
query.error = fts_ast_visit( query.error = fts_ast_visit(
FTS_NONE, ast, fts_query_visitor, FTS_NONE, ast, fts_query_visitor,
&query, &will_be_ignored); &query, &will_be_ignored);
if (query.error == DB_INTERRUPTED) {
error = DB_INTERRUPTED;
ut_free(lc_query_str);
goto func_exit;
}
/* If query expansion is requested, extend the search /* If query expansion is requested, extend the search
with first search pass result */ with first search pass result */
@ -4029,6 +4035,15 @@ fts_query(
memset(*result, 0, sizeof(**result)); memset(*result, 0, sizeof(**result));
} }
if (trx_is_interrupted(trx)) {
error = DB_INTERRUPTED;
ut_free(lc_query_str);
if (result != NULL) {
fts_query_free_result(*result);
}
goto func_exit;
}
ut_free(lc_query_str); ut_free(lc_query_str);
if (fts_enable_diag_print && (*result)) { if (fts_enable_diag_print && (*result)) {

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -314,6 +315,8 @@ struct fts_ast_node_t {
fts_ast_node_t* next_alloc; /*!< For tracking allocations */ fts_ast_node_t* next_alloc; /*!< For tracking allocations */
bool visited; /*!< whether this node is bool visited; /*!< whether this node is
already processed */ already processed */
/** current transaction */
const trx_t* trx;
}; };
/* To track state during parsing */ /* To track state during parsing */