summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--mysql-test/r/loaddata.result50
-rw-r--r--mysql-test/r/sp.result33
-rw-r--r--mysql-test/t/loaddata.test45
-rw-r--r--mysql-test/t/sp.test41
-rw-r--r--sql/sql_delete.cc6
-rw-r--r--sql/sql_derived.cc31
-rw-r--r--sql/sql_derived.h1
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_lex.cc16
-rw-r--r--sql/sql_lex.h32
-rw-r--r--sql/sql_load.cc10
-rw-r--r--sql/sql_prepare.cc21
-rw-r--r--sql/sql_union.cc5
-rw-r--r--win/packaging/create_msi.cmake.in5
15 files changed, 240 insertions, 61 deletions
diff --git a/VERSION b/VERSION
index 0924461861a..163137684a2 100644
--- a/VERSION
+++ b/VERSION
@@ -1,3 +1,3 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=0
-MYSQL_VERSION_PATCH=39
+MYSQL_VERSION_PATCH=38
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index f446a503317..977932ced74 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -550,3 +550,53 @@ SELECT HEX(a) FROM t1;
HEX(a)
C3A4
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;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 058ef69c548..7cff6492fad 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -7915,6 +7915,39 @@ CALL sp;
c a b a b
DROP PROCEDURE sp;
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
#
# MDEV-7040: Crash in field_conv, memcpy_field_possible, part#2
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 8f8ff3520a2..de9de4305a3 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -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;
SELECT HEX(a) FROM 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;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 1b765f0eb2d..dc1a244e716 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9373,6 +9373,47 @@ CALL sp;
DROP PROCEDURE sp;
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
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index bbea9815547..46415566bc2 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -40,7 +40,7 @@
#include "sql_statistics.h"
#include "transaction.h"
#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
#include "sql_partition.h" // make_used_partitions_str
@@ -234,9 +234,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list, TRUE, 0))
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);
- 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);
if (!table_list->single_table_updatable())
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 7ad0b4b4c69..b545adf5a2d 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -91,6 +91,7 @@ mysql_handle_derived(LEX *lex, uint phases)
sl= sl->next_select_in_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
subqueries. Views and derived tables of subqueries should be
@@ -201,36 +202,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
@param thd thread handle
diff --git a/sql/sql_derived.h b/sql/sql_derived.h
index 1dffef7235b..301ae31b016 100644
--- a/sql/sql_derived.h
+++ b/sql/sql_derived.h
@@ -22,7 +22,6 @@ struct LEX;
bool mysql_handle_derived(LEX *lex, 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);
/**
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 5ecdd72541f..c10d3517b5e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1383,7 +1383,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
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);
/*
For subqueries in VALUES() we should not see the table in which we are
@@ -1490,7 +1490,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
}
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
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 2fb239ed498..9bc0cf39ac7 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1896,7 +1896,7 @@ void st_select_lex::init_query()
n_child_sum_items= 0;
subquery_in_having= explicit_limit= 0;
is_item_list_lookup= 0;
- first_execution= 1;
+ changed_elements= 0;
first_natural_join_processing= 1;
first_cond_optimization= 1;
parsing_place= NO_MATTER;
@@ -3368,9 +3368,10 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
Item **having_conds)
{
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_ptrs)
@@ -3608,14 +3609,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
bool st_select_lex::handle_derived(LEX *lex, uint phases)
{
- for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first;
- cursor;
- cursor= cursor->next_local)
- {
- if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
- return TRUE;
- }
- return FALSE;
+ return lex->handle_list_of_derived(table_list.first, phases);
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index d58be8b336a..6483aa0e44d 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -667,6 +667,10 @@ public:
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
*/
@@ -822,7 +826,8 @@ public:
subquery. Prepared statements work OK in that regard, as in
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_cond_optimization;
/* do not wrap view fields with Item_ref */
@@ -2772,6 +2777,31 @@ struct LEX: public Query_tables_list
int print_explain(select_result_sink *output, uint8 explain_flags,
bool *printed_anything);
+
+ /*
+ 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;
+ }
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 530f4379530..bdc8880ec68 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -308,8 +308,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
- if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
- mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE))
+ if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
@@ -325,6 +326,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");
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) ||
table_list->prepare_check_option(thd))
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 18f95490a82..5599e419b28 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2535,7 +2535,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
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() */
sl->options&= ~SELECT_DESCRIBE;
@@ -2582,19 +2582,28 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
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)
+ {
order->item= &order->item_ptr;
+ }
/* Fix ORDER list */
for (order= sl->order_list.first; order; order= order->next)
- order->item= &order->item_ptr;
{
+ order->item= &order->item_ptr;
+ }
+ }
+ if (sl->changed_elements & TOUCHED_SEL_DERIVED)
+ {
#ifndef DBUG_OFF
- bool res=
+ bool res=
#endif
- sl->handle_derived(lex, DT_REINIT);
- DBUG_ASSERT(res == 0);
- }
+ sl->handle_derived(lex, DT_REINIT);
+ DBUG_ASSERT(res == 0);
}
+
{
SELECT_LEX_UNIT *unit= sl->master_unit();
unit->unclean();
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 01de3098783..b8bcbd6909d 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -215,8 +215,9 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
called at the first execution of the statement, while first_execution
shows whether this is called at the first execution of the union that
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;
order;
diff --git a/win/packaging/create_msi.cmake.in b/win/packaging/create_msi.cmake.in
index 62ce5f1edd2..db6f57e023d 100644
--- a/win/packaging/create_msi.cmake.in
+++ b/win/packaging/create_msi.cmake.in
@@ -398,9 +398,10 @@ IF("$ENV{EXTRA_LIGHT_ARGS}")
ENDIF()
FILE(REMOVE mysql_server.wixobj extra.wixobj)
+STRING(REPLACE " " ";" EXTRA_WIX_PREPROCESSOR_FLAGS_LIST ${EXTRA_WIX_PREPROCESSOR_FLAGS})
EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE}
- ${EXTRA_WIX_PREPROCESSOR_FLAGS}
+ ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST}
${CANDLE_ARCH}
-ext WixUtilExtension
-ext WixFirewallExtension
@@ -410,7 +411,7 @@ EXECUTE_PROCESS(
EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH}
- ${EXTRA_WIX_PREPROCESSOR_FLAGS}
+ ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST}
-ext WixUtilExtension
-ext WixFirewallExtension
${CMAKE_CURRENT_BINARY_DIR}/extra.wxs