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

Assertion `d >= 0' failed in COST_ADD on SELECT w/ a negative cost in optimizer_replay_context

    XMLWordPrintable

Details

    Description

      Likely cause: commit 85595ce69c7252aa402f45762fbe62fc537da668 (MDEV-36523), in read_double(). It is not a regression: CS 13.1.1, the first release with optimizer_replay_context, has the commit.

      CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY kb (b), KEY kbc (b, c));
      INSERT INTO t1 VALUES (1,1,'x'),(2,2,'y'),(3,3,'z');
      SET @ctx='{"tables":[{"name":"test.t1","file_stat_records":3,"data_file_length":16384,"index_file_length":32768,"mean_rec_length":5461,"read_cost_io":4,"read_cost_cpu":0.0104286,"multi_range_read_info_const_calls":[{"index_name":"kb","ranges":["(2) <= (b) <= (2)"],"num_rows":1,"cost":{"avg_io_cost":0.0002048,"cpu_cost":0,"comp_cost":3.2e-05,"copy_cost":0,"limit_cost":0,"setup_cost":0.00079112,"index_cost_io":4,"index_cost_cpu":-100,"row_cost_io":4,"row_cost_cpu":0.00086244},"mrr_mode":76,"max_index_blocks":4,"max_row_blocks":4,"call_number":1}]}]}';
      SET optimizer_replay_context='ctx';
      SELECT * FROM t1 WHERE b = 2;
      SET optimizer_replay_context='';
      DROP TABLE t1;

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      mariadbd: /tmp/optimizer-scan/13.1_dbg/sql/optimizer_costs.h:133: double COST_ADD(double, double): Assertion `d >= 0' failed.

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      Core was generated by `/tmp/optimizer-scan/MD071126-mariadb-13.1.2-linux-x86_64-dbg/bin/mariadbd --no-'.
      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 340473)]
      (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  0x00007fdf7304527e in __GI_raise (sig=sig@entry=6)at ../sysdeps/posix/raise.c:26
      #4  0x00007fdf730288ff in __GI_abort () at ./stdlib/abort.c:79
      #5  0x00007fdf7302881b in __assert_fail_base (fmt=0x7fdf731d1208 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x59a7f21d4b36 "d >= 0", file=file@entry=0x59a7f1fe6ea4 "/tmp/optimizer-scan/13.1_dbg/sql/optimizer_costs.h", line=line@entry=133, function=function@entry=0x59a7f1fe6f06 "double COST_ADD(double, double)")at ./assert/assert.c:96
      #6  0x00007fdf7303b517 in __assert_fail (assertion=0x59a7f21d4b36 "d >= 0", file=0x59a7f1fe6ea4 "/tmp/optimizer-scan/13.1_dbg/sql/optimizer_costs.h", line=133, function=0x59a7f1fe6f06 "double COST_ADD(double, double)")at ./assert/assert.c:105
      #7  0x000059a7f1056524 in COST_ADD (c=0, d=-99.997467159999985)at /tmp/optimizer-scan/13.1_dbg/sql/optimizer_costs.h:133
      #8  0x000059a7f107e11c in best_extension_by_limited_search (join=0x77de4001c380, remaining_tables=1, idx=0, record_count=1, read_time=0, search_depth=62, use_cond_selectivity=4, processed_eq_ref_tables=0x77df340f4f88)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:12292
      #9  0x000059a7f1057f3b in greedy_search (join=0x77de4001c380, remaining_tables=1, search_depth=62, use_cond_selectivity=4)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:10891
      #10 0x000059a7f1056b39 in choose_plan (join=0x77de4001c380, join_tables=1, emb_sjm_nest=0x0) at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:10396
      #11 0x000059a7f1039edf in make_join_statistics (join=0x77de4001c380, tables_list=@0x77de4001a788: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x77de4001cb50, last = 0x77de4001cb50, elements = 1}, <No data fields>}, keyuse_array=0x77de4001c6e0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:6382
      #12 0x000059a7f1031fb9 in JOIN::optimize_inner (this=0x77de4001c380)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:2764
      #13 0x000059a7f102fc86 in JOIN::optimize (this=0x77de4001c380)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:2017
      #14 0x000059a7f10284bd in mysql_select (thd=0x77de40000d60, tables=0x77de4001ac10, fields=@0x77de4001a828: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x77de4001aba0, last = 0x77de4001cf90, elements = 3}, <No data fields>}, conds=0x77de4001b560, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2164525824, result=0x77de4001c350, unit=0x77de400052f8, select_lex=0x77de4001a570)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:5426
      #15 0x000059a7f10280bd in handle_select (thd=0x77de40000d60, lex=0x77de40005218, result=0x77de4001c350, setup_tables_done_option=0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:637
      #16 0x000059a7f0fcd726 in execute_sqlcom_select (thd=0x77de40000d60, all_tables=0x77de4001ac10)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:6216
      #17 0x000059a7f0fc3a1b in mysql_execute_command (thd=0x77de40000d60, is_called_from_prepared_stmt=false)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:3989
      #18 0x000059a7f0fbc828 in mysql_parse (thd=0x77de40000d60, rawbuf=0x77de4001a4d0 "SELECT * FROM t1 WHERE b = 2", length=28, parser_state=0x77df340f79c0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:7955
      #19 0x000059a7f0fb9fde in dispatch_command (command=COM_QUERY, thd=0x77de40000d60, packet=0x77de4000b701 "SELECT * FROM t1 WHERE b = 2", packet_length=28, blocking=true)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:1903
      #20 0x000059a7f0fbd2aa in do_command (thd=0x77de40000d60, blocking=true)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:1437
      #21 0x000059a7f11953fe in do_handle_one_connection (connect=0x59a830122950, put_in_cache=true) at /tmp/optimizer-scan/13.1_dbg/sql/sql_connect.cc:1514
      #22 0x000059a7f11951e1 in handle_one_connection (arg=0x59a83010ef50)at /tmp/optimizer-scan/13.1_dbg/sql/sql_connect.cc:1426
      #23 0x00007fdf7309cb84 in start_thread (arg=<optimized out>)at ./nptl/pthread_create.c:447
      #24 0x00007fdf73129ecc in clone3 ()at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

      A num_rows value above the number of rows in the table gives another assert:

      CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c VARCHAR(20), KEY kb (b), KEY kbc (b, c));
      INSERT INTO t1 VALUES (1,1,'x'),(2,2,'y'),(3,3,'z');
      SET @ctx='{"tables":[{"name":"test.t1","file_stat_records":3,"data_file_length":16384,"index_file_length":32768,"mean_rec_length":5461,"read_cost_io":4,"read_cost_cpu":0.0104286,"multi_range_read_info_const_calls":[{"index_name":"kb","ranges":["(2) <= (b) <= (2)"],"num_rows":2147483648,"cost":{"avg_io_cost":0.0002048,"cpu_cost":0,"comp_cost":3.2e-05,"copy_cost":0,"limit_cost":0,"setup_cost":0.00079112,"index_cost_io":4,"index_cost_cpu":0.00092572,"row_cost_io":4,"row_cost_cpu":0.00086244},"mrr_mode":76,"max_index_blocks":4,"max_row_blocks":4,"call_number":1}]}]}';
      SET optimizer_replay_context='ctx';
      SELECT * FROM t1 WHERE b = 2;
      SET optimizer_replay_context='';
      DROP TABLE t1;

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      mariadbd: /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:112: bool compare_cost(double, double): Assertion `a >= 0.0 && b >= 0.0' failed.

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      Core was generated by `/tmp/optimizer-scan/MD071126-mariadb-13.1.2-linux-x86_64-dbg/bin/mariadbd --no-'.
      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 343896)]
      (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  0x000074570f84527e in __GI_raise (sig=sig@entry=6)at ../sysdeps/posix/raise.c:26
      #4  0x000074570f8288ff in __GI_abort () at ./stdlib/abort.c:79
      #5  0x000074570f82881b in __assert_fail_base (fmt=0x74570f9d1208 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x5d4b25babf26 "a >= 0.0 && b >= 0.0", file=file@entry=0x5d4b25ba7a29 "/tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc", line=line@entry=112, function=function@entry=0x5d4b25babf3b "bool compare_cost(double, double)")at ./assert/assert.c:96
      #6  0x000074570f83b517 in __assert_fail (assertion=0x5d4b25babf26 "a >= 0.0 && b >= 0.0", file=0x5d4b25ba7a29 "/tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc", line=112, function=0x5d4b25babf3b "bool compare_cost(double, double)")at ./assert/assert.c:105
      #7  0x00005d4b24c4c7c1 in compare_cost (a=-68719.472390320007, b=-68719.472390320007)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:112
      #8  0x00005d4b24c18e4b in best_access_path (join=0x6c55dc01c380, s=0x6c55dc01d2e0, remaining_tables=1, join_positions=0x6c55dc01d9b0, idx=0, disable_jbuf=true, record_count=1, pos=0x6c55dc01dc40, loose_scan_pos=0x6c55dc01dd80)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:9821
      #9  0x00005d4b24c444c8 in get_costs_for_tables (join=0x6c55dc01c380, remaining_tables=1, idx=0, record_count=1, trace_one_table=0x7456e90b2ec8, pos=0x6c55dc01d970, store_position=0x7456e90b2dc8, allowed_tables=0x7456e90b2d98, stop_on_eq_ref=false)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:11674
      #10 0x00005d4b24c42d7b in best_extension_by_limited_search (join=0x6c55dc01c380, remaining_tables=1, idx=0, record_count=1, read_time=0, search_depth=62, use_cond_selectivity=4, processed_eq_ref_tables=0x7456e90b2f88)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:12244
      #11 0x00005d4b24c1cf3b in greedy_search (join=0x6c55dc01c380, remaining_tables=1, search_depth=62, use_cond_selectivity=4)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:10891
      #12 0x00005d4b24c1bb39 in choose_plan (join=0x6c55dc01c380, join_tables=1, emb_sjm_nest=0x0) at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:10396
      #13 0x00005d4b24bfeedf in make_join_statistics (join=0x6c55dc01c380, tables_list=@0x6c55dc01a788: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x6c55dc01cb50, last = 0x6c55dc01cb50, elements = 1}, <No data fields>}, keyuse_array=0x6c55dc01c6e0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:6382
      #14 0x00005d4b24bf6fb9 in JOIN::optimize_inner (this=0x6c55dc01c380)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:2764
      #15 0x00005d4b24bf4c86 in JOIN::optimize (this=0x6c55dc01c380)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:2017
      #16 0x00005d4b24bed4bd in mysql_select (thd=0x6c55dc000d60, tables=0x6c55dc01ac10, fields=@0x6c55dc01a828: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x6c55dc01aba0, last = 0x6c55dc01cf90, elements = 3}, <No data fields>}, conds=0x6c55dc01b560, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2164525824, result=0x6c55dc01c350, unit=0x6c55dc0052f8, select_lex=0x6c55dc01a570)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:5426
      #17 0x00005d4b24bed0bd in handle_select (thd=0x6c55dc000d60, lex=0x6c55dc005218, result=0x6c55dc01c350, setup_tables_done_option=0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_select.cc:637
      #18 0x00005d4b24b92726 in execute_sqlcom_select (thd=0x6c55dc000d60, all_tables=0x6c55dc01ac10)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:6216
      #19 0x00005d4b24b88a1b in mysql_execute_command (thd=0x6c55dc000d60, is_called_from_prepared_stmt=false)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:3989
      #20 0x00005d4b24b81828 in mysql_parse (thd=0x6c55dc000d60, rawbuf=0x6c55dc01a4d0 "SELECT * FROM t1 WHERE b = 2", length=28, parser_state=0x7456e90b59c0)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:7955
      #21 0x00005d4b24b7efde in dispatch_command (command=COM_QUERY, thd=0x6c55dc000d60, packet=0x6c55dc00b701 "SELECT * FROM t1 WHERE b = 2", packet_length=28, blocking=true)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:1903
      #22 0x00005d4b24b822aa in do_command (thd=0x6c55dc000d60, blocking=true)at /tmp/optimizer-scan/13.1_dbg/sql/sql_parse.cc:1437
      #23 0x00005d4b24d5a3fe in do_handle_one_connection (connect=0x5d4b4f123950, put_in_cache=true) at /tmp/optimizer-scan/13.1_dbg/sql/sql_connect.cc:1514
      #24 0x00005d4b24d5a1e1 in handle_one_connection (arg=0x5d4b4f10ff50)at /tmp/optimizer-scan/13.1_dbg/sql/sql_connect.cc:1426
      #25 0x000074570f89cb84 in start_thread (arg=<optimized out>)at ./nptl/pthread_create.c:447
      #26 0x000074570f929ecc in clone3 ()at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

      On optimized builds, both queries return the row (2,2,'y').

      From the code it seems that read_double() in sql/sql_json_lib.cc accepts a negative cost from the context. Also, check_quick_select() in sql/opt_range.cc lowers num_rows to the table row count, and subtracts the cost of the extra rows from comp_cost, which comes from the context.

      Attachments

        Issue Links

          Activity

            People

              bsrikanth Srikanth Bondalapati
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - 0d
                  0d
                  Remaining:
                  Time Spent - 1h Remaining Estimate - 1.5d
                  1.5d
                  Logged:
                  Time Spent - 1h Remaining Estimate - 1.5d
                  1h

                  Git Integration

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