Merge branch '10.0' into 10.1

This commit is contained in:
Oleksandr Byelkin 2019-03-01 15:52:06 +01:00
commit f2e1451740
14 changed files with 240 additions and 61 deletions

View File

@ -574,3 +574,53 @@ SELECT HEX(a) FROM t1;
HEX(a) HEX(a)
C3A4 C3A4
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-15744: Assertion `derived->table' failed in mysql_derived_merge_for_insert
#
create table t1 (a int, b int);
CREATE OR REPLACE VIEW t2 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
select * from v2;
a b
2 2
3 3
4 4
5 5
6 6
select * from t2;
a b
2 2
3 3
4 4
5 5
6 6
DROP VIEW IF EXISTS v2,t2;
DROP TABLE IF EXISTS t1;
#
# MDEV-15950: LOAD DATA INTO compex_view crashed
#
create table t1 (a int, b int);
create table t0 (x int, y int);
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1,t0;
CREATE VIEW v2 AS SELECT * FROM v1;
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v1
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
DROP VIEW IF EXISTS v2,v1;
DROP TABLE IF EXISTS t1,t0;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), UNIQUE(b));
INSERT INTO t1 VALUES (1,1);
CREATE TABLE t2 (c INT);
CREATE VIEW v AS SELECT t1.* FROM t1 JOIN t2;
SELECT a, b FROM t1 INTO OUTFILE '15645.data';
LOAD DATA INFILE '15645.data' IGNORE INTO TABLE v (a,b);
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
LOAD DATA INFILE '15645.data' REPLACE INTO TABLE v (a,b);
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
drop table t1,t2;
drop view v;

View File

@ -7918,6 +7918,39 @@ CALL sp;
c a b a b c a b a b
DROP PROCEDURE sp; DROP PROCEDURE sp;
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-17055: Server crashes in find_order_in_list upon
# 2nd (3rd) execution of SP with UPDATE
#
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (c INT);
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 ORDER BY a, b LIMIT 1;
LOCK TABLE t2 READ;
CALL sp;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
DROP PROCEDURE sp;
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 WHERE a=1 and b=2;
LOCK TABLE t2 READ;
CALL sp;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
DROP PROCEDURE sp;
DROP VIEW v1;
DROP TABLE t1, t2;
# End of 5.5 test # End of 5.5 test
# #
# MDEV-7040: Crash in field_conv, memcpy_field_possible, part#2 # MDEV-7040: Crash in field_conv, memcpy_field_possible, part#2

View File

@ -676,3 +676,48 @@ CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
LOAD DATA INFILE '../../std_data/loaddata/mdev-11631.txt' INTO TABLE t1 CHARACTER SET utf8; LOAD DATA INFILE '../../std_data/loaddata/mdev-11631.txt' INTO TABLE t1 CHARACTER SET utf8;
SELECT HEX(a) FROM t1; SELECT HEX(a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-15744: Assertion `derived->table' failed in mysql_derived_merge_for_insert
--echo #
create table t1 (a int, b int);
CREATE OR REPLACE VIEW t2 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
select * from v2;
select * from t2;
DROP VIEW IF EXISTS v2,t2;
DROP TABLE IF EXISTS t1;
--echo #
--echo # MDEV-15950: LOAD DATA INTO compex_view crashed
--echo #
create table t1 (a int, b int);
create table t0 (x int, y int);
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1,t0;
CREATE VIEW v2 AS SELECT * FROM v1;
--error ER_WRONG_USAGE
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v1
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
--error ER_WRONG_USAGE
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
DROP VIEW IF EXISTS v2,v1;
DROP TABLE IF EXISTS t1,t0;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), UNIQUE(b));
INSERT INTO t1 VALUES (1,1);
CREATE TABLE t2 (c INT);
CREATE VIEW v AS SELECT t1.* FROM t1 JOIN t2;
SELECT a, b FROM t1 INTO OUTFILE '15645.data';
--error ER_WRONG_USAGE
LOAD DATA INFILE '15645.data' IGNORE INTO TABLE v (a,b);
--error ER_WRONG_USAGE
LOAD DATA INFILE '15645.data' REPLACE INTO TABLE v (a,b);
drop table t1,t2;
drop view v;

View File

@ -9369,6 +9369,47 @@ CALL sp;
DROP PROCEDURE sp; DROP PROCEDURE sp;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-17055: Server crashes in find_order_in_list upon
--echo # 2nd (3rd) execution of SP with UPDATE
--echo #
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (c INT);
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 ORDER BY a, b LIMIT 1;
LOCK TABLE t2 READ;
--error ER_TABLE_NOT_LOCKED
CALL sp;
UNLOCK TABLES;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
# Cleanup
DROP PROCEDURE sp;
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 WHERE a=1 and b=2;
LOCK TABLE t2 READ;
--error ER_TABLE_NOT_LOCKED
CALL sp;
UNLOCK TABLES;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
# Cleanup
DROP PROCEDURE sp;
DROP VIEW v1;
DROP TABLE t1, t2;
--echo # End of 5.5 test --echo # End of 5.5 test

View File

@ -39,7 +39,7 @@
#include "sql_statistics.h" #include "sql_statistics.h"
#include "transaction.h" #include "transaction.h"
#include "records.h" // init_read_record, #include "records.h" // init_read_record,
#include "sql_derived.h" // mysql_handle_list_of_derived #include "sql_derived.h" // mysql_handle_derived
// end_read_record // end_read_record
#include "sql_partition.h" // make_used_partitions_str #include "sql_partition.h" // make_used_partitions_str
@ -248,9 +248,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list, TRUE, 0)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT)) if (thd->lex->handle_list_of_derived(table_list, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!table_list->single_table_updatable()) if (!table_list->single_table_updatable())

View File

@ -91,6 +91,7 @@ mysql_handle_derived(LEX *lex, uint phases)
sl= sl->next_select_in_list()) sl= sl->next_select_in_list())
{ {
TABLE_LIST *cursor= sl->get_table_list(); TABLE_LIST *cursor= sl->get_table_list();
sl->changed_elements|= TOUCHED_SEL_DERIVED;
/* /*
DT_MERGE_FOR_INSERT is not needed for views/derived tables inside DT_MERGE_FOR_INSERT is not needed for views/derived tables inside
subqueries. Views and derived tables of subqueries should be subqueries. Views and derived tables of subqueries should be
@ -200,36 +201,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
} }
/**
Run specified phases for derived tables/views in the given list
@param lex LEX for this thread
@param table_list list of derived tables/view to handle
@param phase_map phases to process tables/views through
@details
This function runs phases specified by the 'phases_map' on derived
tables/views found in the 'dt_list' with help of the
TABLE_LIST::handle_derived function.
'lex' is passed as an argument to the TABLE_LIST::handle_derived.
@return FALSE ok
@return TRUE error
*/
bool
mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *table_list, uint phases)
{
for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local)
{
if (tl->is_view_or_derived() &&
tl->handle_derived(lex, phases))
return TRUE;
}
return FALSE;
}
/** /**
Merge a derived table/view into the embedding select Merge a derived table/view into the embedding select

View File

@ -22,7 +22,6 @@ struct LEX;
bool mysql_handle_derived(LEX *lex, uint phases); bool mysql_handle_derived(LEX *lex, uint phases);
bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases); bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases);
bool mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *dt_list, uint phases);
bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived); bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived);
/** /**

View File

@ -1461,7 +1461,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT)) if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/* /*
For subqueries in VALUES() we should not see the table in which we are For subqueries in VALUES() we should not see the table in which we are
@ -1557,7 +1557,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds); select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
select_lex->first_execution= 0;
} }
/* /*
Only call prepare_for_posistion() if we are not performing a DELAYED Only call prepare_for_posistion() if we are not performing a DELAYED

View File

@ -2127,7 +2127,7 @@ void st_select_lex::init_query()
n_child_sum_items= 0; n_child_sum_items= 0;
subquery_in_having= explicit_limit= 0; subquery_in_having= explicit_limit= 0;
is_item_list_lookup= 0; is_item_list_lookup= 0;
first_execution= 1; changed_elements= 0;
first_natural_join_processing= 1; first_natural_join_processing= 1;
first_cond_optimization= 1; first_cond_optimization= 1;
parsing_place= NO_MATTER; parsing_place= NO_MATTER;
@ -3597,9 +3597,10 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
Item **having_conds) Item **having_conds)
{ {
DBUG_ENTER("st_select_lex::fix_prepare_information"); DBUG_ENTER("st_select_lex::fix_prepare_information");
if (!thd->stmt_arena->is_conventional() && first_execution) if (!thd->stmt_arena->is_conventional() &&
!(changed_elements & TOUCHED_SEL_COND))
{ {
first_execution= 0; changed_elements|= TOUCHED_SEL_COND;
if (group_list.first) if (group_list.first)
{ {
if (!group_list_ptrs) if (!group_list_ptrs)
@ -3850,14 +3851,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
bool st_select_lex::handle_derived(LEX *lex, uint phases) bool st_select_lex::handle_derived(LEX *lex, uint phases)
{ {
for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first; return lex->handle_list_of_derived(table_list.first, phases);
cursor;
cursor= cursor->next_local)
{
if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
return TRUE;
}
return FALSE;
} }

View File

@ -714,6 +714,10 @@ public:
typedef class st_select_lex_unit SELECT_LEX_UNIT; typedef class st_select_lex_unit SELECT_LEX_UNIT;
#define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */
#define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */
/* /*
SELECT_LEX - store information of parsed SELECT statment SELECT_LEX - store information of parsed SELECT statment
*/ */
@ -875,7 +879,8 @@ public:
subquery. Prepared statements work OK in that regard, as in subquery. Prepared statements work OK in that regard, as in
case of an error during prepare the PS is not created. case of an error during prepare the PS is not created.
*/ */
bool first_execution; uint8 changed_elements; // see TOUCHED_SEL_*
/* TODO: add foloowing first_* to bitmap above */
bool first_natural_join_processing; bool first_natural_join_processing;
bool first_cond_optimization; bool first_cond_optimization;
/* do not wrap view fields with Item_ref */ /* do not wrap view fields with Item_ref */
@ -2998,6 +3003,31 @@ public:
*/ */
bool tmp_table() const { return create_info.tmp_table(); } bool tmp_table() const { return create_info.tmp_table(); }
bool if_exists() const { return create_info.if_exists(); } bool if_exists() const { return create_info.if_exists(); }
/*
Run specified phases for derived tables/views in the given list
@param table_list - list of derived tables/view to handle
@param phase - phases to process tables/views through
@details
This method runs phases specified by the 'phases' on derived
tables/views found in the 'table_list' with help of the
TABLE_LIST::handle_derived function.
'this' is passed as an argument to the TABLE_LIST::handle_derived.
@return false - ok
@return true - error
*/
bool handle_list_of_derived(TABLE_LIST *table_list, uint phases)
{
for (TABLE_LIST *tl= table_list; tl; tl= tl->next_local)
{
if (tl->is_view_or_derived() && tl->handle_derived(this, phases))
return true;
}
return false;
}
}; };

View File

@ -293,8 +293,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list, TRUE, 0)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) || if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE)) DBUG_RETURN(TRUE);
if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list, &thd->lex->select_lex.top_join_list,
@ -310,6 +311,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
if (table_list->is_multitable())
{
my_error(ER_WRONG_USAGE, MYF(0), "Multi-table VIEW", "LOAD");
DBUG_RETURN(TRUE);
}
if (table_list->prepare_where(thd, 0, TRUE) || if (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd)) table_list->prepare_check_option(thd))
{ {

View File

@ -2794,7 +2794,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
} }
for (; sl; sl= sl->next_select_in_list()) for (; sl; sl= sl->next_select_in_list())
{ {
if (!sl->first_execution) if (sl->changed_elements & TOUCHED_SEL_COND)
{ {
/* remove option which was put by mysql_explain_union() */ /* remove option which was put by mysql_explain_union() */
sl->options&= ~SELECT_DESCRIBE; sl->options&= ~SELECT_DESCRIBE;
@ -2841,19 +2841,28 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
order->next= sl->group_list_ptrs->at(ix+1); order->next= sl->group_list_ptrs->at(ix+1);
} }
} }
}
{ // no harm to do it (item_ptr set on parsing)
ORDER *order;
for (order= sl->group_list.first; order; order= order->next) for (order= sl->group_list.first; order; order= order->next)
{
order->item= &order->item_ptr; order->item= &order->item_ptr;
}
/* Fix ORDER list */ /* Fix ORDER list */
for (order= sl->order_list.first; order; order= order->next) for (order= sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
{ {
#ifndef DBUG_OFF order->item= &order->item_ptr;
bool res=
#endif
sl->handle_derived(lex, DT_REINIT);
DBUG_ASSERT(res == 0);
} }
} }
if (sl->changed_elements & TOUCHED_SEL_DERIVED)
{
#ifndef DBUG_OFF
bool res=
#endif
sl->handle_derived(lex, DT_REINIT);
DBUG_ASSERT(res == 0);
}
{ {
SELECT_LEX_UNIT *unit= sl->master_unit(); SELECT_LEX_UNIT *unit= sl->master_unit();
unit->unclean(); unit->unclean();

View File

@ -313,8 +313,9 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
called at the first execution of the statement, while first_execution called at the first execution of the statement, while first_execution
shows whether this is called at the first execution of the union that shows whether this is called at the first execution of the union that
may form just a subselect. may form just a subselect.
*/ */
if (!fake_select_lex->first_execution && first_execution) if ((fake_select_lex->changed_elements & TOUCHED_SEL_COND) &&
first_execution)
{ {
for (ORDER *order= global_parameters()->order_list.first; for (ORDER *order= global_parameters()->order_list.first;
order; order;

View File

@ -398,9 +398,10 @@ IF("$ENV{EXTRA_LIGHT_ARGS}")
ENDIF() ENDIF()
FILE(REMOVE mysql_server.wixobj extra.wixobj) FILE(REMOVE mysql_server.wixobj extra.wixobj)
STRING(REPLACE " " ";" EXTRA_WIX_PREPROCESSOR_FLAGS_LIST ${EXTRA_WIX_PREPROCESSOR_FLAGS})
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE} COMMAND ${CANDLE_EXECUTABLE}
${EXTRA_WIX_PREPROCESSOR_FLAGS} ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST}
${CANDLE_ARCH} ${CANDLE_ARCH}
-ext WixUtilExtension -ext WixUtilExtension
-ext WixFirewallExtension -ext WixFirewallExtension
@ -410,7 +411,7 @@ EXECUTE_PROCESS(
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH} COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH}
${EXTRA_WIX_PREPROCESSOR_FLAGS} ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST}
-ext WixUtilExtension -ext WixUtilExtension
-ext WixFirewallExtension -ext WixFirewallExtension
${CMAKE_CURRENT_BINARY_DIR}/extra.wxs ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs