diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2022-01-22 12:46:06 +0700 |
---|---|---|
committer | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2022-01-22 12:46:06 +0700 |
commit | f99d141cd26359acd188858a78f3fed607e7a90c (patch) | |
tree | abc476b3c5d9c33610c4ab4d8853570988f0452c | |
parent | faaecc8fcfa922df3b9c33ec96f4998ffee4b0a6 (diff) | |
download | mariadb-git-bb-10.2-MDEV-20516-1.tar.gz |
MDEV-20516: Assertion `!lex->proc_list.first && !lex->result && !lex->param_list.elements' failed in mysql_create_viewbb-10.2-MDEV-20516-1
Execution of the CREATE VIEW statement sent via binary protocol
where the flags of the COM_STMT_EXECUTE request a cursor to be opened
before running the statement results in an assert failure.
This assert fails since the data member thd->lex->result has not null
value pointing to an instance of the class Select_materialize.
The data member thd->lex->result is assigned a pointer to the class
Select_materialize in the function mysql_open_cursor() that invoked
in case the packet COM_STMT_EXECUTE requests a cursor to be opened.
After thd->lex->result is assigned a pointer to an instance of the
class Select_materialize the function mysql_create_view() is called
(indirectly via the function mysql_execute_statement()) and the assert
fails.
The assert
DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
!lex->param_list.elements);
was added by the commit 591c06d4b771124cc2cf453fbf51d5d99a4ad95e.
Unfortunately , the condition
!lex->result
was specified incorrect. It was supposed that the thd->lex->result
is set only by parser on handling the clauses SELECT ... INTO
but indeed it is also set inside mysql_open_cursor() and
that fact was missed by the assert's condition.
So, the fix for this issue is to just remove the condition
!lex->result
from the failing assert.
-rw-r--r-- | sql/sql_view.cc | 14 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 34 |
2 files changed, 46 insertions, 2 deletions
diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 39744fe5704..e7286ae8e84 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -408,8 +408,18 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, bool res= FALSE; DBUG_ENTER("mysql_create_view"); - /* This is ensured in the parser. */ - DBUG_ASSERT(!lex->proc_list.first && !lex->result && + /* + This is ensured in the parser. + NOTE: Originally, the assert below contained the extra condition + && !lex->result + but in this form the assert is failed in case CREATE VIEW run under + cursor (the case when the byte 'flags' in the COM_STMT_EXECUTE packet has + the flag CURSOR_TYPE_READ_ONLY set). For the cursor use case + thd->lex->result is assigned a pointer to the class Select_materialize + inside the function mysql_open_cursor() just before handling of a statement + will be started and the function mysql_create_view() called. + */ + DBUG_ASSERT(!lex->proc_list.first && !lex->param_list.elements); /* diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 69e451c3019..db5c9a8688a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20013,6 +20013,39 @@ static void test_mdev24827() myquery(rc); } +static void test_mdev_20516() +{ + MYSQL_STMT *stmt; + int rc; + unsigned long cursor= CURSOR_TYPE_READ_ONLY; + + myheader("test_mdev_20516"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t1(a INT)"); + myquery(rc); + + const char* query= + "CREATE VIEW v1 AS SELECT * FROM t1"; + + stmt= mysql_stmt_init(mysql); + check_stmt(stmt); + + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} + #ifndef EMBEDDED_LIBRARY #define MDEV19838_MAX_PARAM_COUNT 32 #define MDEV19838_FIELDS_COUNT 17 @@ -20163,6 +20196,7 @@ static void test_mdev19838() #endif // EMBEDDED_LIBRARY static struct my_tests_st my_tests[]= { + { "test_mdev_20516", test_mdev_20516 }, { "test_mdev24827", test_mdev24827 }, { "test_mdev_26145", test_mdev_26145 }, { "disable_query_logs", disable_query_logs }, |