diff options
author | unknown <monty@mysql.com> | 2004-12-31 00:44:00 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-12-31 00:44:00 +0200 |
commit | 2e8d13c73ec986dde580c9c840f421af4279611a (patch) | |
tree | 77b085cd22eae45e57f4e20f35ecfc231153d656 /sql | |
parent | bb2d3eaa30a3881927142c985fb637aca06d9823 (diff) | |
download | mariadb-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.cc | 7 | ||||
-rw-r--r-- | sql/gen_lex_hash.cc | 24 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 5 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 1 | ||||
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/sp.cc | 1 | ||||
-rw-r--r-- | sql/sp_head.cc | 1 | ||||
-rw-r--r-- | sql/sql_acl.cc | 16 | ||||
-rw-r--r-- | sql/sql_base.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 43 | ||||
-rw-r--r-- | sql/sql_lex.cc | 11 | ||||
-rw-r--r-- | sql/sql_parse.cc | 40 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 20 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 66 | ||||
-rw-r--r-- | sql/sql_view.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 4 | ||||
-rw-r--r-- | sql/table.cc | 1 |
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 */ |