Commit d4885416 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

manual merge from mysql-5.1-bugteam

parents 7e9f53ac 4b2378a1
...@@ -527,3 +527,17 @@ ERROR HY000: You are using safe update mode and you tried to update a table with ...@@ -527,3 +527,17 @@ ERROR HY000: You are using safe update mode and you tried to update a table with
SET SESSION sql_safe_updates = DEFAULT; SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1; DROP TABLE t1;
DROP VIEW v1; DROP VIEW v1;
#
# Bug#54734 assert in Diagnostics_area::set_ok_status
#
DROP TABLE IF EXISTS t1, not_exists;
DROP FUNCTION IF EXISTS f1;
DROP VIEW IF EXISTS v1;
CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk;
CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists);
CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13;
UPDATE v1 SET pk = 7 WHERE pk > 0;
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
...@@ -483,3 +483,23 @@ UPDATE IGNORE v1 SET a = 1; ...@@ -483,3 +483,23 @@ UPDATE IGNORE v1 SET a = 1;
SET SESSION sql_safe_updates = DEFAULT; SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1; DROP TABLE t1;
DROP VIEW v1; DROP VIEW v1;
--echo #
--echo # Bug#54734 assert in Diagnostics_area::set_ok_status
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, not_exists;
DROP FUNCTION IF EXISTS f1;
DROP VIEW IF EXISTS v1;
--enable_warnings
CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk;
CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists);
CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13;
--error ER_VIEW_INVALID
UPDATE v1 SET pk = 7 WHERE pk > 0;
DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
...@@ -511,6 +511,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, ...@@ -511,6 +511,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
volatile THD::killed_state *killed= &thd->killed; volatile THD::killed_state *killed= &thd->killed;
handler *file; handler *file;
MY_BITMAP *save_read_set, *save_write_set; MY_BITMAP *save_read_set, *save_write_set;
bool skip_record;
DBUG_ENTER("find_all_keys"); DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s", DBUG_PRINT("info",("using: %s",
(select ? select->quick ? "ranges" : "where": (select ? select->quick ? "ranges" : "where":
...@@ -603,7 +604,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, ...@@ -603,7 +604,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} }
if (error == 0) if (error == 0)
param->examined_rows++; param->examined_rows++;
if (error == 0 && (!select || select->skip_record() == 0)) if (!error && (!select ||
(!select->skip_record(thd, &skip_record) && !skip_record)))
{ {
if (idx == param->keys) if (idx == param->keys)
{ {
......
...@@ -825,7 +825,11 @@ class SQL_SELECT :public Sql_alloc { ...@@ -825,7 +825,11 @@ class SQL_SELECT :public Sql_alloc {
tmp.set_all(); tmp.set_all();
return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0; return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0;
} }
inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; } inline bool skip_record(THD *thd, bool *skip_record)
{
*skip_record= cond ? cond->val_int() == FALSE : FALSE;
return thd->is_error();
}
int test_quick_select(THD *thd, key_map keys, table_map prev_tables, int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
ha_rows limit, bool force_quick_range); ha_rows limit, bool force_quick_range);
}; };
......
...@@ -59,6 +59,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -59,6 +59,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool const_cond_result; bool const_cond_result;
ha_rows deleted= 0; ha_rows deleted= 0;
bool reverse= FALSE; bool reverse= FALSE;
bool skip_record;
ORDER *order= (ORDER *) ((order_list && order_list->elements) ? ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
order_list->first : NULL); order_list->first : NULL);
uint usable_index= MAX_KEY; uint usable_index= MAX_KEY;
...@@ -298,7 +299,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -298,7 +299,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{ {
thd->examined_row_count++; thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error // thd->is_error() is tested to disallow delete row on error
if (!(select && select->skip_record())&& ! thd->is_error() ) if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
{ {
if (table->triggers && if (table->triggers &&
......
...@@ -11941,37 +11941,29 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last) ...@@ -11941,37 +11941,29 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
SQL_SELECT *select=join_tab->select; SQL_SELECT *select=join_tab->select;
if (rc == NESTED_LOOP_OK) if (rc == NESTED_LOOP_OK)
{ {
bool consider_record= !join_tab->cache.select || bool skip_record= FALSE;
!join_tab->cache.select->skip_record(); if (join_tab->cache.select &&
join_tab->cache.select->skip_record(join->thd, &skip_record))
/*
Check for error: skip_record() can execute code by calling
Item_subselect::val_*. We need to check for errors (if any)
after such call.
*/
if (join->thd->is_error())
{ {
reset_cache_write(&join_tab->cache); reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR; return NESTED_LOOP_ERROR;
} }
if (consider_record) if (!skip_record)
{ {
uint i; uint i;
reset_cache_read(&join_tab->cache); reset_cache_read(&join_tab->cache);
for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;) for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
{ {
read_cached_record(join_tab); read_cached_record(join_tab);
if (!select || !select->skip_record()) skip_record= FALSE;
if (select && select->skip_record(join->thd, &skip_record))
{
reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
}
if (!skip_record)
{ {
/*
Check for error: skip_record() can execute code by calling
Item_subselect::val_*. We need to check for errors (if any)
after such call.
*/
if (join->thd->is_error())
rc= NESTED_LOOP_ERROR;
else
rc= (join_tab->next_select)(join,join_tab+1,0); rc= (join_tab->next_select)(join,join_tab+1,0);
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{ {
......
...@@ -477,7 +477,14 @@ int mysql_update(THD *thd, ...@@ -477,7 +477,14 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
thd->examined_row_count++; thd->examined_row_count++;
if (!(select && select->skip_record())) bool skip_record= FALSE;
if (select && select->skip_record(thd, &skip_record))
{
error= 1;
table->file->unlock_row();
break;
}
if (!skip_record)
{ {
if (table->file->was_semi_consistent_read()) if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */ continue; /* repeat the read of the same row if it still exists */
...@@ -584,7 +591,8 @@ int mysql_update(THD *thd, ...@@ -584,7 +591,8 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
thd->examined_row_count++; thd->examined_row_count++;
if (!(select && select->skip_record())) bool skip_record;
if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
{ {
if (table->file->was_semi_consistent_read()) if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */ continue; /* repeat the read of the same row if it still exists */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment