<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/mariadb-git.git/sql/sql_select.cc, branch preview-10.8-MDEV-14425-innodb</title>
<subtitle>github.com: MariaDB/server.git
</subtitle>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/'/>
<entry>
<title>Merge 10.7 into 10.8</title>
<updated>2022-01-04T08:30:45+00:00</updated>
<author>
<name>Marko Mäkelä</name>
<email>marko.makela@mariadb.com</email>
</author>
<published>2022-01-04T08:30:45+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=daf4fa5238a67fcf47075721d86d4348adab687b'/>
<id>daf4fa5238a67fcf47075721d86d4348adab687b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge 10.6 into 10.7</title>
<updated>2022-01-04T07:55:58+00:00</updated>
<author>
<name>Marko Mäkelä</name>
<email>marko.makela@mariadb.com</email>
</author>
<published>2022-01-04T07:55:58+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=7dfaded9625e832fade4ef1678bcb21c445dad2b'/>
<id>7dfaded9625e832fade4ef1678bcb21c445dad2b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge 10.5 into 10.6</title>
<updated>2022-01-04T07:26:38+00:00</updated>
<author>
<name>Marko Mäkelä</name>
<email>marko.makela@mariadb.com</email>
</author>
<published>2022-01-04T07:26:38+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=3f5726768f17342fd6dfec1be1e4d71814bc8564'/>
<id>3f5726768f17342fd6dfec1be1e4d71814bc8564</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 10.4 into 10.5</title>
<updated>2021-12-26T11:51:04+00:00</updated>
<author>
<name>Julius Goryavsky</name>
<email>julius.goryavsky@mariadb.com</email>
</author>
<published>2021-12-26T11:51:04+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=55bb933a880bf048ebc4ce6c6e239dcc8268958d'/>
<id>55bb933a880bf048ebc4ce6c6e239dcc8268958d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 10.3 into 10.4</title>
<updated>2021-12-25T11:13:03+00:00</updated>
<author>
<name>Julius Goryavsky</name>
<email>julius.goryavsky@mariadb.com</email>
</author>
<published>2021-12-25T11:13:03+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=681b7784b6bb3d735d0a745f5891844f43becc90'/>
<id>681b7784b6bb3d735d0a745f5891844f43becc90</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 10.2 into 10.3</title>
<updated>2021-12-23T13:14:04+00:00</updated>
<author>
<name>Julius Goryavsky</name>
<email>julius.goryavsky@mariadb.com</email>
</author>
<published>2021-12-23T13:14:04+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=3376668ca8799f2dc79b3d71a55c062d55e0f09b'/>
<id>3376668ca8799f2dc79b3d71a55c062d55e0f09b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix typos in optimizer trace output</title>
<updated>2021-12-23T11:08:43+00:00</updated>
<author>
<name>Sergei Petrunia</name>
<email>psergey@askmonty.org</email>
</author>
<published>2021-12-23T09:03:09+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=4b020bfd9a10f991845b995780db4879f8c9f61d'/>
<id>4b020bfd9a10f991845b995780db4879f8c9f61d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer</title>
<updated>2021-12-23T11:08:43+00:00</updated>
<author>
<name>Sergei Petrunia</name>
<email>psergey@askmonty.org</email>
</author>
<published>2021-12-23T09:00:05+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=397f5cf71ee9424373febe0cb8fb0bce1e02e504'/>
<id>397f5cf71ee9424373febe0cb8fb0bce1e02e504</id>
<content type='text'>
make_join_select() calls const_cond-&gt;val_int(). There are edge cases
where const_cond may have a not-yet optimized subquery.

(The subquery will have used_tables() covered by join-&gt;const_tables. It
will still have const_item()==false, so other parts of the optimizer
will not try to evaluate it.  We should probably mark such subqueries
as constant but that is outside the scope of this MDEV)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
make_join_select() calls const_cond-&gt;val_int(). There are edge cases
where const_cond may have a not-yet optimized subquery.

(The subquery will have used_tables() covered by join-&gt;const_tables. It
will still have const_item()==false, so other parts of the optimizer
will not try to evaluate it.  We should probably mark such subqueries
as constant but that is outside the scope of this MDEV)
</pre>
</div>
</content>
</entry>
<entry>
<title>MDEV-21866: Assertion `!result' failed in convert_const_to_int upon 2nd execution of PS</title>
<updated>2021-12-16T01:48:15+00:00</updated>
<author>
<name>Dmitry Shulga</name>
<email>dmitry.shulga@mariadb.com</email>
</author>
<published>2021-11-08T08:22:06+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=fff8ac2e966ac123a091a3e1be22b59cbc1c7e9b'/>
<id>fff8ac2e966ac123a091a3e1be22b59cbc1c7e9b</id>
<content type='text'>
Consider the following use case:
MariaDB [test]&gt; CREATE TABLE t1 (field1 BIGINT DEFAULT -1);
MariaDB [test]&gt; CREATE VIEW v1 AS SELECT DISTINCT field1 FROM t1;

Repeated execution of the following query as a Prepared Statement

MariaDB [test]&gt; PREPARE stmt FROM 'SELECT * FROM v1 WHERE field1 &lt;=&gt; NULL';
MariaDB [test]&gt; EXECUTE stmt;

results in a crash for a server built with DEBUG.

MariaDB [test]&gt; EXECUTE stmt;
ERROR 2013 (HY000): Lost connection to MySQL server during query

Assertion failed: (!result), function convert_const_to_int, file item_cmpfunc.cc, line 476.
Abort trap: 6 (core dumped)

The crash inside the function convert_const_to_int() happens by the reason
that the value -1 is stored in an instance of the class Field_longlong
on restoring its original value in the statement
  result= field-&gt;store(orig_field_val, TRUE);
that leads to assigning the value 1 to the variable 'result' with subsequent
crash in the DBUG_ASSERT statement following it
  DBUG_ASSERT(!result);

The main matter here is why this assertion failure happens on the second
execution of the prepared statement and doens't on the first one.
On first handling of the statement
  'EXECUTE stmt;'
a temporary table is created for serving the query involving the view 'v1'.
The table is created by the function create_tmp_table() in the following
calls trace: (trace #1)
  JOIN::prepare (at sql_select.cc:725)
    st_select_lex::handle_derived
      LEX::handle_list_of_derived
        TABLE_LIST::handle_derived
          mysql_handle_single_derived
            mysql_derived_prepare
              select_union::create_result_table
                create_tmp_table

Note, that the data member TABLE::status of a TABLE instance returned by the
function create_tmp_table() has the value 0.

Later the function setup_table_map() is called on the TABLE instance just
created for the sake of the temporary table (calls trace #2 is below):
  JOIN::prepare (at sql_select.cc:737)
    setup_tables_and_check_access
      setup_tables
        setup_table_map
where the data member TABLE::status is set to the value STATUS_NO_RECORD.

After that when execution of the method JOIN::prepare reaches calling of
the function setup_without_group() the following calls trace is invoked
  JOIN::prepare
    setup_without_group
      setup_conds
        Item_func::fix_fields
          Item_func_equal::fix_length_and_dec
            Item_bool_rowready_func2::fix_length_and_dec
              Item_func::setup_args_and_comparator
                Item_func::convert_const_compared_to_int_field
                  convert_const_to_int

There is the following code snippet in the function convert_const_to_int()
at the line item_cmpfunc.cc:448
    bool save_field_value= (field_item-&gt;const_item() ||
                            !(field-&gt;table-&gt;status &amp; STATUS_NO_RECORD));
Since field-&gt;table-&gt;status has bits STATUS_NO_RECORD set the variable
save_field_value is false and therefore neither the method
Field_longlong::val_int() nor the method Field_longlong::store is called
on the Field instance that has the numeric value -1.
That is the reason why first execution of the Prepared Statement for the query
  'SELECT * FROM v1 WHERE field1 &lt;=&gt; NULL'
is successful.

On second running of the statement 'EXECUTE stmt' a new temporary tables
is also created by running the calls trace #1 but the trace #2 is not executed
by the reason that data member SELECT_LEX::first_cond_optimization has been set
to false on first execution of the prepared statemet (in the method
JOIN::optimize_inner()). As a consequence, the data member TABLE::status for
a temporary table just created doesn't have the flags STATUS_NO_RECORD set and
therefore on re-execution of the prepared statement the methods
Field_longlong::val_int() and Field_longlong::store() are called for the field
having the value -1 and the DBUG_ASSERT(!result) is fired.

To fix the issue the data member TABLE::status has to be assigned the value
STATUS_NO_RECORD in every place where the macros empty_record() is called
to emptify a record for just instantiated TABLE object created on behalf
the new temporary table.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Consider the following use case:
MariaDB [test]&gt; CREATE TABLE t1 (field1 BIGINT DEFAULT -1);
MariaDB [test]&gt; CREATE VIEW v1 AS SELECT DISTINCT field1 FROM t1;

Repeated execution of the following query as a Prepared Statement

MariaDB [test]&gt; PREPARE stmt FROM 'SELECT * FROM v1 WHERE field1 &lt;=&gt; NULL';
MariaDB [test]&gt; EXECUTE stmt;

results in a crash for a server built with DEBUG.

MariaDB [test]&gt; EXECUTE stmt;
ERROR 2013 (HY000): Lost connection to MySQL server during query

Assertion failed: (!result), function convert_const_to_int, file item_cmpfunc.cc, line 476.
Abort trap: 6 (core dumped)

The crash inside the function convert_const_to_int() happens by the reason
that the value -1 is stored in an instance of the class Field_longlong
on restoring its original value in the statement
  result= field-&gt;store(orig_field_val, TRUE);
that leads to assigning the value 1 to the variable 'result' with subsequent
crash in the DBUG_ASSERT statement following it
  DBUG_ASSERT(!result);

The main matter here is why this assertion failure happens on the second
execution of the prepared statement and doens't on the first one.
On first handling of the statement
  'EXECUTE stmt;'
a temporary table is created for serving the query involving the view 'v1'.
The table is created by the function create_tmp_table() in the following
calls trace: (trace #1)
  JOIN::prepare (at sql_select.cc:725)
    st_select_lex::handle_derived
      LEX::handle_list_of_derived
        TABLE_LIST::handle_derived
          mysql_handle_single_derived
            mysql_derived_prepare
              select_union::create_result_table
                create_tmp_table

Note, that the data member TABLE::status of a TABLE instance returned by the
function create_tmp_table() has the value 0.

Later the function setup_table_map() is called on the TABLE instance just
created for the sake of the temporary table (calls trace #2 is below):
  JOIN::prepare (at sql_select.cc:737)
    setup_tables_and_check_access
      setup_tables
        setup_table_map
where the data member TABLE::status is set to the value STATUS_NO_RECORD.

After that when execution of the method JOIN::prepare reaches calling of
the function setup_without_group() the following calls trace is invoked
  JOIN::prepare
    setup_without_group
      setup_conds
        Item_func::fix_fields
          Item_func_equal::fix_length_and_dec
            Item_bool_rowready_func2::fix_length_and_dec
              Item_func::setup_args_and_comparator
                Item_func::convert_const_compared_to_int_field
                  convert_const_to_int

There is the following code snippet in the function convert_const_to_int()
at the line item_cmpfunc.cc:448
    bool save_field_value= (field_item-&gt;const_item() ||
                            !(field-&gt;table-&gt;status &amp; STATUS_NO_RECORD));
Since field-&gt;table-&gt;status has bits STATUS_NO_RECORD set the variable
save_field_value is false and therefore neither the method
Field_longlong::val_int() nor the method Field_longlong::store is called
on the Field instance that has the numeric value -1.
That is the reason why first execution of the Prepared Statement for the query
  'SELECT * FROM v1 WHERE field1 &lt;=&gt; NULL'
is successful.

On second running of the statement 'EXECUTE stmt' a new temporary tables
is also created by running the calls trace #1 but the trace #2 is not executed
by the reason that data member SELECT_LEX::first_cond_optimization has been set
to false on first execution of the prepared statemet (in the method
JOIN::optimize_inner()). As a consequence, the data member TABLE::status for
a temporary table just created doesn't have the flags STATUS_NO_RECORD set and
therefore on re-execution of the prepared statement the methods
Field_longlong::val_int() and Field_longlong::store() are called for the field
having the value -1 and the DBUG_ASSERT(!result) is fired.

To fix the issue the data member TABLE::status has to be assigned the value
STATUS_NO_RECORD in every place where the macros empty_record() is called
to emptify a record for just instantiated TABLE object created on behalf
the new temporary table.
</pre>
</div>
</content>
</entry>
<entry>
<title>MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT</title>
<updated>2021-12-15T19:43:24+00:00</updated>
<author>
<name>Sergei Petrunia</name>
<email>psergey@askmonty.org</email>
</author>
<published>2021-12-15T12:12:06+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/mariadb-git.git/commit/?id=136bcfdf7504092e7e49eba95e8be010da44c594'/>
<id>136bcfdf7504092e7e49eba95e8be010da44c594</id>
<content type='text'>
Followup to fix for MDEV-25858: When test_if_skip_sort_order() decides
to use an index to satisfy ORDER BY ... LIMIT clause, it should
disable "Range Checked for Each Record" optimization.

Do this in all cases.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Followup to fix for MDEV-25858: When test_if_skip_sort_order() decides
to use an index to satisfy ORDER BY ... LIMIT clause, it should
disable "Range Checked for Each Record" optimization.

Do this in all cases.
</pre>
</div>
</content>
</entry>
</feed>
