From df8a43b8b2f51901fc35cd5dbd047e09941eeae3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Sep 2004 20:17:09 +0200 Subject: sql_print_error cleanup --- sql/sql_parse.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 79a011b9501..a90a58ddfe0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1022,12 +1022,12 @@ pthread_handler_decl(handle_one_connection,arg) if (net->error && net->vio != 0 && net->report_error) { if (!thd->killed && thd->variables.log_warnings > 1) - sql_print_error(ER(ER_NEW_ABORTING_CONNECTION), - thd->thread_id,(thd->db ? thd->db : "unconnected"), - thd->user ? thd->user : "unauthenticated", - thd->host_or_ip, - (net->last_errno ? ER(net->last_errno) : - ER(ER_UNKNOWN_ERROR))); + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + thd->user ? thd->user : "unauthenticated", + thd->host_or_ip, + (net->last_errno ? ER(net->last_errno) : + ER(ER_UNKNOWN_ERROR))); send_error(thd,net->last_errno,NullS); statistic_increment(aborted_threads,&LOCK_status); } -- cgit v1.2.1 From 6c2330407f99b0bab1db68ec38789fc10a3518ec Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Sep 2004 13:39:15 +0300 Subject: check that table used in multi-update is unique added (BUG#5455) mysql-test/r/multi_update.result: multi* unique updating table check mysql-test/t/multi_update.test: multi* unique updating table check sql/sql_lex.cc: new method to check table only in subqueries sql/sql_lex.h: new method to check table only in subqueries sql/sql_parse.cc: used new method to check table only in subqueries sql/sql_update.cc: check that table is unique added --- sql/sql_parse.cc | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 39b94362269..dd57f37473c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2796,24 +2796,19 @@ unsent_create_error: target_tbl; target_tbl= target_tbl->next) { - target_tbl->table= target_tbl->table_list->table; - /* + TABLE_LIST *orig= target_tbl->table_list; + target_tbl->table= orig->table; + /* Multi-delete can't be constructed over-union => we always have single SELECT on top and have to check underlaying SELECTs of it */ - for (SELECT_LEX_UNIT *un= lex->select_lex.first_inner_unit(); - un; - un= un->next_unit()) + if (lex->select_lex.check_updateable_in_subqueries(orig->db, + orig->real_name)) { - if (un->first_select()->linkage != DERIVED_TABLE_TYPE && - un->check_updateable(target_tbl->table_list->db, - target_tbl->table_list->real_name)) - { - my_error(ER_UPDATE_TABLE_USED, MYF(0), - target_tbl->table_list->real_name); - res= -1; - break; - } + my_error(ER_UPDATE_TABLE_USED, MYF(0), + orig->real_name); + res= -1; + break; } } -- cgit v1.2.1 From 7c80446c4e0bd6d4572bdbc3a5498c379c49d0a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Sep 2004 18:56:47 +0200 Subject: BUG#4788 - show create table provides incorrect statement. Added code to adjust the field_length of user variables in dependence on the field type. Aded new constants for numeric field widths. include/mysql_com.h: BUG#4788 - show create table provides incorrect statement. Introduced definitions for default field width of numeric types. So common values can be used at different places in the code. mysql-test/r/variables.result: BUG#4788 - show create table provides incorrect statement. New test results. mysql-test/t/variables.test: BUG#4788 - show create table provides incorrect statement. Added a test for the bug. sql/item_func.cc: BUG#4788 - show create table provides incorrect statement. Added code to adjust the field_length of user variables in dependence on the field type. sql/sql_parse.cc: BUG#4788 - show create table provides incorrect statement. Changed numeric literals to the new constants. --- sql/sql_parse.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 39b94362269..b5f5a30d77f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4208,23 +4208,23 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, switch (type) { case FIELD_TYPE_TINY: - if (!length) new_field->length=3+sign_len; + if (!length) new_field->length=MAX_TINYINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; case FIELD_TYPE_SHORT: - if (!length) new_field->length=5+sign_len; + if (!length) new_field->length=MAX_SMALLINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; case FIELD_TYPE_INT24: - if (!length) new_field->length=8+sign_len; + if (!length) new_field->length=MAX_MEDIUMINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; case FIELD_TYPE_LONG: - if (!length) new_field->length=10+sign_len; + if (!length) new_field->length=MAX_INT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; case FIELD_TYPE_LONGLONG: - if (!length) new_field->length=20; + if (!length) new_field->length=MAX_BIGINT_WIDTH; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; case FIELD_TYPE_NULL: -- cgit v1.2.1 From e9e714459f0e150ca6f917028bb3c79882b69445 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Sep 2004 11:16:34 +0200 Subject: indentation cleanup --- sql/sql_parse.cc | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b5f5a30d77f..75c1e0b859e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3518,29 +3518,29 @@ purposes internal to the MySQL server", MYF(0)); } thd->proc_info="query end"; // QQ if (thd->one_shot_set) + { + /* + If this is a SET, do nothing. This is to allow mysqlbinlog to print + many SET commands (in this case we want the charset temp setting to + live until the real query). This is also needed so that SET + CHARACTER_SET_CLIENT... does not cancel itself immediately. + */ + if (lex->sql_command != SQLCOM_SET_OPTION) { - /* - If this is a SET, do nothing. This is to allow mysqlbinlog to print - many SET commands (in this case we want the charset temp setting to - live until the real query). This is also needed so that SET - CHARACTER_SET_CLIENT... does not cancel itself immediately. - */ - if (lex->sql_command != SQLCOM_SET_OPTION) - { - thd->variables.character_set_client= - global_system_variables.character_set_client; - thd->variables.collation_connection= - global_system_variables.collation_connection; - thd->variables.collation_database= - global_system_variables.collation_database; - thd->variables.collation_server= - global_system_variables.collation_server; - thd->update_charset(); - thd->variables.time_zone= - global_system_variables.time_zone; - thd->one_shot_set= 0; - } + thd->variables.character_set_client= + global_system_variables.character_set_client; + thd->variables.collation_connection= + global_system_variables.collation_connection; + thd->variables.collation_database= + global_system_variables.collation_database; + thd->variables.collation_server= + global_system_variables.collation_server; + thd->update_charset(); + thd->variables.time_zone= + global_system_variables.time_zone; + thd->one_shot_set= 0; } + } if (res < 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); -- cgit v1.2.1 From 1bd580aa68acaf4144630f024ec1fa5da6976a4b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Sep 2004 18:37:26 +0300 Subject: wording fixed --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ba9ee611390..2c5ec34b867 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2800,7 +2800,7 @@ unsent_create_error: target_tbl->table= orig->table; /* Multi-delete can't be constructed over-union => we always have - single SELECT on top and have to check underlaying SELECTs of it + single SELECT on top and have to check underlying SELECTs of it */ if (lex->select_lex.check_updateable_in_subqueries(orig->db, orig->real_name)) -- cgit v1.2.1 From e6f924efe586cef418b6d77b950bdcd1ad97871b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 27 Sep 2004 00:50:00 +0400 Subject: Fix for bug #4131 "TIMESTAMP columns missing minutes and seconds when using GROUP BY" Now we are setting Field_timestamp::field_length to 19 in open_table() if we are in new mode (and we are restoring it back when we are coming back to normal mode). This also should solve potential problems with some of LOAD DATA INFILE and SELECT * INTO in this mode. mysql-test/r/type_timestamp.result: Added test for bug #4131 'TIMESTAMP columns missing minutes and seconds when using GROUP BY' and other --new mode related behavior. mysql-test/t/type_timestamp.test: Added test for bug #4131 'TIMESTAMP columns missing minutes and seconds when using GROUP BY' and other --new mode related behavior. sql/field.cc: Added Field_timestamp::orig_field_length member for saving original field_length value, because this member can be modified if new_mode is in effect. Lot of Field_timestamp code simplified and Field_timestamp::make_field() is no longer needed because we are setting field_length to 19 if we are in --new mode now. sql/field.h: Added Field_timestamp::orig_field_length member for saving original field_length value, because this member can be modified if new_mode is in effect. Field_timestamp::make_field() is no longer needed because we are setting field_length to 19 if we are in --new mode now. sql/sql_base.cc: If --new mode is in effect all TIMESTAMP fields should pretend that they have length of 19. We are achieving this by setting Field_timestamp::field_length to 19 (or original value) in open_table(). We are using TABLE::timestamp_mode variable for avoiding of unnecessary looping over all fields of the table and setting field_length if table was used with same new_mode value before. Note: We do not introduce general framework for setting up Field objects for usage with current THD here because this fix is only needed in 4.0 and Monty said that we will also remove looping over all fields when updating table_name member at some point. This more general framework will also complicate nice optimization with avoiding of unneeded looping. sql/sql_parse.cc: Now when we are creating TIMESTAMP(19) fields by default in --new mode, otherwise we will have unaligned behavior between ALTER and CREATE. sql/table.h: Added TABLE::timestamp_mode field for saving information whenever we set field_length members of table's TIMESTAMP fields to 19 (to honor new_mode) or they have original values. --- sql/sql_parse.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 14fc748c288..4f1a0589db1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3229,7 +3229,18 @@ bool add_field_to_list(char *field_name, enum_field_types type, } break; case FIELD_TYPE_TIMESTAMP: +#if MYSQL_VERSION_ID < 40100 + /* + When in in --new mode, we should create TIMESTAMP(19) fields by default; + otherwise we will have problems with ALTER TABLE changing lengths of + existing TIMESTAMP fields to 19 and adding new fields with length 14. + */ + if (thd->variables.new_mode) + new_field->length= 19; + else if (!length) +#else if (!length) +#endif new_field->length= 14; // Full date YYYYMMDDHHMMSS else if (new_field->length != 19) { -- cgit v1.2.1 From 7b511544614ab2ab3906c685f7ea7730f1f46605 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Oct 2004 18:54:06 +0400 Subject: Support for TIMESTAMP columns holding NULL values. Unlike all other column types TIMESTAMP is NOT NULL by default, so in order to have TIMESTAMP column holding NULL valaues you have to specify NULL as one of its attributes (this needed for backward compatibility). Main changes: Replaced TABLE::timestamp_default_now/on_update_now members with TABLE::timestamp_auto_set_type flag which is used everywhere for determining if we should auto-set value of TIMESTAMP field during this operation or not. We are also use Field_timestamp::set_time() instead of handler::update_timestamp() in handlers. mysql-test/r/type_timestamp.result: Added test for TIMESTAMP columns which are able to store NULL values. mysql-test/t/type_timestamp.test: Added test for TIMESTAMP columns which are able to store NULL values. sql/field.cc: Added support for TIMESTAMP fields holding NULL values. We don't need Field_timestamp::set_timestamp_offsets() anymore. Instead we need Field_timestamp::get_auto_set_type() function which will convert TIMESTAMP auto-set type stored in Field in unireg_check to value from timestamp_auto_set_type_enum. (We can't replace this function with additional Field_timestamp member and some code in constructor because then we will have troubles with Field::new_field() method). We should also set field to not null in Field_timestamp::set_time() now. sql/field.h: Added support for TIMESTAMP fields holding NULL values. We don't need Field_timestamp::set_timestamp_offsets() anymore. Instead we need Field_timestamp::get_auto_set_type() function, which will convert TIMESTAMP auto-set type stored in Field in unireg_check to value from timestamp_auto_set_type_enum. We also have to support NULL values in Field_timestamp::get_timestamp() function. sql/field_conv.cc: Added comment clarifying behavior in case of TIMESTAMP fields which are able to store NULL values. sql/ha_berkeley.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_heap.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_innodb.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_isam.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_isammrg.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_myisam.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_myisammrg.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/ha_ndbcluster.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). sql/handler.cc: handler::update_timestamp() is no longer needed since now we use Field_timestamp::set_time() instead. (we can't use handler::update_timestamp() anyway since field position only is not enough for TIMESTAMP fields which are able to store NULLs) sql/handler.h: handler::update_timestamp() is no longer needed since now we use Field_timestamp::set_time() instead. sql/item_timefunc.cc: Since now TIMESTAMP fields can hold NULL values we should take this into account. sql/sql_base.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now. (Here we use Field_timestamp::get_auto_set_type() to setup its value before further statement execution). sql/sql_insert.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now. sql/sql_load.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now. sql/sql_parse.cc: Added support for TIMESTAMP fields holding NULL values. We should distinguish NULL default values and non-specified default values for such fields (because latter could mean DEFAULT NOW() ON UPDATE NOW() in some cases). sql/sql_show.cc: Added support for TIMESTAMP fields holding NULL values. Unlike all other fields these are NOT NULL by default so we have to specify NULL attribute explicitly for them. sql/sql_table.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now. sql/sql_update.cc: Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now. sql/sql_yacc.yy: Added support for TIMESTAMP fields holding NULL values. Unlike all other fields these are NOT NULL by default (so we have to set NOT_NULL_FLAG properly for them). sql/table.h: Added timestamp_auto_set_type enum which values are used for indicating during which operations we should automatically set TIMESTAPM field value to current timestamp. TABLE: Replaced timestamp_default_now/on_update_now members with timestamp_auto_set_type flag (Now when TIMESTAMP field are able to store NULL values, single position of field in record is not enough for updating this field anyway). --- sql/sql_parse.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2c5ec34b867..e8441c05609 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4142,7 +4142,12 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, } else if (default_value->type() == Item::NULL_ITEM) { - default_value=0; + /* + TIMESTAMP type should be able to distingush non-specified default + value and default value NULL later. + */ + if (type != FIELD_TYPE_TIMESTAMP) + default_value= 0; if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { @@ -4334,7 +4339,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */ new_field->length= min(new_field->length,14); /* purecov: inspected */ } - new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG | NOT_NULL_FLAG; + new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; if (default_value) { /* Grammar allows only NOW() value for ON UPDATE clause */ @@ -4352,6 +4357,9 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, else new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD: Field::NONE); + + if (default_value->type() == Item::NULL_ITEM) + new_field->def= 0; } else { -- cgit v1.2.1 From a49f5cae9ad6f4de7f5c2d9f8bbdbca270376af6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Oct 2004 00:20:47 +0100 Subject: Bug#4118: multi-table UPDATE takes WRITE lock on read table Ensures that WRITE lock is not obtained on all tables referenced. mysql-test/r/lock_multi.result: Bug#4118 New test for multi-update locking mysql-test/r/multi_update.result: Bug#4118 Fix test mysql-test/t/lock_multi.test: Bug#4118 New test for multi-update locking mysql-test/t/multi_update.test: Bug#4118 Fix test sql/sql_parse.cc: Bug#4118 Split multi-update to its own case statement in sql_parse.cc sql/sql_update.cc: Bug#4118 Overview of locking checking: 1. Open and acquire READ lock 2. Check to see which tables need WRITE lock 3. Unlock tables and relock sql/sql_yacc.yy: Bug#4118 Split multi-update to its own case statement in sql_parse.cc --- sql/sql_parse.cc | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e95c52f1e48..894fa355262 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1927,21 +1927,26 @@ mysql_execute_command(void) send_error(&thd->net,ER_WRONG_VALUE_COUNT); DBUG_VOID_RETURN; } - if (select_lex->table_list.elements == 1) - { - if (check_one_table_access(thd, UPDATE_ACL, tables, 0)) - goto error; /* purecov: inspected */ + if (check_one_table_access(thd, UPDATE_ACL, tables, 0)) + goto error; /* purecov: inspected */ - res= mysql_update(thd,tables, - select_lex->item_list, - lex->value_list, - select_lex->where, - (ORDER *) select_lex->order_list.first, - select_lex->select_limit, - lex->duplicates); + res= mysql_update(thd,tables, + select_lex->item_list, + lex->value_list, + select_lex->where, + (ORDER *) select_lex->order_list.first, + select_lex->select_limit, + lex->duplicates); + break; + case SQLCOM_MULTI_UPDATE: + if (check_db_used(thd,tables)) + goto error; + if (select_lex->item_list.elements != lex->value_list.elements) + { + send_error(&thd->net,ER_WRONG_VALUE_COUNT); + DBUG_VOID_RETURN; } - else { const char *msg= 0; TABLE_LIST *table; -- cgit v1.2.1 From 76c9e10ebd554b4b11b193b7cefcfc2101ec1fb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Oct 2004 17:13:31 +0400 Subject: Made TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). (still to be discussed with Monty, Brian, Trudy et al. before push) mysql-test/r/type_timestamp.result: Update test after making TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). mysql-test/t/type_timestamp.test: Update test after making TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). sql/sql_parse.cc: add_field_to_list(): made TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). This also simplifies code a bit. --- sql/sql_parse.cc | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e8441c05609..34cad1b062d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4142,12 +4142,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, } else if (default_value->type() == Item::NULL_ITEM) { - /* - TIMESTAMP type should be able to distingush non-specified default - value and default value NULL later. - */ - if (type != FIELD_TYPE_TIMESTAMP) - default_value= 0; + default_value= 0; if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { @@ -4357,19 +4352,27 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, else new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD: Field::NONE); - - if (default_value->type() == Item::NULL_ITEM) - new_field->def= 0; } else { - /* - We are setting TIMESTAMP_OLD_FIELD here only temporary, we will - replace this value by TIMESTAMP_DNUN_FIELD or NONE later when + /* + If we have default TIMESTAMP NOT NULL column without explicit DEFAULT + or ON UPDATE values then for the sake of compatiblity we should treat + this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't + have another TIMESTAMP column with auto-set option before this one) + or DEFAULT 0 (in other cases). + So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will + replace this value by TIMESTAMP_DNUN_FIELD or NONE later when information about all TIMESTAMP fields in table will be availiable. + + If we have TIMESTAMP NULL column without explicit DEFAULT value + we treat it as having DEFAULT NULL attribute. */ - new_field->unireg_check= on_update_value?Field::TIMESTAMP_UN_FIELD: - Field::TIMESTAMP_OLD_FIELD; + new_field->unireg_check= on_update_value ? + Field::TIMESTAMP_UN_FIELD : + (new_field->flags & NOT_NULL_FLAG ? + Field::TIMESTAMP_OLD_FIELD: + Field::NONE); } break; case FIELD_TYPE_DATE: // Old date type -- cgit v1.2.1 From 8fa6f37a2963ad95c985f09ae26e8ed301ea03b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Oct 2004 02:21:19 +0400 Subject: A fix for Bug#5748 "Prepared statement with BETWEEN and bigint values crashes mysqld": implementation for a generic item tree modifications registry. Every item tree modification which should be rolled back for subsequent execution of a prepared statement or stored procedure should be saved in the registry. All such modifications are rolled back at once during cleanup stage of PS. Actual fix for the bug just adds a call to register modifications to convert_constant_item. Post review fixes implemented. mysql-test/r/ps.result: A fix for bug#5748, test results fixed. mysql-test/t/ps.test: A test case for Bug#5748 "Prepared statement with BETWEEN and bigint values crashes mysqld" sql/item.cc: Fix for Bug#5748 "Prepared statement with BETWEEN and bigint values crashes mysqld": First step in removing up item-specific cleanups: now all such tree modifications should be done using the genericm mechanism implemented in this changeset. sql/item.h: Fix for Bug#5748 "Prepared statement with BETWEEN and bigint values crashes mysqld": no need for an item-specific change record any more. sql/item_cmpfunc.cc: A fix for Bug#5748 "Prepared statement with BETWEEN and bigint values crashes mysqld": register item tree transformation performed by convert_constant_item. sql/sql_class.cc: Implementation for item tree transformations registry. sql/sql_class.h: Declarations, necessary for the tree transformations registry. sql/sql_parse.cc: Assert that the item tree transformations registry is not used for conventional execution. sql/sql_prepare.cc: Use of the item tree modifications registry in prepared statements: rollback all modifications in the end of statement prepare and execute. Also we now always set thd->current_arena to be able to determine that this is an execution of prepared statement inside the registry code. tests/client_test.c: A typo fixed. --- sql/sql_parse.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 34cad1b062d..c5ca19ecba8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4056,6 +4056,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) } thd->proc_info="freeing items"; thd->end_statement(); + DBUG_ASSERT(thd->change_list.is_empty()); } DBUG_VOID_RETURN; } -- cgit v1.2.1 From 54b00f5453b49047142d59da21e19d607f4b208e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Oct 2004 02:53:59 +0400 Subject: A fix and test case for Bug#5985 ""prepare stmt from "select rand(?)" crashes server." The fix makes Item_func_rand prepared-statements aware plus it fixes the case when RAND is used in prepared statements and replication is on (as well as several similar issues). Until now we did not reset THD before every execution of a prepared statement, so if some execution had set thd->time_zone_used or thd->rand_used they would not be reset until next mysql_parse. Some of post-review fixes done. mysql-test/r/ps.result: A test case for Bug#5985: test results fixed. mysql-test/t/ps.test: A test case for Bug#5985 "prepare stmt from "select rand(?)" crashes server." sql/item_func.cc: Actual fix for Bug#5985: Item_func_rand rewritten to be prepared statements aware. sql/item_func.h: Actual fix for Bug#5985: Item_func_rand rewritten to be prepared statements aware. sql/mysql_priv.h: We need a separate call to reset THD state before every execute of a prepared statement. Otherwise things like THD->user_var_events are never cleaned up and bloat binary log (as the list of events grows from execution to execution). sql/sql_class.cc: Statement::end_statement -> THD::end_statement() (a leftover from some design change which is not to pushed now, but the leftover is to be pushed). sql/sql_class.h: Statement::end_statement -> THD::end_statement() (a leftover from some design change which is not to pushed now, but the leftover is to be pushed). sql/sql_lex.cc: Move the part responsible for initializing LEX from mysql_init_query to lex_start. sql/sql_lex.h: All lex-related initialization is now in lex_start. Move thd->select_number to lex->select_number to be able to use it easily in lex_start. sql/sql_parse.cc: Split mysql_init_query into two functions: mysql_reset_thd_for_next_query, which is used in PS and conventional execution, and lex_start, used only when we want to parse something. Fix init_connect to use initialized THD. sql/sql_prepare.cc: Deploy mysql_reset_thd_for_next_query to reset THD state before execution of a prepared statement. Normally this should have been added to just one place, but we have to reset thd before assigning placeholders from variables, thus we can't do that in execute_stmt (yuck). --- sql/sql_parse.cc | 57 ++++++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c5ca19ecba8..c9c4ed35dc7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1001,16 +1001,15 @@ pthread_handler_decl(handle_one_connection,arg) net->compress=1; // Use compression thd->version= refresh_version; + thd->proc_info= 0; + thd->set_time(); + thd->init_for_queries(); if (sys_init_connect.value_length && !(thd->master_access & SUPER_ACL)) { execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect); if (thd->query_error) thd->killed= 1; } - - thd->proc_info=0; - thd->set_time(); - thd->init_for_queries(); while (!net->error && net->vio != 0 && !thd->killed) { if (do_command(thd)) @@ -3854,7 +3853,6 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) return 0; } - /**************************************************************************** Initialize global thd variables needed for query ****************************************************************************/ @@ -3863,33 +3861,30 @@ void mysql_init_query(THD *thd, uchar *buf, uint length) { DBUG_ENTER("mysql_init_query"); - LEX *lex= thd->lex; - lex->unit.init_query(); - lex->unit.init_select(); - lex->unit.thd= thd; - lex->select_lex.init_query(); - lex->value_list.empty(); - lex->param_list.empty(); - lex->unit.next= lex->unit.master= - lex->unit.link_next= lex->unit.return_to=0; - lex->unit.prev= lex->unit.link_prev= 0; - lex->unit.slave= lex->unit.global_parameters= lex->current_select= - lex->all_selects_list= &lex->select_lex; - lex->select_lex.master= &lex->unit; - lex->select_lex.prev= &lex->unit.slave; - lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0; - lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); - lex->select_lex.options=0; - lex->describe= 0; - lex->derived_tables= FALSE; - lex->lock_option= TL_READ; - lex->found_colon= 0; - lex->safe_to_cache_query= 1; - lex->time_zone_tables_used= 0; lex_start(thd, buf, length); - thd->select_number= lex->select_lex.select_number= 1; - thd->free_list= 0; - thd->total_warn_count=0; // Warnings for this query + mysql_reset_thd_for_next_command(thd); + DBUG_VOID_RETURN; +} + + +/* + Reset THD part responsible for command processing state. + + DESCRIPTION + This needs to be called before execution of every statement + (prepared or conventional). + + TODO + Make it a method of THD and align its name with the rest of + reset/end/start/init methods. + Call it after we use THD for queries, not before. +*/ + +void mysql_reset_thd_for_next_command(THD *thd) +{ + DBUG_ENTER("mysql_reset_thd_for_next_command"); + thd->select_number= 1; + thd->total_warn_count= 0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->sent_row_count= thd->examined_row_count= 0; thd->is_fatal_error= thd->rand_used= thd->time_zone_used= 0; -- cgit v1.2.1 From 761ae02ca77722f34744a912315d52a0c0f7fca6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Oct 2004 03:37:20 +0400 Subject: Followup to Bug#5985: fixing one thing that went wrong. --- sql/sql_parse.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c9c4ed35dc7..e7a013e19ea 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3883,6 +3883,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length) void mysql_reset_thd_for_next_command(THD *thd) { DBUG_ENTER("mysql_reset_thd_for_next_command"); + thd->free_list= 0; thd->select_number= 1; thd->total_warn_count= 0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; -- cgit v1.2.1 From 8141b058ff58ce58079efb02a5b2d730a1b46c81 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Oct 2004 15:47:00 +0300 Subject: we can't rely on current variables implementation, so have to use String pointer returned by val_str fixed handling errors in case of out of memory in SQL interfase of prepared statements --- sql/sql_parse.cc | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e7a013e19ea..44b0049529e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2005,6 +2005,7 @@ mysql_execute_command(THD *thd) CHARSET_INFO *to_cs= thd->variables.collation_connection; bool need_conversion; user_var_entry *entry; + String *pstr= &str; uint32 unused; /* Convert @var contents to string in connection character set. Although @@ -2020,26 +2021,43 @@ mysql_execute_command(THD *thd) String *pstr; my_bool is_var_null; pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); + /* + NULL value of variable checked early as entry->value so here + we can't get NULL in normal conditions + */ DBUG_ASSERT(!is_var_null); if (!pstr) - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_ASSERT(pstr == &str); + { + res= -1; + break; // EOM (error should be reported by allocator) + } } else + { + /* + variable absent or equal to NULL, so we need to set variable to + something reasonable to get readable error message during parsing + */ str.set("NULL", 4, &my_charset_latin1); + } + need_conversion= - String::needs_conversion(str.length(), str.charset(), to_cs, &unused); + String::needs_conversion(pstr->length(), pstr->charset(), + to_cs, &unused); - query_len= need_conversion? (str.length() * to_cs->mbmaxlen) : - str.length(); + query_len= need_conversion? (pstr->length() * to_cs->mbmaxlen) : + pstr->length(); if (!(query_str= alloc_root(&thd->mem_root, query_len+1))) - send_error(thd, ER_OUT_OF_RESOURCES); + { + res= -1; + break; // EOM (error should be reported by allocator) + } if (need_conversion) - query_len= copy_and_convert(query_str, query_len, to_cs, str.ptr(), - str.length(), str.charset()); + query_len= copy_and_convert(query_str, query_len, to_cs, pstr->ptr(), + pstr->length(), pstr->charset()); else - memcpy(query_str, str.ptr(), str.length()); + memcpy(query_str, pstr->ptr(), pstr->length()); query_str[query_len]= 0; } else -- cgit v1.2.1 From 3307318917fb2995eaed4fa8530613cba08ea341 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Oct 2004 18:03:46 +0300 Subject: true,false -> TRUE, FALSE Simple fixes/optimization of things discovered during review of new pushed code include/my_sys.h: Ensure that clear_alloc_root() interacts correctly with alloc_root_inited() mysys/hash.c: More comments Simple optimization (merge identical code) mysys/my_bitmap.c: Change inline -> static inline sql/examples/ha_archive.cc: Fixed compiler warning sql/ha_ndbcluster.cc: true,false -> TRUE, FALSE Change if (false) -> #ifdef NOT_USED sql/ha_ndbcluster.h: true,false -> TRUE, FALSE sql/handler.cc: More comments Remove not needed initializations. #ifdef not used code sql/item_cmpfunc.h: true,false -> TRUE, FALSE sql/item_strfunc.cc: Move local variables to function beginning Remove wrong comments sql/log_event.h: true,false -> TRUE, FALSE sql/sql_base.cc: true,false -> TRUE, FALSE More comments sql/sql_help.cc: true,false -> TRUE, FALSE sql/sql_lex.cc: Simple optimization of new code sql/sql_parse.cc: true,false -> TRUE, FALSE sql/sql_prepare.cc: true,false -> TRUE, FALSE sql/sql_table.cc: true,false -> TRUE, FALSE sql/sql_yacc.yy: true,false -> TRUE, FALSE --- sql/sql_parse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c5ca19ecba8..731a728d730 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -894,7 +894,7 @@ static int check_connection(THD *thd) x_free(thd->user); if (!(thd->user= my_strdup(user, MYF(0)))) return (ER_OUT_OF_RESOURCES); - return check_user(thd, COM_CONNECT, passwd, passwd_len, db, true); + return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE); } @@ -4771,7 +4771,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, acl_reload(thd); grant_reload(thd); if (mqh_used) - reset_mqh(thd,(LEX_USER *) NULL,true); + reset_mqh(thd,(LEX_USER *) NULL,TRUE); } #endif if (options & REFRESH_LOG) -- cgit v1.2.1 From 07c7aadf444eeea8463eef2d31cfacd129620e8e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 17 Oct 2004 13:59:46 +0400 Subject: Fix for bug #6081 "Call to deprecated mysql_create_db() function crashes server". Altough mysql_create_db()/mysql_drop_db() API calls are deprecated since 4.0, they should not crash server and should not stall connection in case of errors. sql/sql_parse.cc: Handling of COM_CREATE_DB, COM_DROP_DB: mysql_create_db() requires from its second parameter to be non-zero. We also should call send_error() if mysql_create_db or mysql_drop_db return error (like we do it for SQL versions of these commands). tests/client_test.c: Added test for bug #6081 "Execution of deprecated mysql_create_db() crashes server". --- sql/sql_parse.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e7a013e19ea..7b182c4cfd9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1556,6 +1556,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CREATE_DB: // QQ: To be removed { char *db=thd->strdup(packet), *alias; + HA_CREATE_INFO create_info; statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); // null test to handle EOM @@ -1567,7 +1568,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_access(thd,CREATE_ACL,db,0,1,0)) break; mysql_log.write(thd,command,packet); - mysql_create_db(thd,(lower_case_table_names == 2 ? alias : db),0,0); + bzero(&create_info, sizeof(create_info)); + if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), + &create_info, 0) < 0) + send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } case COM_DROP_DB: // QQ: To be removed @@ -1588,7 +1592,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } mysql_log.write(thd,command,db); - mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0); + if (mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), + 0, 0) < 0) + send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } #ifndef EMBEDDED_LIBRARY -- cgit v1.2.1 From 4324519868ec94df1804fd1a0288b45f2ae90ad8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Oct 2004 11:54:33 +0300 Subject: fixed retsult code --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9e0853a370b..1fe9e5093eb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1765,7 +1765,7 @@ mysql_execute_command(void) if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name); - res=0; + res= 1; break; } if (!select_lex->db) -- cgit v1.2.1 From b88150c96edf457099922a7e0a11831160bc5a67 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Oct 2004 16:04:43 +0400 Subject: Fix for bug #6173 "One can circumvent missing UPDATE privilege if he has SELECT and INSERT privileges for table with primary key" Now we set lex->duplicates= DUP_UPDATE right in parser if INSERT has ON DUPLICATE KEY UPDATE clause, this simplifies insert_precheck() function (this also fixes a bug) and some other code. mysql-test/r/grant2.result: Added test for bug #6173 "One can circumvent missing UPDATE privilege if he has SELECT and INSERT privileges for table with primary key" mysql-test/t/grant2.test: Added test for bug #6173 "One can circumvent missing UPDATE privilege if he has SELECT and INSERT privileges for table with primary key" sql/mysql_priv.h: insert_precheck() don't need "update" parameter any longer since now we set lex->duplicates to DUP_UPDATE if INSERT has ON DUPLICATE KEY UPDATE clause. sql/sql_parse.cc: insert_precheck() don't need "update" parameter any longer since now we set lex->duplicates to DUP_UPDATE if INSERT has ON DUPLICATE KEY UPDATE clause, so it can determine whenever it is needed to require UPDATE_ACL by itself. Also calling of mysql_insert() is simplified. sql/sql_prepare.cc: insert_precheck() don't need "update" parameter any longer since now we set lex->duplicates to DUP_UPDATE if INSERT has ON DUPLICATE KEY UPDATE clause, so it can determine whenever it is needed to require UPDATE_ACL by itself. Also calling of mysql_insert() is simplified. sql/sql_yacc.yy: It is better to set Lex->duplicates= DUP_UPDATE right in parser if we have INSERT with ON DUPLICATE KEY UPDATE clause, rather doing this later. --- sql/sql_parse.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e7a013e19ea..4d596feaa55 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2682,12 +2682,11 @@ unsent_create_error: case SQLCOM_REPLACE: case SQLCOM_INSERT: { - my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); - if ((res= insert_precheck(thd, tables, update))) + if ((res= insert_precheck(thd, tables))) break; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, select_lex->item_list, lex->value_list, - (update ? DUP_UPDATE : lex->duplicates)); + lex->duplicates); if (thd->net.report_error) res= -1; break; @@ -5366,13 +5365,14 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) -1 error (message is not sent to user) */ -int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) +int insert_precheck(THD *thd, TABLE_LIST *tables) { LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); - ulong privilege= (lex->duplicates == DUP_REPLACE ? - INSERT_ACL | DELETE_ACL : INSERT_ACL | update); + ulong privilege= INSERT_ACL | + (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | + (lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0); if (check_one_table_access(thd, privilege, tables)) DBUG_RETURN(1); -- cgit v1.2.1 From 8537cf2f4ba91b7e08975842aba910d4debefc13 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Oct 2004 22:18:00 +0400 Subject: Fix for bug #6116 "SET time_zone := ... requires access to mysql.time_zone* tables". We are excluding implicitly used time zone tables from privilege checking. mysql-test/r/timezone2.result: Added test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone tables" mysql-test/t/timezone2.test: Added test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone tables" sql/sql_parse.cc: check_table_access(): we should avoid privilege checking for implicitly used time zone tables. sql/tztime.cc: Indicated dependancy between my_tz_get_table_list() function and my_tz_check_n_skip_implicit_tables() function. sql/tztime.h: Added my_tz_check_n_skip_implicit_tables() function which allows easily determine whenever we have found beggining of the list of implicitly used time zone tables and fast-forward to its end. --- sql/sql_parse.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index daa0bc1e063..9dd18f0f152 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3724,7 +3724,10 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, TABLE_LIST *org_tables=tables; for (; tables ; tables=tables->next) { - if (tables->derived || (tables->table && (int)tables->table->tmp_table)) + if (tables->derived || + (tables->table && (int)tables->table->tmp_table) || + my_tz_check_n_skip_implicit_tables(&tables, + thd->lex->time_zone_tables_used)) continue; if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) && thd->db) -- cgit v1.2.1 From d71efcfdd6205dac6210465c6a23ca698342cbea Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Oct 2004 08:54:14 +0200 Subject: sql_parse.cc: Bug#6167 One element missing in 'uc_update_queries[]' sql/sql_parse.cc: Bug#6167 One element missing in 'uc_update_queries[]' --- sql/sql_parse.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index daa0bc1e063..8279e32c8de 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -501,12 +501,17 @@ void free_max_user_conn(void) /* Mark all commands that somehow changes a table This is used to check number of updates / hour + + sql_command is actually set to SQLCOM_END sometimes + so we need the +1 to include it in the array. */ -char uc_update_queries[SQLCOM_END]; +char uc_update_queries[SQLCOM_END+1]; void init_update_queries(void) { + bzero((gptr) &uc_update_queries, sizeof(uc_update_queries)); + uc_update_queries[SQLCOM_CREATE_TABLE]=1; uc_update_queries[SQLCOM_CREATE_INDEX]=1; uc_update_queries[SQLCOM_ALTER_TABLE]=1; @@ -531,6 +536,7 @@ void init_update_queries(void) bool is_update_query(enum enum_sql_command command) { + DBUG_ASSERT(command >= 0 && command <= SQLCOM_END); return uc_update_queries[command]; } -- cgit v1.2.1 From dd126ba1a59b8bc9560fc5298ad11869611d7e4b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Oct 2004 19:27:43 +0400 Subject: Part of fix for bug #6081 "Call to deprecated mysql_create_db() function crashes server" (in 4.0 we fix only connection stalling in case of error, crash itself is fixed in 4.1, the test case for this code is also there). sql/sql_parse.cc: Handling of COM_CREATE_DB, COM_DROP_DB: We should call send_error() if mysql_create_db or mysql_drop_db return error (like we do it for SQL versions of these commands). --- sql/sql_parse.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9e0853a370b..7c21a5af2a6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1142,7 +1142,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(thd,command,packet); - mysql_create_db(thd,(lower_case_table_names == 2 ? alias : db),0,0); + if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), + 0, 0) < 0) + send_error(&thd->net, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } case COM_DROP_DB: // QQ: To be removed @@ -1163,7 +1165,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } mysql_log.write(thd,command,db); - mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0); + if (mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), + 0, 0) < 0) + send_error(&thd->net, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } case COM_BINLOG_DUMP: -- cgit v1.2.1 From bc6652db9b1f5f302648c3a920fb1fa25449a6d8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Oct 2004 18:44:51 +0300 Subject: Fix compiler warnings (detected by Intel's C++ compiler) Fixed checking of privilege handling in CREATE ... SELECT (Bug #6094) client/mysql.cc: Fix compiler warnings client/mysqltest.c: Fix wrong counting of lines Remove compiler warnings heap/hp_hash.c: Fix compiler warnings innobase/dict/dict0load.c: Fix compiler warnings innobase/include/mem0mem.h: Fix compiler warnings libmysql/client_settings.h: Fix compiler warnings myisam/ft_nlq_search.c: Add comments about compiler warnings myisam/rt_index.c: Add comments about compiler warnings myisam/rt_mbr.c: Add comments about compiler warnings mysql-test/r/ps.result: Test case for bug#6094 mysql-test/t/ps.test: Test case for bug#6094 mysys/hash.c: Fix compiler warnings mysys/my_handler.c: Add comments about compiler warnings mysys/my_thr_init.c: Add comments about compiler warnings ndb/include/mgmapi/mgmapi.h: Fix compiler warnings regex/main.c: Fix compiler warnings sql/item.h: Fix compiler warnings sql/item_func.h: Add comments about compiler warnings sql/spatial.h: Add comments about compiler warnings sql/sql_lex.h: Fix compiler warning sql/sql_list.h: Fix compiler warning sql/sql_parse.cc: Move testing of access rights of tables in CREATE ... SELECT to create_table_precheck() to fix privilege checking in CREATE ... SELECT (Bug #6094) sql/sql_prepare.cc: Remove not needed empty line sql/sql_string.h: Fix compiler warnings strings/ctype-mb.c: Fix compiler warnings --- sql/sql_parse.cc | 85 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 33 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8279e32c8de..bb25fd57d0e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1862,8 +1862,8 @@ mysql_execute_command(THD *thd) { int res= 0; LEX *lex= thd->lex; - TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; SELECT_LEX *select_lex= &lex->select_lex; + TABLE_LIST *tables= (TABLE_LIST*) select_lex->table_list.first; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); @@ -2333,30 +2333,6 @@ mysql_execute_command(THD *thd) { select_result *result; - if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && - find_real_table_in_list(tables, create_table->db, - create_table->real_name)) - { - net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); - goto create_error; - } - if (lex->create_info.used_fields & HA_CREATE_USED_UNION) - { - TABLE_LIST *tab; - for (tab= tables; tab; tab= tab->next) - { - if (find_real_table_in_list((TABLE_LIST*) lex->create_info. - merge_list.first, - tables->db, tab->real_name)) - { - net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); - goto create_error; - } - } - } - - if (tables && check_table_access(thd, SELECT_ACL, tables,0)) - goto create_error; // Error message is given select_lex->options|= SELECT_NO_UNLOCK; unit->offset_limit_cnt= select_lex->offset_limit; unit->select_limit_cnt= select_lex->select_limit+ @@ -5282,7 +5258,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) INSERT ... SELECT query pre-check SYNOPSIS - multi_delete_precheck() + insert_delete_precheck() thd Thread handler tables Global table list @@ -5404,26 +5380,69 @@ int insert_precheck(THD *thd, TABLE_LIST *tables) RETURN VALUE 0 OK 1 Error (message is sent to user) - -1 Error (message is not sent to user) */ int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table) { LEX *lex= thd->lex; + SELECT_LEX *select_lex= &lex->select_lex; + ulong want_priv; + int error= 1; // Error message is given DBUG_ENTER("create_table_precheck"); - ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? - CREATE_TMP_ACL : CREATE_ACL); + + want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? + CREATE_TMP_ACL : CREATE_ACL); lex->create_info.alias= create_table->alias; if (check_access(thd, want_priv, create_table->db, &create_table->grant.privilege, 0, 0) || check_merge_table_access(thd, create_table->db, (TABLE_LIST *) lex->create_info.merge_list.first)) - DBUG_RETURN(1); - DBUG_RETURN((grant_option && want_priv != CREATE_TMP_ACL && - check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) ? - 1 : 0); + goto err; + if (grant_option && want_priv != CREATE_TMP_ACL && + check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) + goto err; + + if (select_lex->item_list.elements) + { + /* Check permissions for used tables in CREATE TABLE ... SELECT */ + + /* + For temporary tables or PREPARED STATEMETNS we don't have to check + if the created table exists + */ + if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && + ! thd->current_arena->is_stmt_prepare() && + find_real_table_in_list(tables, create_table->db, + create_table->real_name)) + { + net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); + + goto err; + } + if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + { + TABLE_LIST *tab; + for (tab= tables; tab; tab= tab->next) + { + if (find_real_table_in_list((TABLE_LIST*) lex->create_info. + merge_list.first, + tables->db, tab->real_name)) + { + net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + goto err; + } + } + } + + if (tables && check_table_access(thd, SELECT_ACL, tables,0)) + goto err; + } + error= 0; + +err: + DBUG_RETURN(error); } -- cgit v1.2.1 From af84ae00975493858043ea0452d84494c30be7b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Oct 2004 19:50:31 +0300 Subject: After merge fixes --- sql/sql_parse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e9ec5022db0..d712d3948d7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1575,7 +1575,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_log.write(thd,command,packet); if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0) < 0) - send_error(&thd->net, thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } case COM_DROP_DB: // QQ: To be removed @@ -1598,7 +1598,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_log.write(thd,command,db); if (mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0) < 0) - send_error(&thd->net, thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); break; } #ifndef EMBEDDED_LIBRARY -- cgit v1.2.1 From be6e299abb4e35657be1c2aeb1d91bd67802d0a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Oct 2004 20:33:10 +0200 Subject: added missing command names to command_name[] array --- sql/sql_parse.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8279e32c8de..00f8f09af0d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -63,9 +63,10 @@ const char *any_db="*any*"; // Special symbol for check_access const char *command_name[]={ "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB", "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist", - "Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user", + "Connect","Kill","Debug","Ping","Time","Delayed insert","Change user", "Binlog Dump","Table Dump", "Connect Out", "Register Slave", "Prepare", "Prepare Execute", "Long Data", "Close stmt", + "Reset stmt", "Set option", "Error" // Last command number }; -- cgit v1.2.1 From ba82d5b1f143e28f43ebe388cc7f31a457b3b8e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 24 Oct 2004 11:54:58 +0300 Subject: removed unneed variable --- sql/sql_parse.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e407865f715..fd037ac2da4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2031,7 +2031,6 @@ mysql_execute_command(THD *thd) lex->prepared_stmt_code.length)) && entry->value) { - String *pstr; my_bool is_var_null; pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); /* -- cgit v1.2.1 From 712326d6846ae718bf5c7c5961ec3173bbf29b06 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Oct 2004 17:51:26 +0500 Subject: Bug#6202: ENUMs are not case sensitive even if declared BINARY --- sql/sql_parse.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fd037ac2da4..dfe6fc049e0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4090,6 +4090,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) } #endif + /***************************************************************************** ** Store field definition for create ** Return 0 if ok @@ -4405,10 +4406,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->pack_length=8; new_field->interval=interval; new_field->length=0; - for (const char **pos=interval->type_names; *pos ; pos++) + uint *lengths; + const char **pos; + for (pos=interval->type_names, + lengths= interval->type_lengths; *pos ; pos++, lengths++) { - uint length= (uint) strip_sp((char*) *pos)+1; CHARSET_INFO *cs= thd->variables.character_set_client; + uint length= (uint) strip_sp((char*) *pos)+1; + set_if_smaller(*lengths, length); length= cs->cset->numchars(cs, *pos, *pos+length); new_field->length+= length; } @@ -4438,10 +4443,15 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->interval=interval; new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe new_field->length=(uint) strip_sp((char*) interval->type_names[0]); - for (const char **pos=interval->type_names+1; *pos ; pos++) + set_if_smaller(interval->type_lengths[0], new_field->length); + uint *lengths; + const char **pos; + for (pos= interval->type_names+1, + lengths= interval->type_lengths+1; *pos ; pos++, lengths++) { - uint length=(uint) strip_sp((char*) *pos); CHARSET_INFO *cs= thd->variables.character_set_client; + uint length=(uint) strip_sp((char*) *pos); + set_if_smaller(*lengths, length); length= cs->cset->numchars(cs, *pos, *pos+length); set_if_bigger(new_field->length,length); } -- cgit v1.2.1 From 52da7eb858bc680280cce9c67a8ebcc25f3985ba Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Oct 2004 09:13:52 +0500 Subject: Reuse more code: two equal pieces for ENUM and SET where moved into a function. --- sql/sql_parse.cc | 59 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index dfe6fc049e0..61049360b93 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4091,6 +4091,31 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) #endif +/* + Calculate interval lengths. + Strip trailing spaces from all strings. + After this function call: + - ENUM uses max_length + - SET uses tot_length. +*/ +void calculate_interval_lengths(THD *thd, TYPELIB *interval, + uint *max_length, uint *tot_length) +{ + const char **pos; + uint *len; + CHARSET_INFO *cs= thd->variables.character_set_client; + *max_length= *tot_length= 0; + for (pos= interval->type_names, len= interval->type_lengths; + *pos ; pos++, len++) + { + *len= (uint) strip_sp((char*) *pos); + uint length= cs->cset->numchars(cs, *pos, *pos + *len); + *tot_length+= length; + set_if_bigger(*max_length, length); + } +} + + /***************************************************************************** ** Store field definition for create ** Return 0 if ok @@ -4405,19 +4430,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (new_field->pack_length > 4) new_field->pack_length=8; new_field->interval=interval; - new_field->length=0; - uint *lengths; - const char **pos; - for (pos=interval->type_names, - lengths= interval->type_lengths; *pos ; pos++, lengths++) - { - CHARSET_INFO *cs= thd->variables.character_set_client; - uint length= (uint) strip_sp((char*) *pos)+1; - set_if_smaller(*lengths, length); - length= cs->cset->numchars(cs, *pos, *pos+length); - new_field->length+= length; - } - new_field->length--; + uint dummy_max_length; + calculate_interval_lengths(thd, interval, + &dummy_max_length, &new_field->length); + new_field->length+= (interval->count - 1); set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) { @@ -4442,19 +4458,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { new_field->interval=interval; new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe - new_field->length=(uint) strip_sp((char*) interval->type_names[0]); - set_if_smaller(interval->type_lengths[0], new_field->length); - uint *lengths; - const char **pos; - for (pos= interval->type_names+1, - lengths= interval->type_lengths+1; *pos ; pos++, lengths++) - { - CHARSET_INFO *cs= thd->variables.character_set_client; - uint length=(uint) strip_sp((char*) *pos); - set_if_smaller(*lengths, length); - length= cs->cset->numchars(cs, *pos, *pos+length); - set_if_bigger(new_field->length,length); - } + + uint dummy_tot_length; + calculate_interval_lengths(thd, interval, + &new_field->length, &dummy_tot_length); set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) { -- cgit v1.2.1 From e948154c8a7c608afbc763ba6c7a7e6c710421f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Oct 2004 13:17:37 +0500 Subject: Bug 6206: ENUMs are not case sensitive even if declared BINARY The same problem with SET columns: find_set() now executes find_type2() to do charset aware search, instead of always using system_charset_info comparison. --- sql/sql_parse.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 61049360b93..0750403aef5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4444,8 +4444,9 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, thd->cuted_fields=0; String str,*res; res=default_value->val_str(&str); - (void) find_set(interval, res->ptr(), res->length(), ¬_used, - ¬_used2, ¬_used3); + (void) find_set(interval, res->ptr(), res->length(), + &my_charset_bin, + ¬_used, ¬_used2, ¬_used3); if (thd->cuted_fields) { net_printf(thd,ER_INVALID_DEFAULT,field_name); -- cgit v1.2.1 From 853c2c788c8bd7120a95c2357de7dabb1b6fcf3b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Oct 2004 19:30:01 +0300 Subject: A lot of fixes for prepared statements (PS): New mysqltest that can run mysqltest with PS Added support for ZEROFILL in PS Fixed crash when one called mysql_stmt_store_result() without a preceding mysql_stmt_bind_result() Updated test cases to support --ps-protocol (Some tests are still run using old protocol) Fixed crash in PS when using SELECT * FROM t1 NATURAL JOIN t2... Fixed crash in PS when using sub queries Create table didn't signal when table was created. This could cause a "DROP TABLE created_table" in another thread to wait "forever" Fixed wrong permissions check in PS and multi-table updates (one could get permission denied for legal quries) Fix for PS and SELECT ... PROCEDURE Reset all warnings when executing a new PS query group_concat(...ORDER BY) didn't work with PS Fixed problem with test suite when not using innodb BitKeeper/deleted/.del-innodb-lock-master.opt~f76a4a1999728f87: Delete: mysql-test/t/innodb-lock-master.opt client/Makefile.am: mysqltest now uses regex client/mysqltest.c: Added support for testing of prepared statements (with --ps-protocol) Main code was done by Kent, I did mainly some cleanups and minor bug fixes New test commands: --disable_ps_protocol --enable_ps_protocol NOTE: new code still has some things that needs to be cleaned up. For example run_query_stmt_handle_error() should be made more general so that same code can be used also by 'normal' queries configure.in: mysqltest now uses regex libmysql/libmysql.c: Reset warning_count after prepare (safety). In the future we should also provide warnings on prepare integer -> string conversion now handles ZEROFILL double -> string conversion is now closer to the one in the server Fixed crash when one called mysql_stmt_store_result() without preceding mysql_stmt_bind_result() libmysqld/examples/Makefile.am: mysqltest now uses regex mysql-test/include/have_query_cache.inc: Fixes for --ps-protocol mysql-test/include/ps_conv.inc: Fixes for --ps-protocol mysql-test/mysql-test-run.sh: Added options --ps-protocol mysql-test/r/ctype_utf8.result: Fixed test case mysql-test/r/fulltext_cache.result: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/r/fulltext_left_join.result: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/r/fulltext_multi.result: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/r/innodb-lock.result: Fixed test to work even if Innodb is not compiled in. mysql-test/t/create.test: Fixes for --ps-protocol mysql-test/t/ctype_utf8.test: Remove warnings mysql-test/t/date_formats.test: Fixes for --ps-protocol mysql-test/t/fulltext_cache.test: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/t/fulltext_left_join.test: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/t/fulltext_multi.test: Changed output of MATCH to use round() to get same numbers with --ps-protocol mysql-test/t/func_group.test: Fixes for --ps-protocol mysql-test/t/func_sapdb.test: Fixes for --ps-protocol mysql-test/t/innodb-lock.test: Fixed test to work even if Innodb is not compiled in. mysql-test/t/insert.test: Fixes for --ps-protocol mysql-test/t/insert_select.test: Fixes for --ps-protocol mysql-test/t/insert_update.test: Fixes for --ps-protocol mysql-test/t/metadata.test: Fixes for --ps-protocol mysql-test/t/multi_statement.test: Fixes for --ps-protocol mysql-test/t/ps_1general.test: Fixes for --ps-protocol mysql-test/t/rollback.test: Fixes for --ps-protocol mysql-test/t/rpl_redirect.test: Fixes for --ps-protocol mysql-test/t/rpl_user_variables.test: Fixes for --ps-protocol mysql-test/t/select.test: Fixes for --ps-protocol mysql-test/t/status.test: Fixes for --ps-protocol mysql-test/t/type_blob.test: Fixes for --ps-protocol mysql-test/t/type_float.test: Fixes for --ps-protocol mysql-test/t/union.test: Fixes for --ps-protocol mysql-test/t/warnings.test: Fixes for --ps-protocol mysys/my_alloc.c: More debugging information sql-common/client.c: More debugging information sql-common/my_time.c: TIME didn't support full range with PS sql/field.cc: TIME didn't support full range with PS sql/item_cmpfunc.cc: IN(constants,...) didn't work with PS sql/item_subselect.cc: Some subqueries didn't work with PS sql/item_sum.cc: group_concat(...ORDER BY) didn't work with PS Removed variable warning_available as 'warning' can be used for this. sql/item_sum.h: Removed not needed variable sql/protocol.cc: TIME didn't support full range with PS sql/set_var.cc: Style fix sql/sql_base.cc: setup_wild() didn't properly restore old arena, which caused core dump in PS when using SELECT * FROM t1 NATURAL JOIN t2... sql/sql_class.cc: Style fix sql/sql_error.cc: Style fix sql/sql_insert.cc: Create table didn't signal when table was created. This could cause a "DROP TABLE created_table" in another thread to wait "forever" sql/sql_lex.h: Fix for PS and procedures sql/sql_parse.cc: More debugging information Make a copy of 'db' in PS as this may change Fixed wrong permissions check in PS and multi-table updates sql/sql_prepare.cc: Fix for PS and SELECT ... PROCEDURE Reset all warnings when executing a new query sql/sql_union.cc: Fixes for PS and SELECT ... PROCEDURE Reset 'with_wild' as 'wild' is resolved on prepare --- sql/sql_parse.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a01b8c895c3..e727eced38f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3590,8 +3590,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool dont_check_global_grants, bool no_errors) { DBUG_ENTER("check_access"); - DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access, - thd->master_access)); + DBUG_PRINT("enter",("db: '%s' want_access: %lu master_access: %lu", + db ? db : "", want_access, thd->master_access)); #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; #endif @@ -3645,7 +3645,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, thd->priv_user, db, test(want_access & GRANT_ACL)); else db_access=thd->db_access; - // Remove SHOW attribute and access rights we already have + DBUG_PRINT("info",("db_access: %lu", db_access)); + /* Remove SHOW attribute and access rights we already have */ want_access &= ~(thd->master_access | EXTRA_ACL); db_access= ((*save_priv=(db_access | thd->master_access)) & want_access); @@ -4617,6 +4618,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->db= empty_c_string; ptr->db_length= 0; } + if (thd->current_arena->is_stmt_prepare()) + ptr->db= thd->strdup(ptr->db); ptr->alias= alias_str; if (lower_case_table_names && table->table.length) @@ -5142,9 +5145,12 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) */ for (table= update_list; table; table= table->next) { - if ((check_access(thd, UPDATE_ACL, table->db, - &table->grant.privilege, 0, 1) || - grant_option && check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && + if (table->derived) + table->grant.privilege= SELECT_ACL; + else if ((check_access(thd, UPDATE_ACL, table->db, + &table->grant.privilege, 0, 1) || + grant_option && + check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) @@ -5162,6 +5168,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) */ if (&lex->select_lex != lex->all_selects_list) { + DBUG_PRINT("info",("Checking sub query list")); for (table= tables; table; table= table->next) { if (table->table_in_update_from_clause) @@ -5174,7 +5181,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (table->table_list) table->grant= table->table_list->grant; } - else + else if (!table->derived) { if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || -- cgit v1.2.1