Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mysql-test/suite/innodb/r/bug.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#
# MDEV-27569 Valgrind/MSAN errors in ha_partition::swap_blobs
#
create table t (id int, a int, b text, key(a), primary key (id)) engine=innodb
partition by hash(id) partitions 2;
insert into t (id,a) select seq, seq%10 from seq_1_to_20;
select * from t where id >= 1900 or a in (2,4) limit 1;
id a b
2 2 NULL
drop table t;
# End of 10.11 tests
18 changes: 18 additions & 0 deletions mysql-test/suite/innodb/t/bug.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/have_sequence.inc

# TODO (newbie): compile all innodb_bug*.test into this file

--echo #
--echo # MDEV-27569 Valgrind/MSAN errors in ha_partition::swap_blobs
--echo #
create table t (id int, a int, b text, key(a), primary key (id)) engine=innodb
partition by hash(id) partitions 2;
insert into t (id,a) select seq, seq%10 from seq_1_to_20;
select * from t where id >= 1900 or a in (2,4) limit 1;
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This SELECT uses LIMIT 1 without an ORDER BY, but the WHERE clause matches multiple rows (e.g., a IN (2,4)), so the returned row is not guaranteed and the .result can become flaky across optimizer/plan changes. Add an explicit ordering (e.g., ORDER BY id) or otherwise make the query deterministic.

Suggested change
select * from t where id >= 1900 or a in (2,4) limit 1;
select * from t where id >= 1900 or a in (2,4) order by id limit 1;

Copilot uses AI. Check for mistakes.

# cleanup
drop table t;

--echo # End of 10.11 tests
6 changes: 3 additions & 3 deletions mysql-test/suite/sql_sequence/other.result
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,11 @@ DROP SEQUENCE s1;
#
CREATE SEQUENCE s1 nocache engine=myisam;
CREATE table t1 (a int check (next value for s1 > 0));
ERROR HY000: Function or expression 'nextval()' cannot be used in the CHECK clause of `a`
ERROR 42000: CHECK does not support subqueries or stored functions
CREATE table t1 (a int check (previous value for s1 > 0));
ERROR HY000: Function or expression 'lastval()' cannot be used in the CHECK clause of `a`
ERROR 42000: CHECK does not support subqueries or stored functions
CREATE table t1 (a int check (setval(s1,10)));
ERROR HY000: Function or expression 'setval()' cannot be used in the CHECK clause of `a`
ERROR 42000: CHECK does not support subqueries or stored functions
CREATE TABLE t1 (a int, b int as (next value for s1 > 0));
ERROR HY000: Function or expression 'nextval()' cannot be used in the GENERATED ALWAYS AS clause of `b`
drop sequence s1;
Expand Down
6 changes: 3 additions & 3 deletions mysql-test/suite/sql_sequence/other.test
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ DROP SEQUENCE s1;
--echo #

CREATE SEQUENCE s1 nocache engine=myisam;
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
--error ER_SUBQUERIES_NOT_SUPPORTED
CREATE table t1 (a int check (next value for s1 > 0));
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
--error ER_SUBQUERIES_NOT_SUPPORTED
CREATE table t1 (a int check (previous value for s1 > 0));
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
--error ER_SUBQUERIES_NOT_SUPPORTED
CREATE table t1 (a int check (setval(s1,10)));
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE t1 (a int, b int as (next value for s1 > 0));
Expand Down
13 changes: 13 additions & 0 deletions mysql-test/suite/versioning/r/partition.result
Original file line number Diff line number Diff line change
Expand Up @@ -3586,6 +3586,19 @@ x
1
drop table t1;
#
# MDEV-36362 MariaDB crashes when parsing fuzzer generated PARTITION
#
create table t
partition by system_time
interval setval(a, 1) second_microsecond;
ERROR 42000: INTERVAL does not support subqueries or stored functions
create table t (x int) with system versioning
partition by system_time interval nextval(s) hour;
ERROR 42000: INTERVAL does not support subqueries or stored functions
create table t (x int) with system versioning
partition by system_time interval lastval(s) hour;
ERROR 42000: INTERVAL does not support subqueries or stored functions
#
# MDEV-33289 INTERVAL partitioning by system time does not work close to
# the end of timestamp range
#
Expand Down
8 changes: 8 additions & 0 deletions mysql-test/suite/versioning/r/update.result
Original file line number Diff line number Diff line change
Expand Up @@ -483,3 +483,11 @@ nid nstate check_row(row_start, row_end)
commit;
drop tables t1;
# End of 10.4 tests
#
# MDEV-38854 Assertion table->vers_write fails upon ODKU into table with versioned column
#
create table t (a int, b int, c int with system versioning, unique(b));
insert into t (b) values (1);
insert into t (b) values (1),(1) on duplicate key update a = 3;
drop table t;
# End of 10.11 tests
16 changes: 16 additions & 0 deletions mysql-test/suite/versioning/t/partition.test
Original file line number Diff line number Diff line change
Expand Up @@ -2813,6 +2813,22 @@ Select * from t1 for system_time as of '2000-01-01 00:59:59';

drop table t1;

--echo #
--echo # MDEV-36362 MariaDB crashes when parsing fuzzer generated PARTITION
--echo #
--error ER_SUBQUERIES_NOT_SUPPORTED
create table t
partition by system_time
interval setval(a, 1) second_microsecond;

--error ER_SUBQUERIES_NOT_SUPPORTED
create table t (x int) with system versioning
partition by system_time interval nextval(s) hour;

--error ER_SUBQUERIES_NOT_SUPPORTED
create table t (x int) with system versioning
partition by system_time interval lastval(s) hour;

--echo #
--echo # MDEV-33289 INTERVAL partitioning by system time does not work close to
--echo # the end of timestamp range
Expand Down
10 changes: 10 additions & 0 deletions mysql-test/suite/versioning/t/update.test
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,14 @@ drop tables t1;

--echo # End of 10.4 tests

--echo #
--echo # MDEV-38854 Assertion table->vers_write fails upon ODKU into table with versioned column
--echo #
create table t (a int, b int, c int with system versioning, unique(b));
insert into t (b) values (1);
insert into t (b) values (1),(1) on duplicate key update a = 3;
drop table t;

--echo # End of 10.11 tests

source suite/versioning/common_finish.inc;
25 changes: 16 additions & 9 deletions sql/sql_insert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2247,18 +2247,25 @@ int Write_record::insert_on_duplicate_update(ha_rows *inserted,
if (error != HA_ERR_RECORD_IS_THE_SAME)
{
++*updated;
if (table->versioned() &&
table->vers_check_update(*info->update_fields))
if (table->versioned())
{
if (versioned)
if (table->vers_check_update(*info->update_fields))
{
store_record(table, record[2]);
error= vers_insert_history_row(table);
restore_record(table, record[2]);
if (unlikely(error))
return on_ha_error(error);
if (versioned)
{
store_record(table, record[2]);
error= vers_insert_history_row(table);
restore_record(table, record[2]);
if (unlikely(error))
return on_ha_error(error);
}
++*inserted;
}
++*inserted;
/*
INSERT will need it in the next bulk iteration
(see vers_check_update() and MDEV-25644).
*/
table->vers_write= true;
}
}
/*
Expand Down
55 changes: 55 additions & 0 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3682,6 +3682,31 @@ uint st_select_lex::get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg)
order_group_num * 2 * winfunc_factor +
hidden_bit_fields +
fields_in_window_functions;

#ifndef DBUG_OFF
DBUG_PRINT("ref_array", ("ref_array reserves %u elements", n));
if (n_sum_items)
DBUG_PRINT("ref_array", ("n_sum_items: %u", n_sum_items));
if (n_child_sum_items)
DBUG_PRINT("ref_array", ("n_child_sum_items: %u", n_child_sum_items));
if (item_list.elements)
DBUG_PRINT("ref_array", ("item_list.elements: %u", item_list.elements));
if (select_n_reserved)
DBUG_PRINT("ref_array", ("select_n_reserved: %u", select_n_reserved));
if (select_n_having_items)
DBUG_PRINT("ref_array", ("select_n_having_items: %u", select_n_having_items));
if (select_n_where_fields)
DBUG_PRINT("ref_array", ("select_n_where_fields: %u", select_n_where_fields));
if (order_group_num)
DBUG_PRINT("ref_array", ("order_group_num: %u", order_group_num));
if (hidden_bit_fields)
DBUG_PRINT("ref_array", ("hidden_bit_fields: %u", hidden_bit_fields));
if (fields_in_window_functions)
DBUG_PRINT("ref_array", ("fields_in_window_functions: %u", fields_in_window_functions));
if (window_funcs.elements)
DBUG_PRINT("ref_array", ("window_funcs.elements: %u (winfunc_factor %u)", window_funcs.elements, winfunc_factor));
#endif

return n;
}

Expand Down Expand Up @@ -8370,6 +8395,12 @@ my_var *LEX::create_outvar(THD *thd,
Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident)
{
TABLE_LIST *table;
if (clause_that_disallows_subselect)
{
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
clause_that_disallows_subselect);
return NULL;
}
if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0,
TL_OPTION_SEQUENCE,
TL_WRITE_ALLOW_WRITE,
Expand All @@ -8383,6 +8414,12 @@ Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident)
Item *LEX::create_item_func_lastval(THD *thd, Table_ident *table_ident)
{
TABLE_LIST *table;
if (clause_that_disallows_subselect)
{
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
clause_that_disallows_subselect);
return NULL;
}
if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0,
TL_OPTION_SEQUENCE,
TL_READ,
Expand All @@ -8398,6 +8435,12 @@ Item *LEX::create_item_func_nextval(THD *thd,
const LEX_CSTRING *name)
{
Table_ident *table_ident;
if (clause_that_disallows_subselect)
{
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
clause_that_disallows_subselect);
return NULL;
}
if (unlikely(!(table_ident=
new (thd->mem_root) Table_ident(thd, db, name, false))))
return NULL;
Expand All @@ -8410,6 +8453,12 @@ Item *LEX::create_item_func_lastval(THD *thd,
const LEX_CSTRING *name)
{
Table_ident *table_ident;
if (clause_that_disallows_subselect)
{
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
clause_that_disallows_subselect);
return NULL;
}
if (unlikely(!(table_ident=
new (thd->mem_root) Table_ident(thd, db, name, false))))
return NULL;
Expand All @@ -8422,6 +8471,12 @@ Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident,
bool is_used)
{
TABLE_LIST *table;
if (clause_that_disallows_subselect)
{
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
clause_that_disallows_subselect);
return NULL;
}
if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0,
TL_OPTION_SEQUENCE,
TL_WRITE_ALLOW_WRITE,
Expand Down
2 changes: 2 additions & 0 deletions sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -3479,6 +3479,8 @@ struct LEX: public Query_tables_list
not support subqueries which comes standard with this rule, like
KILL, HA_READ, CREATE/ALTER EVENT etc. Set this to a non-NULL
clause name to get an error.
Note: see also table_or_sp_used().
*/
const char *clause_that_disallows_subselect;

Expand Down
53 changes: 50 additions & 3 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1553,11 +1553,21 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
}
}

#ifdef DBUG_TRACE
uint dbug_elements= all_fields.elements;
DBUG_PRINT("ref_array", ("Parser requires %u elements", dbug_elements));
#endif

if (setup_fields(thd, ref_ptrs, fields_list, MARK_COLUMNS_READ,
&all_fields, &select_lex->pre_fix, 1))
DBUG_RETURN(-1);
thd->lex->current_select->context_analysis_place= save_place;

#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("setup_fields() requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif

if (setup_without_group(thd, ref_ptrs, tables_list,
select_lex->leaf_tables, fields_list,
all_fields, &conds, order, group_list,
Expand All @@ -1566,6 +1576,11 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
&hidden_group_fields))
DBUG_RETURN(-1);

#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("setup_without_group() requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif

/*
Permanently remove redundant parts from the query if
1) This is a subquery
Expand Down Expand Up @@ -1599,6 +1614,10 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
}
thd->lex->allow_sum_func= save_allow_sum_func;
select_lex->order_list.empty();
#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("find_order_in_list() requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif
}

if (having)
Expand Down Expand Up @@ -1707,6 +1726,11 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
can produce a meaningful sorted set. */
if (!requires_sorting)
order= NULL;

#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("ORDER requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif
}
else
{
Expand All @@ -1719,8 +1743,14 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
}

if (having && (having->with_sum_func() || having->with_rownum_func()))
{
having->split_sum_func2(thd, ref_ptrs, all_fields,
&having, SPLIT_SUM_SKIP_REGISTERED);
#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("HAVING requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif
}
if (select_lex->inner_sum_func_list)
{
Item_sum *end=select_lex->inner_sum_func_list;
Expand All @@ -1731,11 +1761,22 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
item_sum->split_sum_func2(thd, ref_ptrs,
all_fields, item_sum->ref_by, 0);
} while (item_sum != end);
#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("inner_sum_func requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif
}

if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, ref_ptrs))
DBUG_RETURN(-1);
if (select_lex->inner_refs_list.elements)
{
if (fix_inner_refs(thd, all_fields, select_lex, ref_ptrs))
DBUG_RETURN(-1);
#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("inner_refs requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif

}

if (group_list)
{
Expand All @@ -1759,8 +1800,14 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
ord->item= &ref_ptrs[el];
}
}
#ifdef DBUG_TRACE
DBUG_PRINT("ref_array", ("group_list requires %u elements", all_fields.elements - dbug_elements));
dbug_elements= all_fields.elements;
#endif
}

DBUG_PRINT("ref_array", ("Total of %u elements used", all_fields.elements));

/*
Check if there are references to un-aggregated columns when computing
aggregate functions with implicit grouping (there is no GROUP BY).
Expand Down
Loading