summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-12-31 00:44:00 +0200
committerunknown <monty@mysql.com>2004-12-31 00:44:00 +0200
commit2e8d13c73ec986dde580c9c840f421af4279611a (patch)
tree77b085cd22eae45e57f4e20f35ecfc231153d656 /sql
parentbb2d3eaa30a3881927142c985fb637aca06d9823 (diff)
downloadmariadb-git-2e8d13c73ec986dde580c9c840f421af4279611a.tar.gz
After merge fixes
config/ac-macros/character_sets.m4: Added latin1_spanish_ci dbug/dbug_analyze.c: Remove compiler warnings include/my_handler.h: Reorder structure arguments to be more optimal innobase/dict/dict0load.c: Fixed wrong define tag (for MySQL 5.0) innobase/fil/fil0fil.c: Fixed compiler warning innobase/os/os0file.c: Fixed compiler warning myisam/ft_boolean_search.c: Fixed compiler warning myisam/ft_static.c: Update to use new HA_KEYSEG structure myisam/mi_open.c: Simple optimization myisammrg/myrg_static.c: Removed compiler warning mysql-test/r/grant.result: Update results after merge mysql-test/r/index_merge.result: Update results after merge mysql-test/r/information_schema_inno.result: Add missing drop table mysql-test/r/lowercase_table.result: safety fix mysql-test/r/multi_update.result: safety fix mysql-test/r/ps_1general.result: safety fix mysql-test/r/ps_2myisam.result: Update results after merge (set is not anymore of binary type) mysql-test/r/ps_3innodb.result: Update results after merge mysql-test/r/ps_4heap.result: Update results after merge mysql-test/r/ps_5merge.result: Update results after merge mysql-test/r/ps_6bdb.result: Update results after merge mysql-test/r/show_check.result: Update results after merge mysql-test/r/subselect.result: Update results after merge (added missing quotes) mysql-test/r/timezone2.result: Update results after merge mysql-test/r/view.result: Update results after merge (note that INSERT IGNORE will work again after next merge from 4.1) mysql-test/t/derived.test: Removed empty line mysql-test/t/grant.test: Update results after merge mysql-test/t/information_schema_inno.test: added missing drop table mysql-test/t/lowercase_table.test: safety fix mysql-test/t/multi_update.test: safety fix mysql-test/t/ps_1general.test: safety fix mysql-test/t/view.test: update error codes after merge ndb/src/mgmsrv/main.cpp: after merge fix ndb/tools/ndb_test_platform.cpp: removed compiler warnings regex/main.c: remove compiler warnings sql/field.cc: Remove compiler warning sql/gen_lex_hash.cc: Added DBUG support sql/ha_myisam.cc: Removed warning from valgrind sql/ha_ndbcluster.cc: Remove compiler warning sql/item_cmpfunc.cc: Better to use val_int() instead of val_real() as we don't want Item_func_nop_all to return different value than the original ref element sql/mysqld.cc: Remove compiler warning sql/sql_acl.cc: More debugging sql/sql_lex.cc: Remove unnecessary 'else' sql/sql_parse.cc: After merge fixes Simplify reset of thd->server_status for SQLCOM_CALL sql/sql_prepare.cc: After merge fixes Removed possible core dump in mysql_stmt_fetch() sql/sql_update.cc: After merge fixes (together with Sanja) strings/ctype-czech.c: Remove compiler warning strings/ctype-ucs2.c: Remove compiler warning strings/ctype-win1250ch.c: Remove compiler warning strings/xml.c: Remove compiler warning tests/client_test.c: Fix test to work with 5.0 vio/test-sslserver.c: Portability fix
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc7
-rw-r--r--sql/gen_lex_hash.cc24
-rw-r--r--sql/ha_myisam.cc5
-rw-r--r--sql/ha_ndbcluster.cc1
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/sp.cc1
-rw-r--r--sql/sp_head.cc1
-rw-r--r--sql/sql_acl.cc16
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_insert.cc43
-rw-r--r--sql/sql_lex.cc11
-rw-r--r--sql/sql_parse.cc40
-rw-r--r--sql/sql_prepare.cc20
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_update.cc66
-rw-r--r--sql/sql_view.cc1
-rw-r--r--sql/sql_yacc.yy4
-rw-r--r--sql/table.cc1
23 files changed, 142 insertions, 130 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 0f1faccfe42..a270f102cd5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -342,9 +342,10 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_flag)
longlong value= val_int();
if (val_buffer->alloc(length))
return 0;
- length= (uint) cs->cset->longlong10_to_str(cs, (char*) val_buffer->ptr(),
- length, unsigned_flag ? 10 : -10,
- value);
+ length= (uint) (*cs->cset->longlong10_to_str)(cs, (char*) val_buffer->ptr(),
+ length,
+ unsigned_flag ? 10 : -10,
+ value);
val_buffer->length(length);
return val_buffer;
}
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 0bbdf84c8d6..57b5e006489 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -83,8 +83,17 @@ TODO:
#include "mysql_version.h"
#include "lex.h"
+const char *default_dbug_option="d:t:o,/tmp/gen_lex_hash.trace";
+
struct my_option my_long_options[] =
{
+#ifdef DBUG_OFF
+ {"debug", '#', "This is a non-debug version. Catch this and exit",
+ 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#else
+ {"debug", '#', "Output debug log", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"help", '?', "Display help and exit",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit",
@@ -108,7 +117,7 @@ hash_lex_struct *get_hash_struct_by_len(hash_lex_struct **root_by_len,
{
if (*max_len<len){
*root_by_len= (hash_lex_struct *)realloc((char*)*root_by_len,
- sizeof(hash_lex_struct)*len);
+ sizeof(hash_lex_struct)*len);
hash_lex_struct *cur, *end= *root_by_len + len;
for (cur= *root_by_len + *max_len; cur<end; cur++)
cur->first_char= 0;
@@ -353,6 +362,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '?':
usage(0);
exit(0);
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ break;
}
return 0;
}
@@ -425,11 +437,12 @@ int check_duplicates()
int main(int argc,char **argv)
{
MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
if (get_options(argc,(char **) argv))
exit(1);
- printf("/* Copyright (C) 2001 MySQL AB\n\
+ printf("/* Copyright (C) 2001-2004 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n\
\n*/\n\n");
@@ -449,9 +462,8 @@ int main(int argc,char **argv)
printf("\nunsigned int sql_functions_max_len=%d;\n",max_len);
printf("\nunsigned int symbols_max_len=%d;\n\n",max_len2);
- printf
-(
-"inline SYMBOL *get_hash_symbol(const char *s,\n\
+ printf("\
+inline SYMBOL *get_hash_symbol(const char *s,\n \
unsigned int len,bool function)\n\
{\n\
register uchar *hash_map;\n\
@@ -516,5 +528,7 @@ int main(int argc,char **argv)
}\n\
}\n"
);
+ my_end(0);
+ exit(0);
}
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index c23a728b715..c89eb4426ff 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -1410,8 +1410,9 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
keydef[i].seg[j].start= pos->key_part[j].offset;
keydef[i].seg[j].length= pos->key_part[j].length;
keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end=
- keydef[i].seg[j].bit_pos= 0;
- keydef[i].seg[j].language = field->charset()->number;
+ keydef[i].seg[j].bit_length= 0;
+ keydef[i].seg[j].bit_pos= 0;
+ keydef[i].seg[j].language= field->charset()->number;
if (field->null_ptr)
{
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 7320665dc49..2d2bd12f425 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -408,6 +408,7 @@ static inline bool ndb_supported_type(enum_field_types type)
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_BIT:
break;
}
return FALSE;
diff --git a/sql/item.cc b/sql/item.cc
index ee77f2d43c0..7dba1f3a66a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -23,7 +23,6 @@
#include <m_ctype.h>
#include "my_dir.h"
#include "sp_rcontext.h"
-#include "sql_acl.h"
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_select.h"
@@ -1925,6 +1924,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
/* Search in the SELECT and GROUP lists of the outer select. */
if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE)
+ {
if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel)))
return TRUE; /* Some error occured (e.g. ambigous names). */
if (ref != not_found_item)
diff --git a/sql/item.h b/sql/item.h
index 5a760db23f5..2503f137355 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1120,9 +1120,9 @@ public:
/* Constructor need to process subselect with temporary tables (see Item) */
Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
- double val()
+ double val_real()
{
- double tmp=(*ref)->val();
+ double tmp=(*ref)->val_real();
null_value=(*ref)->null_value;
return tmp;
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index a118de6fdb9..40513c2c25a 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -154,7 +154,7 @@ void Item_func_not_all::print(String *str)
longlong Item_func_nop_all::val_int()
{
DBUG_ASSERT(fixed == 1);
- double value= args[0]->val();
+ longlong value= args[0]->val_int();
/*
return FALSE if there was records in underlaying select in max/min
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index c346de98615..a820d04d900 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -635,7 +635,8 @@ bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields,
- List<Item> &update_values, enum_duplicates duplic);
+ List<Item> &update_values, enum_duplicates duplic,
+ COND **where, bool select_insert);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 203be4b96a4..2b51419d7b7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2124,7 +2124,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
- (void*) sig))
+ (void*) &sig))
sql_print_error("Can't create thread to kill server");
#else
kill_server((void*) sig); // MIT THREAD has a alarm thread
diff --git a/sql/sp.cc b/sql/sp.cc
index 4605d49f3ab..04233f931b5 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -16,7 +16,6 @@
#include "mysql_priv.h"
-#include "sql_acl.h"
#include "sp.h"
#include "sp_head.h"
#include "sp_cache.h"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 31c6075b590..9afc0c04631 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -19,7 +19,6 @@
#endif
#include "mysql_priv.h"
-#include "sql_acl.h"
#include "sp_head.h"
#include "sp.h"
#include "sp_pcontext.h"
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 81419d64e15..57430d5ee8e 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2981,15 +2981,17 @@ err:
bool check_grant_column(THD *thd, GRANT_INFO *grant,
- char*db_name, char *table_name,
+ char *db_name, char *table_name,
const char *name, uint length, uint show_tables)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
-
ulong want_access= grant->want_privilege & ~grant->privilege;
+ DBUG_ENTER("check_grant_column");
+ DBUG_PRINT("enter", ("table: %s want_access: %u", table_name, want_access));
+
if (!want_access)
- return 0; // Already checked
+ DBUG_RETURN(0); // Already checked
rw_rdlock(&LOCK_grant);
@@ -3000,7 +3002,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
grant->grant_table=
table_hash_search(thd->host, thd->ip, db_name,
thd->priv_user,
- table_name, 0); /* purecov: inspected */
+ table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
if (!(grant_table= grant->grant_table))
@@ -3010,13 +3012,13 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
if (grant_column && !(~grant_column->rights & want_access))
{
rw_unlock(&LOCK_grant);
- return 0;
+ DBUG_RETURN(0);
}
#ifdef NOT_USED
if (show_tables && (grant_column || grant->privilege & COL_ACLS))
{
rw_unlock(&LOCK_grant); /* purecov: deadcode */
- return 0; /* purecov: deadcode */
+ DBUG_RETURN(0); /* purecov: deadcode */
}
#endif
@@ -3033,7 +3035,7 @@ err:
name,
table_name);
}
- return 1;
+ DBUG_RETURN(1);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 250da2981ff..62d0c72a4b3 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2067,10 +2067,10 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
uint *cached_field_index_ptr,
bool register_tree_change)
{
- DBUG_ENTER("find_field_in_table");
- DBUG_PRINT("enter", ("table:%s name: %s item name %s, ref 0x%lx",
- table_list->alias, name, item_name, (ulong)ref));
Field *fld;
+ DBUG_ENTER("find_field_in_table");
+ DBUG_PRINT("enter", ("table: '%s' name: '%s' item name: '%s' ref 0x%lx",
+ table_list->alias, name, item_name, (ulong) ref));
if (table_list->field_translation)
{
DBUG_ASSERT(ref != 0 && table_list->view != 0);
@@ -2097,10 +2097,7 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
item_name);
/* as far as Item_ref have defined reference it do not need tables */
if (register_tree_change && item_ref)
- {
thd->change_item_tree(ref, item_ref);
- (*ref)->fix_fields(thd, 0, ref);
- }
}
DBUG_RETURN((Field*) view_ref_found);
}
@@ -2788,6 +2785,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
TABLE_LIST **leaves, bool refresh, bool select_insert)
{
+ uint tablenr= 0;
DBUG_ENTER("setup_tables");
/*
this is used for INSERT ... SELECT.
@@ -2800,13 +2798,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
DBUG_RETURN(0);
tables->setup_is_done= 1;
-
if (!(*leaves))
- {
make_leaves_list(leaves, tables);
- }
- uint tablenr= 0;
for (TABLE_LIST *table_list= *leaves;
table_list;
table_list= table_list->next_leaf, tablenr++)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 149d12225a3..db6dbd5e3ea 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1401,7 +1401,7 @@ public:
List<create_field> &fields_par,
List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic)
- :select_insert (NULL, NULL, &select_fields, duplic, 0), create_table(table),
+ :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, 0), create_table(table),
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par),
lock(0)
{}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index e2b7ee93905..c681fe25548 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -180,6 +180,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
char *query= thd->query;
#endif
thr_lock_type lock_type = table_list->lock_type;
+ Item *unused_conds= 0;
DBUG_ENTER("mysql_insert");
/*
@@ -244,7 +245,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
values= its++;
if (mysql_prepare_insert(thd, table_list, table, fields, values,
- update_fields, update_values, duplic))
+ update_fields, update_values, duplic, &unused_conds,
+ FALSE))
goto abort;
/* mysql_prepare_insert set table_list->table if it was not set */
@@ -651,6 +653,10 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
mysql_prepare_insert()
thd Thread handler
table_list Global/local table list
+ table Table to insert into (can be NULL if table should be taken from
+ table_list->table)
+ where Where clause (for insert ... select)
+ select_insert TRUE if INSERT ... SELECT statement
RETURN VALUE
FALSE OK
@@ -660,11 +666,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
- enum_duplicates duplic)
+ enum_duplicates duplic,
+ COND **where, bool select_insert)
{
bool insert_into_view= (table_list->view != 0);
/* TODO: use this condition for 'WITH CHECK OPTION' */
- Item *unused_conds= 0;
bool res;
DBUG_ENTER("mysql_prepare_insert");
DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
@@ -675,11 +681,11 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
{
/* it should be allocated before Item::fix_fields() */
if (table_list->set_insert_values(thd->mem_root))
- goto abort;
+ DBUG_RETURN(TRUE);
}
- if (mysql_prepare_insert_check_table(thd, table_list, fields, &unused_conds,
- FALSE))
+ if (mysql_prepare_insert_check_table(thd, table_list, fields, where,
+ select_insert))
DBUG_RETURN(TRUE);
if ((values && check_insert_fields(thd, table_list, fields, *values, 1,
@@ -799,7 +805,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
DBUG_ASSERT(table->insert_values != NULL);
store_record(table,insert_values);
restore_record(table,record[1]);
- DBUG_ASSERT(info->update_fields->elements == info->update_values->elements);
+ DBUG_ASSERT(info->update_fields->elements ==
+ info->update_values->elements);
if (fill_record(thd, *info->update_fields, *info->update_values, 0))
goto err;
@@ -808,7 +815,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
(res= info->view->view_check_option(current_thd, info->ignore)) ==
VIEW_CHECK_SKIP)
break;
- else if (res == VIEW_CHECK_ERROR)
+ if (res == VIEW_CHECK_ERROR)
goto err;
if ((error=table->file->update_row(table->record[1],table->record[0])))
@@ -1715,23 +1722,25 @@ bool delayed_insert::handle_inserts(void)
bool mysql_insert_select_prepare(THD *thd)
{
LEX *lex= thd->lex;
- TABLE_LIST* first_select_table=
- (TABLE_LIST*)lex->select_lex.table_list.first;
- TABLE_LIST* first_select_leaf_table;
+ TABLE_LIST *first_select_table=
+ (TABLE_LIST*) lex->select_lex.table_list.first;
+ TABLE_LIST *first_select_leaf_table;
int res;
DBUG_ENTER("mysql_insert_select_prepare");
/*
SELECT_LEX do not belong to INSERT statement, so we can't add WHERE
- clasue if table is VIEW
+ clause if table is VIEW
*/
lex->query_tables->no_where_clause= 1;
- if (mysql_prepare_insert_check_table(thd, lex->query_tables,
- lex->field_list,
- &lex->select_lex.where,
- TRUE))
+ if (mysql_prepare_insert(thd, lex->query_tables,
+ lex->query_tables->table, lex->field_list, 0,
+ lex->update_list, lex->value_list,
+ lex->duplicates,
+ &lex->select_lex.where, TRUE))
DBUG_RETURN(TRUE);
+
/*
- setup was done in mysql_insert_select_prepare, but we have to mark
+ setup was done in mysql_prepare_insert_check_table, but we have to mark
first local table
*/
if (first_select_table)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index ece960c5d1c..c8ad2b00480 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -952,13 +952,12 @@ int yylex(void *arg, void *yythd)
if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) &&
(thd->command != COM_PREPARE))
{
- lex->found_colon=(char*)lex->ptr;
- thd->server_status |= SERVER_MORE_RESULTS_EXISTS;
- lex->next_state=MY_LEX_END;
- return(END_OF_INPUT);
+ lex->found_colon= (char*) lex->ptr;
+ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
+ lex->next_state= MY_LEX_END;
+ return (END_OF_INPUT);
}
- else
- state=MY_LEX_CHAR; // Return ';'
+ state= MY_LEX_CHAR; // Return ';'
break;
}
/* fall true */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b5b0d76dcf3..6a59469f5c2 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2983,13 +2983,8 @@ create_error:
select_result *result;
unit->set_limit(select_lex, select_lex);
- if (!(res= open_and_lock_tables(thd, all_tables)) &&
- !(res= mysql_prepare_insert(thd, tables, first_local_table,
- tables->table, lex->field_list, 0,
- lex->update_list, lex->value_list,
- lex->duplicates)))
+ if (!(res= open_and_lock_tables(thd, all_tables)))
{
- TABLE *table= tables->table;
/* Skip first table, which is the table we are inserting in */
lex->select_lex.table_list.first= (byte*)first_table->next_local;
@@ -3008,8 +3003,10 @@ create_error:
res= handle_select(thd, lex, result);
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
delete result;
- table->insert_values= 0;
}
+ /* in case of error first_table->table can be 0 */
+ if (first_table->table)
+ first_table->table->insert_values= 0;
/* revert changes for SP */
lex->select_lex.table_list.first= (byte*) first_table;
}
@@ -3819,8 +3816,8 @@ create_error:
st_sp_security_context save_ctx;
#endif
ha_rows select_limit;
- uint smrx;
- LINT_INIT(smrx);
+ /* bits that should be cleared in thd->server_status */
+ uint bits_to_be_cleared= 0;
/* In case the arguments are subselects... */
if (all_tables &&
@@ -3842,8 +3839,13 @@ create_error:
#endif
goto error;
}
- smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS;
- thd->server_status |= SERVER_MORE_RESULTS_EXISTS;
+ /*
+ If SERVER_MORE_RESULTS_EXISTS is not set,
+ then remember that it should be cleared
+ */
+ bits_to_be_cleared= (~thd->server_status &
+ SERVER_MORE_RESULTS_EXISTS);
+ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -3863,14 +3865,11 @@ create_error:
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
- if (sp->m_multi_results)
- {
- if (! smrx)
- thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
- }
+ thd->server_status&= ~bits_to_be_cleared;
if (!res)
- send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 : thd->row_count_func));
+ send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
+ thd->row_count_func));
else
goto error; // Substatement should already have sent error
}
@@ -6102,10 +6101,9 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
DBUG_PRINT("info",("Checking sub query list"));
for (table= tables; table; table= table->next_global)
{
- if (my_tz_check_n_skip_implicit_tables(&table,
- lex->time_zone_tables_used))
- continue;
- if (!table->table_in_first_from_clause && table->derived)
+ if (!my_tz_check_n_skip_implicit_tables(&table,
+ lex->time_zone_tables_used) &&
+ !table->table_in_first_from_clause)
{
if (check_access(thd, SELECT_ACL, table->db,
&table->grant.privilege, 0, 0) ||
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index e4e61dc8d31..c860e3a79ac 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -905,10 +905,12 @@ static bool mysql_test_insert(Prepared_statement *stmt,
{
uint value_count;
ulong counter= 0;
+ Item *unused_conds= 0;
if ((res= mysql_prepare_insert(thd, table_list, table_list->table,
fields, values, update_fields,
- update_values, duplic)))
+ update_values, duplic,
+ &unused_conds, FALSE)))
goto error;
value_count= values->elements;
@@ -1381,18 +1383,21 @@ static int mysql_test_multidelete(Prepared_statement *stmt,
1 error, sent to client
-1 error, not sent to client
*/
+
static int mysql_test_insert_select(Prepared_statement *stmt,
TABLE_LIST *tables)
{
int res;
LEX *lex= stmt->lex;
+ TABLE_LIST *first_local_table;
+
if ((res= insert_precheck(stmt->thd, tables)))
return res;
- TABLE_LIST *first_local_table=
- (TABLE_LIST *)lex->select_lex.table_list.first;
+ first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
/* Skip first table, which is the table we are inserting in */
lex->select_lex.table_list.first= (byte*) first_local_table->next_local;
+
/*
insert/replace from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
@@ -1595,7 +1600,7 @@ static void cleanup_stmt_for_execute(Prepared_statement *stmt)
{
for (TABLE_LIST *tables= (TABLE_LIST*) sl->table_list.first;
tables;
- tables= tables->next)
+ tables= tables->next_global)
{
if (tables->table)
tables->table->insert_values= 0;
@@ -1698,7 +1703,6 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
if (!error)
error= check_prepared_statement(stmt, test(name));
- cleanup_stmt_for_execute(stmt);
/* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */
if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -1713,6 +1717,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
lex_end(lex);
thd->restore_backup_statement(stmt, &thd->stmt_backup);
cleanup_items(stmt->free_list);
+ cleanup_stmt_for_execute(stmt);
close_thread_tables(thd);
thd->rollback_item_tree_changes();
thd->cleanup_after_query();
@@ -2057,9 +2062,9 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
cleanup_items(stmt->free_list);
thd->rollback_item_tree_changes();
reset_stmt_params(stmt);
+ cleanup_stmt_for_execute(stmt);
close_thread_tables(thd); // to close derived tables
thd->set_statement(&thd->stmt_backup);
- cleanup_stmt_for_execute(stmt);
thd->cleanup_after_query();
if (stmt->state == Item_arena::PREPARED)
@@ -2087,7 +2092,6 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
int error;
DBUG_ENTER("mysql_stmt_fetch");
- thd->current_arena= stmt;
if (!(stmt= thd->stmt_map.find(stmt_id)) ||
!stmt->cursor ||
!stmt->cursor->is_open())
@@ -2095,7 +2099,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_id, "fetch");
DBUG_VOID_RETURN;
}
-
+ thd->current_arena= stmt;
thd->set_n_backup_statement(stmt, &thd->stmt_backup);
stmt->cursor->init_thd(thd);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index a88dc0b20bf..96ede3fbe6b 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -2,8 +2,6 @@
#include "sp_head.h"
#include "sql_trigger.h"
#include "parse_file.h"
-#include "sql_acl.h"
-
static const LEX_STRING triggers_file_type= {(char *)"TRIGGERS", 8};
static const char * const triggers_file_ext= ".TRG";
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index fa4acce31f7..d10c54f6fab 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -620,9 +620,8 @@ bool mysql_multi_update_prepare(THD *thd)
LEX *lex= thd->lex;
ulong opened_tables;
TABLE_LIST *table_list= lex->query_tables;
+ TABLE_LIST *tl, *leaves;
List<Item> *fields= &lex->select_lex.item_list;
- TABLE_LIST *tl;
- TABLE_LIST *leaves;
table_map tables_for_update;
int res;
bool update_view= 0;
@@ -634,9 +633,10 @@ bool mysql_multi_update_prepare(THD *thd)
uint table_count= lex->table_count;
const bool using_lock_tables= thd->locked_tables != 0;
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
+ DBUG_ENTER("mysql_multi_update_prepare");
+
/* following need for prepared statements, to run next time multi-update */
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
- DBUG_ENTER("mysql_multi_update_prepare");
/* open tables and create derived ones, but do not lock and fill them */
if ((original_multiupdate && open_tables(thd, table_list, & table_count)) ||
@@ -651,24 +651,7 @@ bool mysql_multi_update_prepare(THD *thd)
if (setup_tables(thd, table_list, &lex->select_lex.where,
&lex->select_lex.leaf_tables, FALSE, FALSE))
DBUG_RETURN(TRUE);
- /*
- Ensure that we have update privilege for all tables and columns in the
- SET part
- */
- for (tl= (leaves= lex->select_lex.leaf_tables); tl; tl= tl->next_leaf)
- {
- /*
- Update of derived tables is checked later
- We don't check privileges here, becasue then we would get error
- "UPDATE command denided .. for column N" instead of
- "Target table ... is not updatable"
- */
- TABLE *table= tl->table;
- TABLE_LIST *tlist;
- if (!(tlist= tl->belong_to_view?tl->belong_to_view:tl)->derived)
- tlist->grant.want_privilege= table->grant.want_privilege=
- (UPDATE_ACL & ~table->grant.privilege);
- }
+ leaves= lex->select_lex.leaf_tables;
if ((lex->select_lex.no_wrap_view_item= 1,
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
@@ -698,11 +681,6 @@ bool mysql_multi_update_prepare(THD *thd)
for (tl= leaves; tl; tl= tl->next_leaf)
{
TABLE *table= tl->table;
- TABLE_LIST *tlist= tl->belong_to_view?tl->belong_to_view:tl;
-
- /* We only need SELECT privilege for columns in the values list */
- tlist->grant.want_privilege= table->grant.want_privilege=
- (SELECT_ACL & ~table->grant.privilege);
/* Only set timestamp column if this is not modified */
if (table->timestamp_field &&
table->timestamp_field->query_id == thd->query_id)
@@ -730,26 +708,24 @@ bool mysql_multi_update_prepare(THD *thd)
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
tl->lock_type= lex->multi_lock_option;
tl->updating= 1;
- }
+ }
else
{
DBUG_PRINT("info",("setting table `%s` for read-only", tl->alias));
tl->lock_type= TL_READ;
tl->updating= 0;
}
- if (!using_lock_tables)
- tl->table->reginfo.lock_type= tl->lock_type;
/* Check access privileges for table */
+ if (!tl->derived)
{
- TABLE_LIST *save= tl->next;
- bool res;
- tl->next= 0;
- res= (check_access(thd, tl->updating ? UPDATE_ACL : SELECT_ACL,
- tl->db, &tl->grant.privilege, 0, 0) ||
- (grant_option && check_grant(thd, wants, tl, 0, 0, 0)));
- tl->next= save;
- if (res)
+ uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
+ if (!using_lock_tables)
+ tl->table->reginfo.lock_type= tl->lock_type;
+
+ if (check_access(thd, want_privilege,
+ tl->db, &tl->grant.privilege, 0, 0) ||
+ (grant_option && check_grant(thd, want_privilege, tl, 0, 1, 0)))
DBUG_RETURN(TRUE);
}
}
@@ -806,6 +782,22 @@ bool mysql_multi_update_prepare(THD *thd)
res))
DBUG_RETURN(TRUE);
}
+
+ /* We only need SELECT privilege for columns in the values list */
+ for (tl= leaves; tl; tl= tl->next_leaf)
+ {
+ TABLE *table= tl->table;
+ TABLE_LIST *tlist;
+ if (!(tlist= tl->belong_to_view ? tl->belong_to_view : tl)->derived)
+ {
+ tlist->grant.want_privilege=
+ (SELECT_ACL & ~tlist->grant.privilege);
+ table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
+ }
+ DBUG_PRINT("info", ("table: %s want_privilege: %u", tl->alias,
+ (uint) table->grant.want_privilege));
+ }
+
if (thd->fill_derived_tables() &&
mysql_handle_derived(lex, &mysql_derived_filling))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 993a4d1987b..bafb57c44b0 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -16,7 +16,6 @@
*/
#include "mysql_priv.h"
-#include "sql_acl.h"
#include "sql_select.h"
#include "parse_file.h"
#include "sp.h"
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 1c2dde5d278..96e93fb126d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5716,7 +5716,7 @@ expr_or_default:
opt_insert_update:
/* empty */
- | ON DUPLICATE_SYM
+ | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
KEY_SYM UPDATE_SYM insert_update_list
;
@@ -5759,6 +5759,8 @@ update_list:
update_elem:
simple_ident_nospvar equal expr_or_default
{
+ if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
+ YYABORT;
};
insert_update_list:
diff --git a/sql/table.cc b/sql/table.cc
index a37186287b4..877ffe4fbb9 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -21,7 +21,6 @@
#include <errno.h>
#include <m_ctype.h>
#include "md5.h"
-#include "sql_acl.h"
/* Functions defined in this file */