Commit a7f84f09 authored by Marko Mäkelä's avatar Marko Mäkelä

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
parent b3e95086
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;
--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;
/***************************************************************************** /*****************************************************************************
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. ...@@ -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( ...@@ -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( ...@@ -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;
......
/***************************************************************************** /*****************************************************************************
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( ...@@ -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( ...@@ -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( ...@@ -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)) {
......
/***************************************************************************** /*****************************************************************************
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 { ...@@ -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 */
......
/***************************************************************************** /*****************************************************************************
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. ...@@ -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( ...@@ -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( ...@@ -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;
......
/***************************************************************************** /*****************************************************************************
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( ...@@ -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( ...@@ -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( ...@@ -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)) {
......
/***************************************************************************** /*****************************************************************************
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 { ...@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment