Revert "MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT"

This reverts commit 49e14000ee
as it introduces regression MDEV-29935 and has to be reconsidered
in general
This commit is contained in:
Oleg Smirnov 2024-10-25 14:35:22 +07:00
parent 271b73770c
commit e640373389
8 changed files with 59 additions and 264 deletions

View file

@ -883,76 +883,6 @@ INSERT INTO t1 SELECT a*2 FROM t1 ORDER BY a;
Warnings:
Warning 1264 Out of range value for column 'a' at row 4
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 (a) SELECT SUM(1);
INSERT INTO t1 (a, b) SELECT AVG(2), MIN(3);
INSERT INTO t1 (b) SELECT AVG('x') OVER ();
ERROR 22007: Truncated incorrect DOUBLE value: 'x'
INSERT INTO t1 SELECT MIN(7) OVER (), MAX(8) OVER();
SELECT * FROM t1;
a b
1 NULL
2 3
7 8
PREPARE stmt FROM 'INSERT INTO t1 (a) SELECT AVG(?)';
EXECUTE stmt USING 9;
EXECUTE stmt USING 10;
PREPARE stmt FROM 'INSERT INTO t1 SELECT MIN(?), MAX(?)';
EXECUTE stmt USING 11, 12;
EXECUTE stmt USING 13, 14;
DEALLOCATE PREPARE stmt;
SELECT * FROM t1;
a b
1 NULL
2 3
7 8
9 NULL
10 NULL
11 12
13 14
CREATE PROCEDURE p1(param_a INT, param_b INT)
BEGIN
INSERT INTO t1 SELECT MIN(param_a) OVER (), MAX(param_b);
END//
CALL p1(21, 22);
CALL p1(23, 24);
SELECT * FROM t1;
a b
1 NULL
2 3
7 8
9 NULL
10 NULL
11 12
13 14
21 22
23 24
CREATE TABLE t2 (
a DECIMAL UNIQUE CHECK (CASE 0 * 27302337.000000 WHEN 34 THEN
+ 'x' LIKE 'x' OR a NOT IN (-1 / TRUE ^ 2) ELSE 7105743.000000 END));
INSERT INTO t2 VALUES (90),( -1),(31152443.000000),(-32768),(NULL),(NULL);
INSERT INTO t2 SELECT AVG('x') OVER (
PARTITION BY ((NOT AVG(76698761.000000))) IS NOT NULL);
ERROR 22007: Truncated incorrect DOUBLE value: 'x'
INSERT IGNORE INTO t2 () VALUES (0),('x'),(3751286.000000),
('x'),((a = 'x' AND 0 AND 0));
Warnings:
Warning 1366 Incorrect decimal value: 'x' for column `test`.`t2`.`a` at row 2
Warning 1062 Duplicate entry '0' for key 'a'
Warning 1366 Incorrect decimal value: 'x' for column `test`.`t2`.`a` at row 4
Warning 1062 Duplicate entry '0' for key 'a'
Warning 1062 Duplicate entry '0' for key 'a'
INSERT INTO t2 VALUES (127);
INSERT INTO t2 SELECT -2147483648 END FROM t2 AS TEXT JOIN t2 JOIN t2 TABLES;
ERROR 23000: Duplicate entry '-2147483648' for key 'a'
ALTER TABLE t2 ADD (
b INT UNIQUE CHECK ((a = 'x' AND ((-(+(BINARY 49730460.000000)))) = 'x'
BETWEEN 'x' AND 'x')));
ERROR 22007: Truncated incorrect DECIMAL value: 'x'
UPDATE t2 SET a = -128 WHERE a IS NULL ORDER BY 78 IN ('x','x'),a;
ERROR 23000: Duplicate entry '-128' for key 'a'
DROP TABLE t1, t2;
DROP PROCEDURE p1;
# End of 10.2 test
#
# MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY

View file

@ -459,60 +459,6 @@ INSERT INTO t1 SELECT a*2 FROM t1 ORDER BY a;
DROP TABLE t1;
#
# MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT
#
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 (a) SELECT SUM(1);
INSERT INTO t1 (a, b) SELECT AVG(2), MIN(3);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 (b) SELECT AVG('x') OVER ();
INSERT INTO t1 SELECT MIN(7) OVER (), MAX(8) OVER();
SELECT * FROM t1;
PREPARE stmt FROM 'INSERT INTO t1 (a) SELECT AVG(?)';
EXECUTE stmt USING 9;
EXECUTE stmt USING 10;
PREPARE stmt FROM 'INSERT INTO t1 SELECT MIN(?), MAX(?)';
EXECUTE stmt USING 11, 12;
EXECUTE stmt USING 13, 14;
DEALLOCATE PREPARE stmt;
SELECT * FROM t1;
DELIMITER //;
CREATE PROCEDURE p1(param_a INT, param_b INT)
BEGIN
INSERT INTO t1 SELECT MIN(param_a) OVER (), MAX(param_b);
END//
DELIMITER ;//
CALL p1(21, 22);
CALL p1(23, 24);
SELECT * FROM t1;
CREATE TABLE t2 (
a DECIMAL UNIQUE CHECK (CASE 0 * 27302337.000000 WHEN 34 THEN
+ 'x' LIKE 'x' OR a NOT IN (-1 / TRUE ^ 2) ELSE 7105743.000000 END));
INSERT INTO t2 VALUES (90),( -1),(31152443.000000),(-32768),(NULL),(NULL);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t2 SELECT AVG('x') OVER (
PARTITION BY ((NOT AVG(76698761.000000))) IS NOT NULL);
INSERT IGNORE INTO t2 () VALUES (0),('x'),(3751286.000000),
('x'),((a = 'x' AND 0 AND 0));
INSERT INTO t2 VALUES (127);
--error ER_DUP_ENTRY
INSERT INTO t2 SELECT -2147483648 END FROM t2 AS TEXT JOIN t2 JOIN t2 TABLES;
--error ER_TRUNCATED_WRONG_VALUE
ALTER TABLE t2 ADD (
b INT UNIQUE CHECK ((a = 'x' AND ((-(+(BINARY 49730460.000000)))) = 'x'
BETWEEN 'x' AND 'x')));
--error ER_DUP_ENTRY
UPDATE t2 SET a = -128 WHERE a IS NULL ORDER BY 78 IN ('x','x'),a;
DROP TABLE t1, t2;
DROP PROCEDURE p1;
--echo # End of 10.2 test
--echo #

View file

@ -1503,8 +1503,6 @@ execute stmt1 using @a;
set @a= 301;
execute stmt1 using @a;
deallocate prepare stmt1;
insert into v3(a) select sum(302);
insert into v3(a) select sum(303) over ();
select * from v3;
a b
100 0
@ -1523,14 +1521,6 @@ a b
301 10
301 1000
301 2000
302 0
302 10
302 1000
302 2000
303 0
303 10
303 1000
303 2000
drop view v3;
drop tables t1,t2;
create table t1(f1 int);

View file

@ -1334,8 +1334,6 @@ execute stmt1 using @a;
set @a= 301;
execute stmt1 using @a;
deallocate prepare stmt1;
insert into v3(a) select sum(302);
insert into v3(a) select sum(303) over ();
--sorted_result
select * from v3;

View file

@ -7708,39 +7708,6 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
DBUG_RETURN(MY_TEST(thd->is_error()));
}
/*
make list of leaves for a single TABLE_LIST
SYNOPSIS
make_leaves_for_single_table()
thd Thread handler
leaves List of leaf tables to be filled
table TABLE_LIST object to process
full_table_list Whether to include tables from mergeable derived table/view
*/
void make_leaves_for_single_table(THD *thd, List<TABLE_LIST> &leaves,
TABLE_LIST *table, bool& full_table_list,
TABLE_LIST *boundary)
{
if (table == boundary)
full_table_list= !full_table_list;
if (full_table_list && table->is_merged_derived())
{
SELECT_LEX *select_lex= table->get_single_select();
/*
It's safe to use select_lex->leaf_tables because all derived
tables/views were already prepared and has their leaf_tables
set properly.
*/
make_leaves_list(thd, leaves, select_lex->get_table_list(),
full_table_list, boundary);
}
else
{
leaves.push_back(table, thd->mem_root);
}
}
/*
Perform checks like all given fields exists, if exists fill struct with
@ -7767,78 +7734,39 @@ int setup_returning_fields(THD* thd, TABLE_LIST* table_list)
SYNOPSIS
make_leaves_list()
leaves List of leaf tables to be filled
tables Table list
full_table_list Whether to include tables from mergeable derived table/view.
We need them for checks for INSERT/UPDATE statements only.
list pointer to pointer on list first element
tables table list
full_table_list whether to include tables from mergeable derived table/view.
we need them for checks for INSERT/UPDATE statements only.
RETURN pointer on pointer to next_leaf of last element
*/
void make_leaves_list(THD *thd, List<TABLE_LIST> &leaves, TABLE_LIST *tables,
void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
bool full_table_list, TABLE_LIST *boundary)
{
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
make_leaves_for_single_table(thd, leaves, table, full_table_list,
boundary);
}
}
if (table == boundary)
full_table_list= !full_table_list;
if (full_table_list && table->is_merged_derived())
{
SELECT_LEX *select_lex= table->get_single_select();
/*
Setup the map and other attributes for a single TABLE_LIST object
SYNOPSIS
setup_table_attributes()
thd Thread handler
table_list TABLE_LIST object to process
first_select_table First table participating in SELECT for INSERT..SELECT
statements, NULL for other cases
tablenr Serial number of the table in the SQL statement
RETURN
false Success
true Failure
It's safe to use select_lex->leaf_tables because all derived
tables/views were already prepared and has their leaf_tables
set properly.
*/
bool setup_table_attributes(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *first_select_table,
uint &tablenr)
{
TABLE *table= table_list->table;
if (table)
table->pos_in_table_list= table_list;
if (first_select_table && table_list->top_table() == first_select_table)
{
/* new counting for SELECT of INSERT ... SELECT command */
first_select_table= 0;
thd->lex->first_select_lex()->insert_tables= tablenr;
tablenr= 0;
make_leaves_list(thd, list, select_lex->get_table_list(),
full_table_list, boundary);
}
if (table_list->jtbm_subselect)
else
{
table_list->jtbm_table_no= tablenr;
list.push_back(table, thd->mem_root);
}
else if (table)
{
table->pos_in_table_list= table_list;
setup_table_map(table, table_list, tablenr);
if (table_list->process_index_hints(table))
return true;
}
tablenr++;
/*
We test the max tables here as we setup_table_map() should not be called
with tablenr >= 64
*/
if (tablenr > MAX_TABLES)
{
my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast<int>(MAX_TABLES));
return true;
}
return false;
}
/*
prepare tables
@ -7896,14 +7824,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
leaves.empty();
if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED)
{
/*
For INSERT ... SELECT statements we must not include the first table
(where the data is being inserted into) in the list of leaves
*/
TABLE_LIST *tables_for_leaves=
select_insert ? first_select_table : tables;
make_leaves_list(thd, leaves, tables_for_leaves, full_table_list,
first_select_table);
make_leaves_list(thd, leaves, tables, full_table_list, first_select_table);
select_lex->prep_leaf_list_state= SELECT_LEX::READY;
select_lex->leaf_tables_exec.empty();
}
@ -7914,34 +7835,37 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
leaves.push_back(table_list, thd->mem_root);
}
List_iterator<TABLE_LIST> ti(leaves);
while ((table_list= ti++))
{
if (setup_table_attributes(thd, table_list, first_select_table, tablenr))
TABLE *table= table_list->table;
if (table)
table->pos_in_table_list= table_list;
if (first_select_table &&
table_list->top_table() == first_select_table)
{
/* new counting for SELECT of INSERT ... SELECT command */
first_select_table= 0;
thd->lex->select_lex.insert_tables= tablenr;
tablenr= 0;
}
if(table_list->jtbm_subselect)
{
table_list->jtbm_table_no= tablenr;
}
else if (table)
{
table->pos_in_table_list= table_list;
setup_table_map(table, table_list, tablenr);
if (table_list->process_index_hints(table))
DBUG_RETURN(1);
}
if (select_insert)
{
/*
The table/view in which the data is inserted must not be included into
the leaf_tables list. But we need this table/view to setup attributes
for it. So build a temporary list of leaves and setup attributes for
the tables included
*/
List<TABLE_LIST> leaves;
TABLE_LIST *table= tables;
make_leaves_for_single_table(thd, leaves, table, full_table_list,
first_select_table);
List_iterator<TABLE_LIST> ti(leaves);
while ((table_list= ti++))
{
if (setup_table_attributes(thd, table_list, first_select_table,
tablenr))
DBUG_RETURN(1);
tablenr++;
}
if (tablenr > MAX_TABLES)
{
my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES));
DBUG_RETURN(1);
}
}
else

View file

@ -1570,7 +1570,8 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
if (insert_into_view && !fields.elements)
{
thd->lex->empty_field_list_on_rset= 1;
if (!table_list->table || table_list->is_multitable())
if (!thd->lex->select_lex.leaf_tables.head()->table ||
table_list->is_multitable())
{
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
table_list->view_db.str, table_list->view_name.str);
@ -3855,6 +3856,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
if (sel_res)
sel_res->prepare(lex->returning()->item_list, NULL);
DBUG_ASSERT(select_lex->leaf_tables.elements != 0);
List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
TABLE_LIST *table;
uint insert_tables;

View file

@ -1957,6 +1957,7 @@ JOIN::optimize_inner()
/* Merge all mergeable derived tables/views in this SELECT. */
if (select_lex->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
table_count= select_lex->leaf_tables.elements;
}
if (select_lex->first_cond_optimization &&
@ -1999,6 +2000,8 @@ JOIN::optimize_inner()
eval_select_list_used_tables();
table_count= select_lex->leaf_tables.elements;
if (select_lex->options & OPTION_SCHEMA_TABLE &&
optimize_schema_tables_memory_usage(select_lex->leaf_tables))
DBUG_RETURN(1);
@ -14320,6 +14323,7 @@ void JOIN::cleanup(bool full)
/* Free the original optimized join created for the group_by_handler */
join_tab= original_join_tab;
original_join_tab= 0;
table_count= original_table_count;
}
if (join_tab)

View file

@ -1306,6 +1306,7 @@ public:
Pushdown_query *pushdown_query;
JOIN_TAB *original_join_tab;
uint original_table_count;
/******* Join optimization state members start *******/
/*