← Back to team overview

maria-developers team mailing list archive

Re: [Commits] aa9bd40: MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc()

 

Hi Sergey!

I think you commited the AAA.test file by mystake.

Regards,
Vicentiu

On Mon, 24 Oct 2016 at 13:47 Sergey Vojtovich <svoj@xxxxxxxxxxx> wrote:

> revision-id: aa9bd40f8067e1421ad71d2ada367544a6db78ca
> (mariadb-10.0.27-8-gaa9bd40)
> parent(s): 4dfb6a3f54cfb26535636197cc5fa70fe5bacc2e
> committer: Sergey Vojtovich
> timestamp: 2016-10-24 15:26:11 +0400
> message:
>
> MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc()
>
> Code flow hit incorrect branch while closing table instances before
> removal.
> This branch expects thread to hold open table instance, whereas CREATE OR
> REPLACE doesn't actually hold open table instance.
>
> Before CREATE OR REPLACE TABLE it was impossible to hit this condition in
> LTM_PRELOCKED mode, thus the problem didn't expose itself during DROP TABLE
> or DROP DATABASE.
>
> Fixed by adjusting condition to take into account LTM_PRELOCKED mode,
> which can
> be set during CREATE OR REPLACE TABLE.
>
> ---
>  mysql-test/r/create_or_replace.result | 11 +++++++++++
>  mysql-test/t/AAA.test                 | 24 ++++++++++++++++++++++++
>  mysql-test/t/create_or_replace.test   | 12 ++++++++++++
>  sql/sql_parse.cc                      | 12 ------------
>  sql/sql_table.cc                      |  3 ++-
>  5 files changed, 49 insertions(+), 13 deletions(-)
>
> diff --git a/mysql-test/r/create_or_replace.result
> b/mysql-test/r/create_or_replace.result
> index 3a894e9..a43dc2e 100644
> --- a/mysql-test/r/create_or_replace.result
> +++ b/mysql-test/r/create_or_replace.result
> @@ -442,3 +442,14 @@ KILL QUERY con_id;
>  ERROR 70100: Query execution was interrupted
>  drop table t1;
>  DROP TABLE t2;
> +#
> +# MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc()
> +#
> +CREATE TABLE t1(a INT);
> +CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test';
> +CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +LOCK TABLE t1 WRITE;
> +CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +UNLOCK TABLES;
> +DROP FUNCTION f1;
> +DROP TABLE t1;
> diff --git a/mysql-test/t/AAA.test b/mysql-test/t/AAA.test
> new file mode 100644
> index 0000000..22e22dd
> --- /dev/null
> +++ b/mysql-test/t/AAA.test
> @@ -0,0 +1,24 @@
> +CREATE TABLE t1(a INT);
> +DELIMITER $$;
> +CREATE FUNCTION f2() RETURNS VARCHAR(16383) RETURN 'test';
> +CREATE FUNCTION f1() RETURNS VARCHAR(16383)
> +BEGIN
> +  INSERT INTO t1 VALUES(1);
> +  RETURN 'test';
> +END;
> +$$
> +CREATE PROCEDURE p1() CREATE OR REPLACE TABLE t1 AS SELECT f2();
> +$$
> +DELIMITER ;$$
> +
> +CALL p1;
> +
> +#CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +LOCK TABLE t1 WRITE;
> +#CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +UNLOCK TABLES;
> +
> +DROP PROCEDURE p1;
> +DROP FUNCTION f1;
> +DROP FUNCTION f2;
> +DROP TABLE t1;
> diff --git a/mysql-test/t/create_or_replace.test
> b/mysql-test/t/create_or_replace.test
> index 7bba2b3..b37417f 100644
> --- a/mysql-test/t/create_or_replace.test
> +++ b/mysql-test/t/create_or_replace.test
> @@ -386,3 +386,15 @@ drop table t1;
>  # Cleanup
>  #
>  DROP TABLE t2;
> +
> +--echo #
> +--echo # MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT
> spfunc()
> +--echo #
> +CREATE TABLE t1(a INT);
> +CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test';
> +CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +LOCK TABLE t1 WRITE;
> +CREATE OR REPLACE TABLE t1 AS SELECT f1();
> +UNLOCK TABLES;
> +DROP FUNCTION f1;
> +DROP TABLE t1;
> diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
> index cbf723c..70511fc 100644
> --- a/sql/sql_parse.cc
> +++ b/sql/sql_parse.cc
> @@ -2858,12 +2858,6 @@ case SQLCOM_PREPARE:
>      }
>
>      /*
> -      For CREATE TABLE we should not open the table even if it exists.
> -      If the table exists, we should either not create it or replace it
> -    */
> -    lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
> -
> -    /*
>        If we are a slave, we should add OR REPLACE if we don't have
>        IF EXISTS. This will help a slave to recover from
>        CREATE TABLE OR EXISTS failures by dropping the table and
> @@ -8225,12 +8219,6 @@ bool create_table_precheck(THD *thd, TABLE_LIST
> *tables,
>    if (check_fk_parent_table_access(thd, &lex->create_info,
> &lex->alter_info, create_table->db))
>      goto err;
>
> -  /*
> -    For CREATE TABLE we should not open the table even if it exists.
> -    If the table exists, we should either not create it or replace it
> -  */
> -  lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
> -
>    error= FALSE;
>
>  err:
> diff --git a/sql/sql_table.cc b/sql/sql_table.cc
> index 7cf31ee..050a338 100644
> --- a/sql/sql_table.cc
> +++ b/sql/sql_table.cc
> @@ -2464,7 +2464,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST
> *tables, bool if_exists,
>        if (table_type && table_type != view_pseudo_hton)
>          ha_lock_engine(thd, table_type);
>
> -      if (thd->locked_tables_mode)
> +      if (thd->locked_tables_mode == LTM_LOCK_TABLES ||
> +          thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
>        {
>          if (wait_while_table_is_used(thd, table->table,
> HA_EXTRA_NOT_USED))
>          {
> _______________________________________________
> commits mailing list
> commits@xxxxxxxxxxx
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits