summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/sql_acl.cc7
-rw-r--r--sql/sql_base.cc19
-rw-r--r--sql/sql_handler.cc17
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_table.cc35
-rw-r--r--sql/sql_update.cc37
-rw-r--r--sql/sql_yacc.yy2
13 files changed, 89 insertions, 50 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 5b6484f5017..8ff479df098 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1166,8 +1166,8 @@ Item_func_nullif::val_str(String *str)
bool
Item_func_nullif::is_null()
{
- if (!(this->*cmp_func)())
- return null_value=1;
+ if (!cmp.compare())
+ return (null_value=1);
return 0;
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0bddeed14d6..c7cd9d26974 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2736,6 +2736,8 @@ void Item_func_get_user_var::fix_length_and_dec()
case STRING_RESULT:
max_length= MAX_BLOB_WIDTH;
break;
+ case ROW_RESULT: // Keep compiler happy
+ break;
}
}
else
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 8a81c0690b8..538590e6197 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -729,6 +729,7 @@ void wait_for_refresh(THD *thd);
int open_tables(THD *thd, TABLE_LIST *tables, uint *counter);
int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
int open_and_lock_tables(THD *thd,TABLE_LIST *tables);
+void relink_tables_for_derived(THD *thd);
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
const char *table_name, bool link_in_list);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b9fc5477449..b173a62efbb 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2118,7 +2118,7 @@ static void check_data_home(const char *path)
/* ARGSUSED */
-! extern "C" int my_message_sql(uint error, const char *str, myf MyFlags)
+extern "C" int my_message_sql(uint error, const char *str, myf MyFlags)
{
THD *thd;
DBUG_ENTER("my_message_sql");
@@ -2132,7 +2132,11 @@ static void check_data_home(const char *path)
if (thd->lex->current_select &&
thd->lex->current_select->no_error && !thd->is_fatal_error)
{
- DBUG_PRINT("error", ("above error converted to warning"));
+ DBUG_PRINT("error", ("Error converted to warning: current_select: no_error %d fatal_error: %d",
+ (thd->lex->current_select ?
+ thd->lex->current_select->no_error : 0),
+ (int) thd->is_fatal_error));
+
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
}
else
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index a5284a543e6..fc252c1f5ac 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2699,10 +2699,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
{
TABLE_LIST *table;
char *user = thd->priv_user;
+ DBUG_ENTER("check_grant");
want_access &= ~thd->master_access;
if (!want_access)
- return 0; // ok
+ DBUG_RETURN(0); // ok
rw_rdlock(&LOCK_grant);
for (table= tables; table && number--; table= table->next)
@@ -2739,7 +2740,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
}
rw_unlock(&LOCK_grant);
- return 0;
+ DBUG_RETURN(0);
err:
rw_unlock(&LOCK_grant);
@@ -2770,7 +2771,7 @@ err:
thd->host_or_ip,
table ? table->real_name : "unknown");
}
- return 1;
+ DBUG_RETURN(1);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a91371b4248..3c25d01ced0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1695,10 +1695,18 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
uint counter;
if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
DBUG_RETURN(-1); /* purecov: inspected */
- /*
- Let us propagate pointers to open tables from global table list
- to table lists in particular selects if needed.
- */
+ relink_tables_for_derived(thd);
+ DBUG_RETURN(mysql_handle_derived(thd->lex));
+}
+
+
+/*
+ Let us propagate pointers to open tables from global table list
+ to table lists in particular selects if needed.
+*/
+
+void relink_tables_for_derived(THD *thd)
+{
if (thd->lex->all_selects_list->next_select_in_list() ||
thd->lex->time_zone_tables_used)
{
@@ -1711,7 +1719,6 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
if (cursor->table_list)
cursor->table= cursor->table_list->table;
}
- DBUG_RETURN(mysql_handle_derived(thd->lex));
}
@@ -1751,7 +1758,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
if (!table->derived)
*(ptr++)= table->table;
}
- if (!(thd->lock=mysql_lock_tables(thd,start,count)))
+ if (!(thd->lock=mysql_lock_tables(thd,start, (uint) (ptr - start))))
return -1; /* purecov: inspected */
}
else
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 1e50e1e571e..33537d1080a 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -159,7 +159,8 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
/*
HASH entries are of type TABLE_LIST.
*/
- if (hash_init(&thd->handler_tables_hash, HANDLER_TABLES_HASH_SIZE, 0, 0,
+ if (hash_init(&thd->handler_tables_hash, &my_charset_latin1,
+ HANDLER_TABLES_HASH_SIZE, 0, 0,
(hash_get_key) mysql_ha_hash_get_key,
(hash_free_key) mysql_ha_hash_free, 0))
goto err;
@@ -223,7 +224,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
memcpy(hash_tables->alias, tables->alias, aliaslen);
/* add to hash */
- if (hash_insert(&thd->handler_tables_hash, (byte*) hash_tables))
+ if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables))
{
mysql_ha_close(thd, tables);
goto err;
@@ -293,7 +294,7 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
if (*table_ptr)
{
- table_ptr->file->ha_index_or_rnd_end();
+ (*table_ptr)->file->ha_index_or_rnd_end();
VOID(pthread_mutex_lock(&LOCK_open));
if (close_thread_table(thd, table_ptr))
{
@@ -582,7 +583,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
ok:
mysql_unlock_tables(thd,lock);
- send_eof(&thd->net);
+ send_eof(thd);
DBUG_PRINT("exit",("mysql_ha_read: OK"));
DBUG_RETURN(0);
err:
@@ -645,8 +646,10 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, int mode_flags)
while (*table_ptr)
{
if ((! *tmp_tables->db ||
- ! my_strcasecmp((*table_ptr)->table_cache_key, tmp_tables->db)) &&
- ! my_strcasecmp((*table_ptr)->real_name, tmp_tables->real_name))
+ ! my_strcasecmp(&my_charset_latin1, (*table_ptr)->table_cache_key,
+ tmp_tables->db)) &&
+ ! my_strcasecmp(&my_charset_latin1, (*table_ptr)->real_name,
+ tmp_tables->real_name))
{
DBUG_PRINT("info",("mysql_ha_flush: *table_ptr '%s'.'%s' as '%s'",
(*table_ptr)->table_cache_key,
@@ -725,7 +728,7 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, int mode_flags)
}
}
- table_ptr->file->ha_index_or_rnd_end();
+ (*table_ptr)->file->ha_index_or_rnd_end();
if (close_thread_table(thd, table_ptr))
{
/* Tell threads waiting for refresh that something has happened */
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index dffe7bcb2b0..d198855a2d3 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -599,7 +599,7 @@ typedef struct st_lex
USER_RESOURCES mqh;
ulong thread_id,type;
enum_sql_command sql_command;
- thr_lock_type lock_option;
+ thr_lock_type lock_option, multi_lock_option;
enum SSL_type ssl_type; /* defined in violite.h */
enum my_lex_states next_state;
enum enum_duplicates duplicates;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 156c20edc0c..7a389a906c0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7188,7 +7188,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (keys.is_set(nr))
{
int flag;
- if (flag=test_if_order_by_key(order, table, nr, &not_used))
+ if ((flag= test_if_order_by_key(order, table, nr, &not_used)))
{
if (!no_changes)
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 44bc2a9efc9..c5cd2860e03 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5cb328f530b..6305da85d30 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2265,31 +2265,32 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
&handler::check));
}
+
/* table_list should contain just one table */
-int mysql_discard_or_import_tablespace(THD *thd,
- TABLE_LIST *table_list,
- enum tablespace_op_type tablespace_op)
+static int
+mysql_discard_or_import_tablespace(THD *thd,
+ TABLE_LIST *table_list,
+ enum tablespace_op_type tablespace_op)
{
TABLE *table;
my_bool discard;
int error;
DBUG_ENTER("mysql_discard_or_import_tablespace");
- /* Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
- ALTER TABLE */
+ /*
+ Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
+ ALTER TABLE
+ */
thd->proc_info="discard_or_import_tablespace";
- if (tablespace_op == DISCARD_TABLESPACE)
- discard = TRUE;
- else
- discard = FALSE;
-
- thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open
- and ::external_lock() do not complain when we
- lock the table */
- mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
+ discard= test(tablespace_op == DISCARD_TABLESPACE);
+ /*
+ We set this flag so that ha_innobase::open and ::external_lock() do
+ not complain when we lock the table
+ */
+ thd->tablespace_op= TRUE;
if (!(table=open_ltable(thd,table_list,TL_WRITE)))
{
thd->tablespace_op=FALSE;
@@ -2303,8 +2304,10 @@ int mysql_discard_or_import_tablespace(THD *thd,
if (error)
goto err;
- /* The 0 in the call below means 'not in a transaction', which means
- immediate invalidation; that is probably what we wish here */
+ /*
+ The 0 in the call below means 'not in a transaction', which means
+ immediate invalidation; that is probably what we wish here
+ */
query_cache_invalidate3(thd, table_list, 0);
/* The ALTER TABLE is always in its own transaction */
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 25d94d6d039..d3597f274dc 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -303,6 +303,7 @@ int mysql_update(THD *thd,
else if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
{
+ thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0));
error= 1;
break;
@@ -484,6 +485,8 @@ int mysql_multi_update(THD *thd,
TABLE_LIST *tl;
TABLE_LIST *update_list= (TABLE_LIST*) thd->lex->select_lex.table_list.first;
List<Item> total_list;
+ const bool using_lock_tables= thd->locked_tables != 0;
+ bool initialized_dervied= 0;
DBUG_ENTER("mysql_multi_update");
select_lex->select_limit= HA_POS_ERROR;
@@ -495,15 +498,24 @@ int mysql_multi_update(THD *thd,
for (;;)
{
table_map update_tables, derived_tables=0;
- uint tnr, counter;
+ uint tnr, table_count;
- if ((res=open_tables(thd,table_list, &counter)))
+ if ((res=open_tables(thd, table_list, &table_count)))
DBUG_RETURN(res);
/* Only need to call lock_tables if we are not using LOCK TABLES */
- if (!using_lock_tables && ((res= lock_tables(thd, table_list))))
+ if (!using_lock_tables &&
+ ((res= lock_tables(thd, table_list, table_count))))
DBUG_RETURN(res);
+ if (!initialized_dervied)
+ {
+ initialized_dervied= 1;
+ relink_tables_for_derived(thd);
+ if ((res= mysql_handle_derived(thd->lex)))
+ DBUG_RETURN(res);
+ }
+
/*
Ensure that we have update privilege for all tables and columns in the
SET part
@@ -558,7 +570,7 @@ int mysql_multi_update(THD *thd,
DBUG_RETURN(-1);
}
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
- tl->lock_type= thd->lex.lock_option;
+ tl->lock_type= thd->lex->multi_lock_option;
tl->updating= 1;
}
else
@@ -569,6 +581,8 @@ int mysql_multi_update(THD *thd,
}
if (tl->derived)
derived_tables|= table->map;
+ else if (!using_lock_tables)
+ tl->table->reginfo.lock_type= tl->lock_type;
}
if (thd->lex->derived_tables && (update_tables & derived_tables))
@@ -586,7 +600,7 @@ int mysql_multi_update(THD *thd,
}
/* Relock the tables with the correct modes */
- res= lock_tables(thd,table_list);
+ res= lock_tables(thd, table_list, table_count);
if (using_lock_tables)
{
if (res)
@@ -608,7 +622,7 @@ int mysql_multi_update(THD *thd,
item->cleanup();
}
}
- if (setup_fields(thd, table_list, *fields, 1, 0, 0))
+ if (setup_fields(thd, 0, update_list, *fields, 1, 0, 0))
DBUG_RETURN(-1);
/*
If lock succeded and the table map didn't change since the above lock
@@ -624,9 +638,7 @@ int mysql_multi_update(THD *thd,
close_thread_tables(thd);
}
- /*
- Setup timestamp handling
- */
+ /* Setup timestamp handling */
for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
@@ -634,6 +646,9 @@ int mysql_multi_update(THD *thd,
if (table->timestamp_field &&
table->timestamp_field->query_id == thd->query_id)
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
+ /* We only need SELECT privilege for columns in the values list */
+ table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
}
if (!(result=new multi_update(thd, update_list, fields, values,
@@ -994,6 +1009,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
{
+ thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
}
@@ -1149,7 +1165,10 @@ int multi_update::do_updates(bool from_send_error)
err:
if (!from_send_error)
+ {
+ thd->fatal_error();
table->file->print_error(local_error,MYF(0));
+ }
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 7982b501ac4..7cf24d3972d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4169,7 +4169,7 @@ update:
if (lex->select_lex.table_list.elements > 1)
{
lex->sql_command= SQLCOM_UPDATE_MULTI;
- lex->lock_option= $3;
+ lex->multi_lock_option= $3;
}
else if (lex->select_lex.get_table_list()->derived)
{