Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-36486

Optimizer hints are resolved against the INSERT part of INSERT..SELECT

Details

    • Bug
    • Status: In Review (View Workflow)
    • Critical
    • Resolution: Unresolved
    • N/A
    • 12.0
    • Optimizer
    • None

    Description

      This bug exists only in preview-12.0-preview, not in any other version including 12.0 trunk as of today.

      CREATE TABLE t (a CHAR,KEY(a));
      INSERT INTO t (a) SELECT /*+ no_range_optimization (t a)*/0 FROM t;
      

      Leads to:

      preview-12.0-preview CS 12.0.0 61c96785d1910976fd740aa0724105b16952786d (Debug) Build 29/03/2025

      mariadbd: /test/preview-12.0-preview_dbg/sql/opt_hints.cc:473: bool Opt_hints_table::fix_hint(TABLE *): Assertion `keyinfo_array.size() == 0' failed.
      

      preview-12.0-preview CS 12.0.0 61c96785d1910976fd740aa0724105b16952786d (Debug) Build 29/03/2025

      Core was generated by `/test/P12_MD290325-mariadb-12.0.0-linux-x86_64-dbg/bin/mariadbd --no-defaults -'.
      Program terminated with signal SIGABRT, Aborted.
      #0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:44
       
      [Current thread is 1 (LWP 3630775)]
      (gdb) bt
      #0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:44
      #1  __pthread_kill_internal (signo=6, threadid=<optimized out>)at ./nptl/pthread_kill.c:78
      #2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6)at ./nptl/pthread_kill.c:89
      #3  0x0000732a44a4526e in __GI_raise (sig=sig@entry=6)at ../sysdeps/posix/raise.c:26
      #4  0x0000732a44a288ff in __GI_abort () at ./stdlib/abort.c:79
      #5  0x0000732a44a2881b in __assert_fail_base (fmt=0x732a44bd01e8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x5c2d1552247f "keyinfo_array.size() == 0", file=file@entry=0x5c2d15522361 "/test/preview-12.0-preview_dbg/sql/opt_hints.cc", line=line@entry=473, function=function@entry=0x5c2d15522499 "bool Opt_hints_table::fix_hint(TABLE *)") at ./assert/assert.c:94
      #6  0x0000732a44a3b507 in __assert_fail (assertion=0x5c2d1552247f "keyinfo_array.size() == 0", file=0x5c2d15522361 "/test/preview-12.0-preview_dbg/sql/opt_hints.cc", line=473, function=0x5c2d15522499 "bool Opt_hints_table::fix_hint(TABLE *)")at ./assert/assert.c:103
      #7  0x00005c2d147ce1c5 in Opt_hints_table::fix_hint (this=0x730b5401bcf8, table=0x730b54030678)at /test/preview-12.0-preview_dbg/sql/opt_hints.cc:473
      #8  0x00005c2d147ce0d4 in Opt_hints_qb::fix_hints_for_table (this=0x730b5401bb58, table=0x730b54030678, alias=@0x730b5401b3f0: {<Lex_ident_fs> = {<Lex_ident<Compare_table_names>> = {<Lex_cstring> = {<st_mysql_const_lex_string> = {str = 0x730b5401b3a0 "t", length = 1}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}) at /test/preview-12.0-preview_dbg/sql/opt_hints.cc:390
      #9  0x00005c2d143c7404 in setup_tables (thd=0x730b54000d58, context=0x730b5401ae40, from_clause=0x730b5401afb0, tables=0x730b5401a0f8, leaves=@0x730b5401b010: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x730b5401c870, last = 0x730b5401c880, elements = 2}, <No data fields>}, select_insert=true, full_table_list=true, resolve_opt_hints=true)at /test/preview-12.0-preview_dbg/sql/sql_base.cc:8326
      #10 0x00005c2d143c7cba in setup_tables_and_check_access (thd=0x730b54000d58, context=0x730b5401ae40, from_clause=0x730b5401afb0, tables=0x730b5401a0f8, leaves=@0x730b5401b010: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x730b5401c870, last = 0x730b5401c880, elements = 2}, <No data fields>}, select_insert=true, want_access_first=INSERT_ACL, want_access=SELECT_ACL, full_table_list=true, resolve_opt_hints=true)at /test/preview-12.0-preview_dbg/sql/sql_base.cc:8451
      #11 0x00005c2d14422b7a in mysql_prepare_insert_check_table (thd=0x730b54000d58, table_list=0x730b5401a0f8, fields=@0x730b540060d8: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x730b5401a958, last = 0x730b5401a958, elements = 1}, <No data fields>}, select_insert=true)at /test/preview-12.0-preview_dbg/sql/sql_insert.cc:1635
      #12 0x00005c2d144203ab in mysql_prepare_insert (thd=0x730b54000d58, table_list=0x730b5401a0f8, fields=@0x730b540060d8: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x730b5401a958, last = 0x730b5401a958, elements = 1}, <No data fields>}, values=0x0, update_fields=@0x730b54006108: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5c2d16088330 <end_of_list>, last = 0x730b54006108, elements = 0}, <No data fields>}, update_values=@0x730b540060f0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5c2d16088330 <end_of_list>, last = 0x730b540060f0, elements = 0}, <No data fields>}, duplic=DUP_ERROR, ignore=false, where=0x730b5401aeb8, select_insert=true)at /test/preview-12.0-preview_dbg/sql/sql_insert.cc:1754
      #13 0x00005c2d144266af in mysql_insert_select_prepare (thd=0x730b54000d58, sel_res=0x0) at /test/preview-12.0-preview_dbg/sql/sql_insert.cc:3994
      #14 0x00005c2d1448bcbd in mysql_execute_command (thd=0x730b54000d58, is_called_from_prepared_stmt=false)at /test/preview-12.0-preview_dbg/sql/sql_parse.cc:4631
      #15 0x00005c2d14480b54 in mysql_parse (thd=0x730b54000d58, rawbuf=0x730b54019fc0 "INSERT INTO t (a) SELECT /*+ no_range_optimization (t a)*/0 FROM t", length=66, parser_state=0x732a37f67a10)at /test/preview-12.0-preview_dbg/sql/sql_parse.cc:7889
      #16 0x00005c2d1447df28 in dispatch_command (command=COM_QUERY, thd=0x730b54000d58, packet=0x730b5400b339 "INSERT INTO t (a) SELECT /*+ no_range_optimization (t a)*/0 FROM t", packet_length=66, blocking=true)at /test/preview-12.0-preview_dbg/sql/sql_parse.cc:1875
      #17 0x00005c2d14481703 in do_command (thd=0x730b54000d58, blocking=true)at /test/preview-12.0-preview_dbg/sql/sql_parse.cc:1416
      #18 0x00005c2d1466e7e9 in do_handle_one_connection (connect=0x5c2d18968468, put_in_cache=true)at /test/preview-12.0-preview_dbg/sql/sql_connect.cc:1415
      #19 0x00005c2d1466e58e in handle_one_connection (arg=0x5c2d18a1c8e8)at /test/preview-12.0-preview_dbg/sql/sql_connect.cc:1327
      #20 0x0000732a44a9ca94 in start_thread (arg=<optimized out>)at ./nptl/pthread_create.c:447
      #21 0x0000732a44b29c3c in clone3 ()at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
      

      Attachments

        Issue Links

          Activity

            oleg.smirnov Oleg Smirnov added a comment - - edited

            The whole INSERT..SELECT is a single query block (i.e., a single SELECT_LEX):

            INSERT INTO t (a) SELECT /*+ no_range_optimization (t a)*/0 FROM t;
            

            It has two TABLE_LIST objects with the same name `t`. During hints resolution, when hints are attached to particular TABLE_LIST's, the search is performed by table name. Usually tables having same name cannot be present in a single query block, however it is allowed for INSERT..SELECT clauses.

            What happens here is the hint `no_range_optimization (t a)` is first attached to the table `t` in the INSERT part (which is already wrong) and then is tried to be attached to table `t` in the SELECT part. The second attempt triggers an assertion.

            Such behaviour is possible at least for INSERT..SELECT's having same table name in both INSERT and SELECT parts, however UPDATE's and DELETE's can be affected too.

            oleg.smirnov Oleg Smirnov added a comment - - edited The whole INSERT..SELECT is a single query block (i.e., a single SELECT_LEX): INSERT INTO t (a) SELECT /*+ no_range_optimization (t a)*/ 0 FROM t; It has two TABLE_LIST objects with the same name `t`. During hints resolution, when hints are attached to particular TABLE_LIST's, the search is performed by table name. Usually tables having same name cannot be present in a single query block, however it is allowed for INSERT..SELECT clauses. What happens here is the hint `no_range_optimization (t a)` is first attached to the table `t` in the INSERT part (which is already wrong) and then is tried to be attached to table `t` in the SELECT part. The second attempt triggers an assertion. Such behaviour is possible at least for INSERT..SELECT's having same table name in both INSERT and SELECT parts, however UPDATE's and DELETE's can be affected too.
            oleg.smirnov Oleg Smirnov added a comment -

            psergei, please review the PR

            oleg.smirnov Oleg Smirnov added a comment - psergei , please review the PR

            Looks good.

            psergei Sergei Petrunia added a comment - Looks good.
            oleg.smirnov Oleg Smirnov added a comment -

            It is related to the optimizer hints feature (MDEV-35504).

            I'm not pushing the proposed solution 'cause I found another bug in hints resolution for INSERT..SELECT statements and want to fix it along with this one.

            oleg.smirnov Oleg Smirnov added a comment - It is related to the optimizer hints feature ( MDEV-35504 ). I'm not pushing the proposed solution 'cause I found another bug in hints resolution for INSERT..SELECT statements and want to fix it along with this one.
            oleg.smirnov Oleg Smirnov added a comment -

            Last patch has broken `opt_hint_timeout.test`, please see the improved one force-pushed to the same pull request.

            oleg.smirnov Oleg Smirnov added a comment - Last patch has broken `opt_hint_timeout.test`, please see the improved one force-pushed to the same pull request .

            People

              psergei Sergei Petrunia
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.