diff options
Diffstat (limited to 'sql')
73 files changed, 1020 insertions, 567 deletions
diff --git a/sql/field.cc b/sql/field.cc index d26534b5ac7..1e926c0926e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2933,10 +2933,10 @@ int Field_timestamp::store(longlong nr) { long not_used; - if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1) + if (!(timestamp= my_gmt_sec(&l_time, ¬_used))) goto err; - timestamp= my_gmt_sec(&l_time, ¬_used); } + #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -5644,8 +5644,7 @@ create_field::create_field(Field *old_field,Field *orig_field) interval=0; def=0; if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) && - old_field->type() != FIELD_TYPE_TIMESTAMP && old_field->ptr && - orig_field) + old_field->ptr && orig_field) { char buff[MAX_FIELD_WIDTH],*pos; String tmp(buff,sizeof(buff), charset); diff --git a/sql/field.h b/sql/field.h index b62b7a7859e..90e78c5421a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -643,7 +643,10 @@ public: void set_time(); virtual void set_default() { - set_time(); + if (table->timestamp_field == this) + set_time(); + else + Field::set_default(); } inline long get_timestamp() { @@ -679,6 +682,7 @@ public: String *val_str(String*,String *); bool send_binary(Protocol *protocol); void sql_type(String &str) const; + bool store_for_compare() { return 1; } field_cast_enum field_cast_type() { return FIELD_CAST_YEAR; } }; diff --git a/sql/filesort.cc b/sql/filesort.cc index 43a99a36287..064e92b7888 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -56,17 +56,38 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield, static void unpack_addon_fields(struct st_sort_addon_field *addon_field, byte *buff); - /* - Creates a set of pointers that can be used to read the rows - in sorted order. This should be done with the functions - in records.cc +/* + Sort a table - Before calling filesort, one must have done - table->file->info(HA_STATUS_VARIABLE) + SYNOPSIS + filesort() + table Table to sort + sortorder How to sort the table + s_length Number of elements in sortorder + select condition to apply to the rows + special Not used. + (This could be used to sort the rows pointed on by + select->file) + examined_rows Store number of examined rows here + + IMPLEMENTATION + Creates a set of pointers that can be used to read the rows + in sorted order. This should be done with the functions + in records.cc + + REQUIREMENTS + Before calling filesort, one must have done + table->file->info(HA_STATUS_VARIABLE) - The result set is stored in table->io_cache or - table->record_pointers - */ + RETURN + HA_POS_ERROR Error + # Number of rows + + examined_rows will be set to number of examined rows + + The result set is stored in table->io_cache or + table->record_pointers +*/ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, SQL_SELECT *select, ha_rows max_rows, ha_rows *examined_rows) @@ -794,7 +815,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek, rec_length)); if (error == -1) - goto err; /* purecov: inspected */ + goto err; /* purecov: inspected */ + buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected queue_insert(&queue, (byte*) buffpek); } diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index e87e31708f3..0dccab0c9d3 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -547,7 +547,10 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) (*ptr)->set_bt_compare(*ptr, berkeley_cmp_packed_key); (*ptr)->app_private= (void*) (table->key_info+i); if (!(table->key_info[i].flags & HA_NOSAME)) + { + DBUG_PRINT("bdb",("Setting DB_DUP for key %u", i)); (*ptr)->set_flags(*ptr, DB_DUP); + } if ((error= txn_begin(db_env, 0, (DB_TXN**) &transaction, 0)) || (error=((*ptr)->open(*ptr, transaction, name_buff, part, DB_BTREE, open_mode, 0))) || @@ -1661,8 +1664,9 @@ void ha_berkeley::info(uint flag) share->rec_per_key[i]; } } - else if (flag & HA_STATUS_ERRKEY) - errkey=last_dup_key; + /* Don't return key if we got an error for the internal primary key */ + if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys) + errkey= last_dup_key; DBUG_VOID_RETURN; } @@ -1860,7 +1864,7 @@ static int create_sub_table(const char *table_name, const char *sub_name, int error; DB *file; DBUG_ENTER("create_sub_table"); - DBUG_PRINT("enter",("sub_name: %s",sub_name)); + DBUG_PRINT("enter",("sub_name: %s flags: %d",sub_name, flags)); if (!(error=db_create(&file, db_env, 0))) { @@ -1892,14 +1896,14 @@ int ha_berkeley::create(const char *name, register TABLE *form, char name_buff[FN_REFLEN]; char part[7]; uint index=1; - int error=1; + int error; DBUG_ENTER("ha_berkeley::create"); fn_format(name_buff,name,"", ha_berkeley_ext,2 | 4); /* Create the main table that will hold the real rows */ - if (create_sub_table(name_buff,"main",DB_BTREE,0)) - DBUG_RETURN(1); /* purecov: inspected */ + if ((error= create_sub_table(name_buff,"main",DB_BTREE,0))) + DBUG_RETURN(error); /* purecov: inspected */ primary_key=table->primary_key; /* Create the keys */ @@ -1908,10 +1912,10 @@ int ha_berkeley::create(const char *name, register TABLE *form, if (i != primary_key) { sprintf(part,"key%02d",index++); - if (create_sub_table(name_buff, part, DB_BTREE, - (table->key_info[i].flags & HA_NOSAME) ? 0 : - DB_DUP)) - DBUG_RETURN(1); /* purecov: inspected */ + if ((error= create_sub_table(name_buff, part, DB_BTREE, + (table->key_info[i].flags & HA_NOSAME) ? 0 : + DB_DUP))) + DBUG_RETURN(error); /* purecov: inspected */ } } @@ -1919,16 +1923,15 @@ int ha_berkeley::create(const char *name, register TABLE *form, /* Is DB_BTREE the best option here ? (QUEUE can't be used in sub tables) */ DB *status_block; - if (!db_create(&status_block, db_env, 0)) + if (!(error=(db_create(&status_block, db_env, 0)))) { - if (!status_block->open(status_block, NULL, name_buff, - "status", DB_BTREE, DB_CREATE, 0)) + if (!(error=(status_block->open(status_block, NULL, name_buff, + "status", DB_BTREE, DB_CREATE, 0)))) { char rec_buff[4+MAX_KEY*4]; uint length= 4+ table->keys*4; bzero(rec_buff, length); - if (!write_status(status_block, rec_buff, length)) - error=0; + error= write_status(status_block, rec_buff, length); status_block->close(status_block,0); } } @@ -1936,6 +1939,7 @@ int ha_berkeley::create(const char *name, register TABLE *form, } + int ha_berkeley::delete_table(const char *name) { int error; diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 39293717c27..aa0a7daeb43 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -88,10 +88,11 @@ class ha_berkeley: public handler public: ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), int_table_flags(HA_REC_NOT_IN_SEQ | - HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | - HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | - HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), + HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | + HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | + HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX | + HA_KEY_READ_WRONG_STR | HA_FILE_BASED), changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) { } diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index c1228cbd319..807b6e35a29 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -38,7 +38,10 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) HA_CREATE_INFO create_info; bzero(&create_info, sizeof(create_info)); if (!create(name, table, &create_info)) + { file= heap_open(name, mode); + implicit_emptied= 1; + } } ref_length= sizeof(HEAP_PTR); return (file ? 0 : 1); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 7796c063424..161b9fe6c32 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -290,7 +290,7 @@ convert_error_code_to_mysql( } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) { - return(HA_WRONG_CREATE_OPTION); + return(HA_ERR_ROW_IS_REFERENCED); } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) { @@ -552,7 +552,7 @@ innobase_query_caching_of_table_permitted( if (thd->variables.tx_isolation == ISO_SERIALIZABLE) { /* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every - plain SELECT */ + plain SELECT if AUTOCOMMIT is not on. */ return((my_bool)FALSE); } @@ -3467,7 +3467,7 @@ ha_innobase::create( /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, but we play safe here */ - return(HA_ERR_TO_BIG_ROW); + DBUG_RETURN(HA_ERR_TO_BIG_ROW); } /* Get the transaction associated with the current thd, or create one @@ -3681,6 +3681,7 @@ ha_innobase::delete_table( int error; trx_t* parent_trx; trx_t* trx; + THD *thd= current_thd; char norm_name[1000]; DBUG_ENTER("ha_innobase::delete_table"); @@ -3706,6 +3707,14 @@ ha_innobase::delete_table( trx->mysql_thd = current_thd; trx->mysql_query_str = &((*current_thd).query); + if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { + trx->check_foreigns = FALSE; + } + + if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) { + trx->check_unique_secondary = FALSE; + } + name_len = strlen(name); assert(name_len < 1000); @@ -4399,7 +4408,28 @@ ha_innobase::get_foreign_key_create_info(void) prebuilt->trx->op_info = (char*)""; return(str); -} +} + +/*********************************************************************** +Checks if a table is referenced by a foreign key. The MySQL manual states that +a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a +delete is then allowed internally to resolve a duplicate key conflict in +REPLACE, not an update. */ + +uint +ha_innobase::referenced_by_foreign_key(void) +/*========================================*/ + /* out: > 0 if referenced by a FOREIGN KEY */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + + if (dict_table_referenced_by_foreign_key(prebuilt->table)) { + + return(1); + } + + return(0); +} /*********************************************************************** Frees the foreign key create info for a table stored in InnoDB, if it is @@ -4617,11 +4647,17 @@ ha_innobase::external_lock( } if (trx->isolation_level == TRX_ISO_SERIALIZABLE - && prebuilt->select_lock_type == LOCK_NONE) { + && prebuilt->select_lock_type == LOCK_NONE + && (thd->options + & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { - /* To get serializable execution we let InnoDB + /* To get serializable execution, we let InnoDB conceptually add 'LOCK IN SHARE MODE' to all SELECTs - which otherwise would have been consistent reads */ + which otherwise would have been consistent reads. An + exception is consistent reads in the AUTOCOMMIT=1 mode: + we know that they are read-only transactions, and they + can be serialized also if performed as consistent + reads. */ prebuilt->select_lock_type = LOCK_S; } diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 2fa70f27128..229ca514eda 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -181,6 +181,7 @@ class ha_innobase: public handler int check(THD* thd, HA_CHECK_OPT* check_opt); char* update_table_comment(const char* comment); char* get_foreign_key_create_info(); + uint referenced_by_foreign_key(); void free_foreign_key_create_info(char* str); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 8025e5169c8..1763427e8d9 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -279,7 +279,7 @@ int ha_isam::create(const char *name, register TABLE *form, type=HA_KEYTYPE_BINARY; // Keep compiler happy if (!(recinfo= (N_RECINFO*) my_malloc((form->fields*2+2)*sizeof(N_RECINFO), MYF(MY_WME)))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); pos=form->key_info; for (i=0; i < form->keys ; i++, pos++) diff --git a/sql/ha_isam.h b/sql/ha_isam.h index 3cea79da3ea..0b8619e5f33 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -34,7 +34,7 @@ class ha_isam: public handler :handler(table), file(0), int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_KEY_READ_WRONG_STR | HA_DUPP_POS | - HA_NOT_DELETE_WITH_CACHE) + HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED) {} ~ha_isam() {} const char *table_type() const { return "ISAM"; } diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h index c936a15164a..e5846d20212 100644 --- a/sql/ha_isammrg.h +++ b/sql/ha_isammrg.h @@ -33,7 +33,7 @@ class ha_isammrg: public handler const char *table_type() const { return "MRG_ISAM"; } const char **bas_ext() const; ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | - HA_REC_NOT_IN_SEQ); } + HA_REC_NOT_IN_SEQ | HA_FILE_BASED); } ulong index_flags(uint idx) const { return HA_NOT_READ_PREFIX_LAST; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index c3fa434c32e..a87054333cb 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1205,7 +1205,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, ((table_arg->key_parts + table_arg->keys) * sizeof(HA_KEYSEG)), NullS))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); pos=table_arg->key_info; for (i=0; i < table_arg->keys ; i++, pos++) diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index e6297373fea..06663516011 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -46,7 +46,8 @@ class ha_myisam: public handler ha_myisam(TABLE *table): handler(table), file(0), int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | - HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY | HA_HAS_GEOMETRY), + HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY | + HA_FILE_BASED | HA_HAS_GEOMETRY), enable_activate_all_index(1) {} ~ha_myisam() {} diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 3cd5d96d5f3..b62c347a7bd 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -386,7 +386,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, if (!(table_names= (char**) thd->alloc((create_info->merge_list.elements+1)* sizeof(char*)))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); for (pos=table_names ; tables ; tables=tables->next) { char *table_name; @@ -399,7 +399,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, mysql_real_data_home, tables->db, tables->real_name); if (!(table_name= thd->strmake(buff, length))) - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } else table_name=(*tbl)->path; diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 008f5339caf..ea53b40739d 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -36,7 +36,7 @@ class ha_myisammrg: public handler { return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_BLOB_KEY); + HA_NULL_KEY | HA_BLOB_KEY | HA_FILE_BASED); } ulong index_flags(uint inx) const { diff --git a/sql/handler.cc b/sql/handler.cc index e9eecabaa84..5aa3967edb6 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -649,14 +649,23 @@ bool ha_flush_logs() int ha_delete_table(enum db_type table_type, const char *path) { + char tmp_path[FN_REFLEN]; handler *file=get_new_handler((TABLE*) 0, table_type); if (!file) return ENOENT; + if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) + { + /* Ensure that table handler get path in lower case */ + strmov(tmp_path, path); + my_casedn_str(system_charset_info, tmp_path); + path= tmp_path; + } int error=file->delete_table(path); delete file; return error; } + void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos) { switch (pack_length) { @@ -1134,6 +1143,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, { int error; TABLE table; + char name_buff[FN_REFLEN]; DBUG_ENTER("ha_create_table"); if (openfrm(name,"",0,(uint) READ_ALL, 0, &table)) @@ -1144,19 +1154,19 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, if (table.file->table_flags() & HA_DROP_BEFORE_CREATE) table.file->delete_table(name); // Needed for BDB tables } + if (lower_case_table_names == 2 && + !(table.file->table_flags() & HA_FILE_BASED)) + { + /* Ensure that handler gets name in lower case */ + strmov(name_buff, name); + my_casedn_str(system_charset_info, name_buff); + name= name_buff; + } + error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) - { - if (table.db_type == DB_TYPE_INNODB) - { - /* Creation of InnoDB table cannot fail because of an OS error: - put error as the number */ - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); - } - else - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno); - } + my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); DBUG_RETURN(error != 0); } diff --git a/sql/handler.h b/sql/handler.h index 36700695406..35a93709e98 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -70,12 +70,14 @@ #define HA_CAN_SQL_HANDLER (1 << 22) #define HA_NO_AUTO_INCREMENT (1 << 23) #define HA_HAS_CHECKSUM (1 << 24) - /* Next record gives next record according last record read (even if database is updated after read). Not used at this point. */ -#define HA_LASTKEY_ORDER (1 << 25) +#define HA_LASTKEY_ORDER (1 << 25) +/* Table data are stored in separate files */ +#define HA_FILE_BASED (1 << 26) + /* bits in index_flags(index_number) for what you can do with index */ @@ -167,8 +169,9 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { CHARSET_INFO *table_charset, *default_table_charset; - char *comment,*password; - char *data_file_name, *index_file_name; + const char *comment,*password; + const char *data_file_name, *index_file_name; + const char *alias; ulonglong max_rows,min_rows; ulonglong auto_increment_value; ulong table_options; @@ -230,6 +233,7 @@ public: uint raid_type,raid_chunks; FT_INFO *ft_handler; bool auto_increment_column_changed; + bool implicit_emptied; /* Can be !=0 only if HEAP */ handler(TABLE *table_arg) :table(table_arg), ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0), @@ -238,7 +242,7 @@ public: create_time(0), check_time(0), update_time(0), key_used_on_scan(MAX_KEY), active_index(MAX_REF_PARTS), ref_length(sizeof(my_off_t)), block_size(0), - raid_type(0), ft_handler(0) + raid_type(0), ft_handler(0), implicit_emptied(0) {} virtual ~handler(void) {} int ha_open(const char *name, int mode, int test_if_locked); @@ -337,6 +341,8 @@ public: virtual void append_create_info(String *packet) {} virtual char* get_foreign_key_create_info() { return(NULL);} /* gets foreign key create string from InnoDB */ + /* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */ + virtual uint referenced_by_foreign_key() { return 0;} virtual void init_table_handle_for_HANDLER() { return; } /* prepare InnoDB for HANDLER */ virtual void free_foreign_key_create_info(char* str) {} diff --git a/sql/item.cc b/sql/item.cc index 850d5a3cad3..eb2550fdbcc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -175,12 +175,13 @@ bool Item::eq(const Item *item, bool binary_cmp) const !my_strcasecmp(system_charset_info,name,item->name); } + bool Item_string::eq(const Item *item, bool binary_cmp) const { if (type() == item->type()) { if (binary_cmp) - return !sortcmp(&str_value, &item->str_value, &my_charset_bin); + return !stringcmp(&str_value, &item->str_value); return !sortcmp(&str_value, &item->str_value, collation.collation); } return 0; @@ -1825,7 +1826,7 @@ bool field_is_equal_to_item(Field *field,Item *item) if (item->null_value) return 1; // This must be true field->val_str(&field_tmp,&field_tmp); - return !sortcmp(&field_tmp,item_result,&my_charset_bin); + return !stringcmp(&field_tmp,item_result); } if (res_type == INT_RESULT) return 1; // Both where of type int diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4046a4d6414..1bba934cf8f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -293,6 +293,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name()); return 1; } + if (my_binary_compare(cmp_collation.collation)) + { + /* + We are using binary collation, change to compare byte by byte, + without removing end space + */ + if (func == &Arg_comparator::compare_string) + func= &Arg_comparator::compare_binary_string; + else if (func == &Arg_comparator::compare_e_string) + func= &Arg_comparator::compare_e_binary_string; + } } return 0; } @@ -313,6 +324,39 @@ int Arg_comparator::compare_string() return -1; } + +/* + Compare strings byte by byte. End spaces are also compared. + + RETURN + < 0 *a < *b + 0 *b == *b + > 0 *a > *b +*/ + +int Arg_comparator::compare_binary_string() +{ + String *res1,*res2; + if ((res1= (*a)->val_str(&owner->tmp_value1))) + { + if ((res2= (*b)->val_str(&owner->tmp_value2))) + { + owner->null_value= 0; + uint res1_length= res1->length(); + uint res2_length= res2->length(); + int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length)); + return cmp ? cmp : (int) (res1_length - res2_length); + } + } + owner->null_value= 1; + return -1; +} + + +/* + Compare strings, but take into account that NULL == NULL +*/ + int Arg_comparator::compare_e_string() { String *res1,*res2; @@ -324,6 +368,17 @@ int Arg_comparator::compare_e_string() } +int Arg_comparator::compare_e_binary_string() +{ + String *res1,*res2; + res1= (*a)->val_str(&owner->tmp_value1); + res2= (*b)->val_str(&owner->tmp_value2); + if (!res1 || !res2) + return test(res1 == res2); + return test(stringcmp(res1, res2) == 0); +} + + int Arg_comparator::compare_real() { double val1= (*a)->val(); @@ -2132,7 +2187,7 @@ longlong Item_func_regex::val_int() null_value=1; return 0; } - if (!regex_compiled || sortcmp(res2,&prev_regexp,&my_charset_bin)) + if (!regex_compiled || stringcmp(res2,&prev_regexp)) { prev_regexp.copy(*res2); if (regex_compiled) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7e1749ef7a0..3c70a50502a 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -63,10 +63,12 @@ public: inline int compare() { return (this->*func)(); } int compare_string(); // compare args[0] & args[1] + int compare_binary_string(); // compare args[0] & args[1] int compare_real(); // compare args[0] & args[1] int compare_int(); // compare args[0] & args[1] int compare_row(); // compare args[0] & args[1] int compare_e_string(); // compare args[0] & args[1] + int compare_e_binary_string(); // compare args[0] & args[1] int compare_e_real(); // compare args[0] & args[1] int compare_e_int(); // compare args[0] & args[1] int compare_e_row(); // compare args[0] & args[1] @@ -811,8 +813,6 @@ public: class Item_func_like :public Item_bool_func2 { - char escape; - // Turbo Boyer-Moore data bool canDoTurboBM; // pattern is '%abcd%' case const char* pattern; @@ -829,10 +829,11 @@ class Item_func_like :public Item_bool_func2 enum { alphabet_size = 256 }; public: + char escape; + Item_func_like(Item *a,Item *b, char* escape_arg) - :Item_bool_func2(a,b), escape(*escape_arg), canDoTurboBM(false), - pattern(0), pattern_len(0), bmGs(0), bmBc(0) - {} + :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), + bmGs(0), bmBc(0), escape(*escape_arg) {} longlong val_int(); enum Functype functype() const { return LIKE_FUNC; } optimize_type select_optimize() const; diff --git a/sql/item_func.cc b/sql/item_func.cc index 82ff9de4a56..0327204dbfd 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -785,7 +785,8 @@ double Item_func_pow::val() double Item_func_acos::val() { - double value=args[0]->val(); + // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) + volatile double value=args[0]->val(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(acos(value)); @@ -793,7 +794,8 @@ double Item_func_acos::val() double Item_func_asin::val() { - double value=args[0]->val(); + // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) + volatile double value=args[0]->val(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(asin(value)); diff --git a/sql/key.cc b/sql/key.cc index 639b1e535a6..d4499573e8e 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -182,9 +182,9 @@ int key_cmp(TABLE *table,const byte *key,uint idx,uint key_length) } if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH)) { - if (key_part->field->key_cmp(key, key_part->length+2)) + if (key_part->field->key_cmp(key, key_part->length+ HA_KEY_BLOB_LENGTH)) return 1; - length=key_part->length+2; + length=key_part->length+HA_KEY_BLOB_LENGTH; } else { diff --git a/sql/log_event.cc b/sql/log_event.cc index 1f20948aa82..a128b5809b2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -290,6 +290,8 @@ Log_event::Log_event(const char* buf, bool old_format) int Log_event::exec_event(struct st_relay_log_info* rli) { + DBUG_ENTER("Log_event::exec_event"); + /* rli is null when (as far as I (Guilhem) know) the caller is @@ -342,7 +344,7 @@ int Log_event::exec_event(struct st_relay_log_info* rli) rli->last_master_timestamp= when; } } - return 0; + DBUG_RETURN(0); } @@ -592,11 +594,13 @@ Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d", Log_event* Log_event::read_log_event(const char* buf, int event_len, const char **error, bool old_format) { + DBUG_ENTER("Log_event::read_log_event"); + if (event_len < EVENT_LEN_OFFSET || (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET)) { *error="Sanity check failed"; // Needed to free buffer - return NULL; // general sanity check - will fail on a partial read + DBUG_RETURN(NULL); // general sanity check - will fail on a partial read } Log_event* ev = NULL; @@ -658,16 +662,16 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len, if (!force_opt) { *error= "Found invalid event in binary log"; - return 0; + DBUG_RETURN(0); } ev= new Unknown_log_event(buf, old_format); #else *error= "Found invalid event in binary log"; - return 0; + DBUG_RETURN(0); #endif } ev->cached_event_len = event_len; - return ev; + DBUG_RETURN(ev); } #ifdef MYSQL_CLIENT @@ -949,6 +953,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) since we must store the pos of the END of the current log event (COMMIT). */ rli->event_len= get_event_len(); + thd->query_error= 0; // clear error + thd->clear_error(); if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { @@ -958,8 +964,6 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); - thd->query_error= 0; // clear error - thd->clear_error(); thd->variables.pseudo_thread_id= thread_id; // for temp tables /* @@ -1004,7 +1008,8 @@ Default database: '%s'", ignored_error_code(actual_error)) { DBUG_PRINT("info",("error ignored")); - thd->query_error = 0; + thd->query_error= 0; + thd->clear_error(); *rli->last_slave_error = 0; rli->last_slave_errno = 0; } @@ -1213,7 +1218,7 @@ void Load_log_event::pack_info(Protocol *protocol) 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''" 7 + // LOCAL 9 + // " REPLACE or IGNORE " - 11 + table_name_len + // "INTO TABLE table" + 13 + table_name_len*2 + // "INTO TABLE `table`" 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'" 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'" 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'" @@ -1244,42 +1249,25 @@ void Load_log_event::pack_info(Protocol *protocol) else if (sql_ex.opt_flags & IGNORE_FLAG) pos= strmov(pos, " IGNORE "); - pos= strmov(pos ,"INTO TABLE "); + pos= strmov(pos ,"INTO TABLE `"); memcpy(pos, table_name, table_name_len); pos+= table_name_len; - if (sql_ex.field_term_len) - { - pos= strmov(pos, " FIELDS TERMINATED BY "); - pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len); - } + /* We have to create all optinal fields as the default is not empty */ + pos= strmov(pos, "` FIELDS TERMINATED BY "); + pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len); + if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) + pos= strmov(pos, " OPTIONALLY "); + pos= strmov(pos, " ENCLOSED BY "); + pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len); - if (sql_ex.enclosed_len) - { - if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) - pos= strmov(pos, " OPTIONALLY "); - pos= strmov(pos, " ENCLOSED BY "); - pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len); - } - - if (sql_ex.escaped_len) - { - pos= strmov(pos, " ESCAPED BY "); - pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len); - } - - bool line_lexem_added= false; - if (sql_ex.line_term_len) - { - pos= strmov(pos, " LINES TERMINATED BY "); - pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len); - line_lexem_added= true; - } + pos= strmov(pos, " ESCAPED BY "); + pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len); + pos= strmov(pos, " LINES TERMINATED BY "); + pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len); if (sql_ex.line_start_len) { - if (!line_lexem_added) - pos= strmov(pos," LINES"); pos= strmov(pos, " STARTING BY "); pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len); } @@ -1368,7 +1356,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, num_fields(0),fields(0), field_lens(0),field_block_len(0), table_name(table_name_arg ? table_name_arg : ""), - db(db_arg), fname(ex->file_name) + db(db_arg), fname(ex->file_name), local_fname(FALSE) { time_t end_time; time(&end_time); @@ -1450,13 +1438,14 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, Load_log_event::Load_log_event(const char *buf, int event_len, bool old_format) - :Log_event(buf, old_format),num_fields(0),fields(0), - field_lens(0),field_block_len(0), - table_name(0),db(0),fname(0) + :Log_event(buf, old_format), num_fields(0), fields(0), + field_lens(0), field_block_len(0), + table_name(0), db(0), fname(0), local_fname(FALSE) { - if (!event_len) // derived class, will call copy_log_event() itself - return; - copy_log_event(buf, event_len, old_format); + DBUG_ENTER("Load_log_event"); + if (event_len) // derived class, will call copy_log_event() itself + copy_log_event(buf, event_len, old_format); + DBUG_VOID_RETURN; } @@ -1471,6 +1460,8 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, char* buf_end = (char*)buf + event_len; uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; const char* data_head = buf + header_len; + DBUG_ENTER("Load_log_event::copy_log_event"); + slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET); exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET); skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET); @@ -1483,19 +1474,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, get_data_body_offset()); if ((int) event_len < body_offset) - return 1; + DBUG_RETURN(1); /* Sql_ex.init() on success returns the pointer to the first byte after the sql_ex structure, which is the start of field lengths array. */ if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset, - buf_end, - buf[EVENT_TYPE_OFFSET] != LOAD_EVENT))) - return 1; - + buf_end, + buf[EVENT_TYPE_OFFSET] != LOAD_EVENT))) + DBUG_RETURN(1); + data_len = event_len - body_offset; if (num_fields > data_len) // simple sanity check against corruption - return 1; + DBUG_RETURN(1); for (uint i = 0; i < num_fields; i++) field_block_len += (uint)field_lens[i] + 1; @@ -1505,7 +1496,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, fname = db + db_len + 1; fname_len = strlen(fname); // null termination is accomplished by the caller doing buf[event_len]=0 - return 0; + DBUG_RETURN(0); } @@ -1523,6 +1514,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db) void Load_log_event::print(FILE* file, bool short_form, char* last_db, bool commented) { + DBUG_ENTER("Load_log_event::print"); if (!short_form) { print_header(file); @@ -1553,43 +1545,27 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db, else if (sql_ex.opt_flags & IGNORE_FLAG) fprintf(file," IGNORE "); - fprintf(file, "INTO TABLE %s ", table_name); - if (sql_ex.field_term) - { - fprintf(file, " FIELDS TERMINATED BY "); - pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len); - } - - if (sql_ex.enclosed) - { - if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) - fprintf(file," OPTIONALLY "); - fprintf(file, " ENCLOSED BY "); - pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len); - } + fprintf(file, "INTO TABLE `%s`", table_name); + fprintf(file, " FIELDS TERMINATED BY "); + pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len); + + if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) + fprintf(file," OPTIONALLY "); + fprintf(file, " ENCLOSED BY "); + pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len); - if (sql_ex.escaped) - { - fprintf(file, " ESCAPED BY "); - pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len); - } + fprintf(file, " ESCAPED BY "); + pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len); - bool line_lexem_added= false; - if (sql_ex.line_term) - { - fprintf(file," LINES TERMINATED BY "); - pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len); - line_lexem_added= true; - } + fprintf(file," LINES TERMINATED BY "); + pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len); + if (sql_ex.line_start) { - if (!line_lexem_added) - fprintf(file," LINES"); fprintf(file," STARTING BY "); pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len); } - if ((long) skip_lines > 0) fprintf(file, " IGNORE %ld LINES", (long) skip_lines); @@ -1610,6 +1586,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db, } fprintf(file, ";\n"); + DBUG_VOID_RETURN; } #endif /* MYSQL_CLIENT */ @@ -1664,8 +1641,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, { thd->db= (char*) rewrite_db(db); DBUG_ASSERT(thd->query == 0); - thd->query = 0; // Should not be needed - thd->query_error = 0; + thd->query= 0; // Should not be needed + thd->query_error= 0; + thd->clear_error(); /* We test replicate_*_db rules. Note that we have already prepared the file @@ -1875,8 +1853,11 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; uint ident_offset; + DBUG_ENTER("Rotate_log_event"); + if (event_len < header_size) - return; + DBUG_VOID_RETURN; + buf += header_size; if (old_format) { @@ -1895,8 +1876,9 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, ident_offset, (uint) ident_len, MYF(MY_WME)))) - return; + DBUG_VOID_RETURN; alloced = 1; + DBUG_VOID_RETURN; } @@ -2588,10 +2570,12 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex, char* block_arg, uint block_len_arg, bool using_trans) :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, using_trans), - fake_base(0),block(block_arg),block_len(block_len_arg), + fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg), file_id(thd_arg->file_id = mysql_bin_log.next_file_id()) { + DBUG_ENTER("Create_file_log_event"); sql_ex.force_new_format(); + DBUG_VOID_RETURN; } #endif /* !MYSQL_CLIENT */ @@ -2648,8 +2632,16 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, :Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0) { int block_offset; - if (copy_log_event(buf,len,old_format)) - return; + DBUG_ENTER("Create_file_log_event"); + + /* + We must make copy of 'buf' as this event may have to live over a + rotate log entry when used in mysqlbinlog + */ + if (!(event_buf= my_memdup(buf, len, MYF(MY_WME))) || + (copy_log_event(event_buf, len, old_format))) + DBUG_VOID_RETURN; + if (!old_format) { file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + @@ -2667,6 +2659,7 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, sql_ex.force_new_format(); inited_from_old = 1; } + DBUG_VOID_RETURN; } @@ -2819,11 +2812,13 @@ Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg, Append_block_log_event::Append_block_log_event(const char* buf, int len) :Log_event(buf, 0),block(0) { + DBUG_ENTER("Append_block_log_event"); if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD) - return; + DBUG_VOID_RETURN; file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET); block = (char*)buf + APPEND_BLOCK_EVENT_OVERHEAD; block_len = len - APPEND_BLOCK_EVENT_OVERHEAD; + DBUG_VOID_RETURN; } @@ -2886,6 +2881,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) char *p= slave_load_file_stem(fname, file_id, server_id); int fd; int error = 1; + DBUG_ENTER("Append_block_log_event::exec_event"); memcpy(p, ".data", 6); if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0) @@ -2903,7 +2899,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) err: if (fd >= 0) my_close(fd, MYF(0)); - return error ? error : Log_event::exec_event(rli); + DBUG_RETURN(error ? error : Log_event::exec_event(rli)); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index d615c0e361b..28d1f44df92 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -564,17 +564,19 @@ public: const char* fname; uint32 skip_lines; sql_ex_info sql_ex; + bool local_fname; /* fname doesn't point to memory inside Log_event::temp_buf */ void set_fname_outside_temp_buf(const char *afname, uint alen) { fname= afname; fname_len= alen; + local_fname= true; } /* fname doesn't point to memory inside Log_event::temp_buf */ int check_fname_outside_temp_buf() { - return fname < temp_buf || fname > temp_buf+ cached_event_len; + return local_fname; } #ifndef MYSQL_CLIENT @@ -883,6 +885,7 @@ protected: bool fake_base; public: char* block; + const char *event_buf; uint block_len; uint file_id; bool inited_from_old; @@ -904,7 +907,10 @@ public: #endif Create_file_log_event(const char* buf, int event_len, bool old_format); - ~Create_file_log_event() {} + ~Create_file_log_event() + { + my_free((char*) event_buf, MYF(MY_ALLOW_ZERO_PTR)); + } Log_event_type get_type_code() { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c79c942979a..5e265412be7 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -135,6 +135,9 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; /* Time handling defaults */ #define TIMESTAMP_MAX_YEAR 2038 #define YY_PART_YEAR 70 +#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1) +#define TIMESTAMP_MAX_VALUE 2145916799 +#define TIMESTAMP_MIN_VALUE 1 #define PRECISION_FOR_DOUBLE 53 #define PRECISION_FOR_FLOAT 24 @@ -831,7 +834,7 @@ extern ulong expire_logs_days; extern my_bool relay_log_purge; extern uint test_flags,select_errors,ha_open_options; extern uint protocol_version, mysqld_port, dropping_tables; -extern uint delay_key_write_options; +extern uint delay_key_write_options, lower_case_table_names; extern bool opt_endinfo, using_udf_functions, locked_in_memory; extern bool opt_using_transactions, mysql_embedded; extern bool using_update_log, opt_large_files; @@ -840,10 +843,10 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool volatile abort_loop, shutdown_in_progress, grant_option; extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; -extern my_bool opt_safe_show_db, opt_local_infile, lower_case_table_names; +extern my_bool opt_safe_show_db, opt_local_infile; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern my_bool opt_readonly; -extern my_bool opt_enable_named_pipe; +extern my_bool opt_enable_named_pipe, opt_sync_frm; extern my_bool opt_secure_auth; extern char *shared_memory_base_name, *mysqld_unix_port; extern bool opt_enable_shared_memory; @@ -1076,6 +1079,11 @@ inline void table_case_convert(char * name, uint length) my_casedn(files_charset_info, name, length); } +inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) +{ + return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); +} + Comp_creator *comp_eq_creator(bool invert); Comp_creator *comp_ge_creator(bool invert); Comp_creator *comp_gt_creator(bool invert); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 509c18d3dda..4feadd8ac20 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -149,7 +149,7 @@ int initgroups(const char *,unsigned int); typedef fp_except fp_except_t; #endif - /* We can't handle floating point expections with threads, so disable + /* We can't handle floating point exceptions with threads, so disable this on freebsd */ @@ -262,11 +262,11 @@ my_bool opt_reckless_slave = 0; my_bool opt_enable_named_pipe= 0, opt_debugging= 0; my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; my_bool opt_safe_user_create = 0, opt_no_mix_types = 0; -my_bool lower_case_table_names, opt_old_rpl_compat; my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; my_bool opt_log_slave_updates= 0; my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam; my_bool opt_readonly, use_temp_pool, relay_log_purge; +my_bool opt_sync_bdb_logs, opt_sync_frm; my_bool opt_secure_auth= 0; my_bool opt_short_log_format= 0; my_bool opt_log_queries_not_using_indexes= 0; @@ -274,6 +274,7 @@ volatile bool mqh_used = 0; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint delay_key_write_options, protocol_version; +uint lower_case_table_names; uint volatile thread_count, thread_running, kill_cached_threads, wake_thread; ulong back_log, connect_timeout, concurrency; @@ -1712,7 +1713,7 @@ static void start_signal_handler(void) (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR); - pthread_attr_setstacksize(&thr_attr, 129*1024); + pthread_attr_setstacksize(&thr_attr,thread_stack); #endif (void) pthread_mutex_lock(&LOCK_thread_count); @@ -2506,6 +2507,18 @@ int main(int argc, char **argv) #endif (void) thr_setconcurrency(concurrency); // 10 by default + /* + Ensure that lower_case_table_names is set on system where we have case + insensitive names. If this is not done the users MyISAM tables will + get corrupted if accesses with names of different case. + */ + if (!lower_case_table_names && + test_if_case_insensitive(mysql_real_data_home) == 1) + { + sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); + lower_case_table_names= 2; + } + select_thread=pthread_self(); select_thread_in_use=1; init_ssl(); @@ -3540,7 +3553,7 @@ enum options_mysqld OPT_DELAY_KEY_WRITE_ALL, OPT_SLOW_QUERY_LOG, OPT_DELAY_KEY_WRITE, OPT_CHARSETS_DIR, OPT_BDB_HOME, OPT_BDB_LOG, - OPT_BDB_TMP, OPT_BDB_NOSYNC, + OPT_BDB_TMP, OPT_BDB_SYNC, OPT_BDB_LOCK, OPT_BDB, OPT_BDB_NO_RECOVER, OPT_BDB_SHARED, OPT_MASTER_HOST, OPT_MASTER_USER, @@ -3580,7 +3593,7 @@ enum options_mysqld OPT_HAVE_NAMED_PIPE, OPT_DO_PSTACK, OPT_REPORT_HOST, OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT, - OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT, + OPT_SHOW_SLAVE_AUTH_INFO, OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE, OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE, @@ -3641,6 +3654,7 @@ enum options_mysqld OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE, + OPT_SYNC_FRM, OPT_BDB_NOSYNC, OPT_ENABLE_SHARED_MEMORY, OPT_SHARED_MEMORY_BASE_NAME, OPT_OLD_PASSWORDS, @@ -3679,8 +3693,14 @@ struct my_option my_long_options[] = {"bdb-no-recover", OPT_BDB_NO_RECOVER, "Don't try to recover Berkeley DB tables on start.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"bdb-no-sync", OPT_BDB_NOSYNC, "Don't synchronously flush logs.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-no-sync", OPT_BDB_NOSYNC, + "Disable synchronously flushing logs. This option is deprecated, use --skip-sync-bdb-logs or sync-bdb-logs=0 instead", + // (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sync-bdb-logs", OPT_BDB_SYNC, + "Synchronously flush logs. Enabled by default", + (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, + NO_ARG, 1, 0, 0, 0, 0, 0}, {"bdb-shared-data", OPT_BDB_SHARED, "Start Berkeley DB in multi-process mode.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -3688,6 +3708,9 @@ struct my_option my_long_options[] = (gptr*) &berkeley_tmpdir, (gptr*) &berkeley_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_BERKELEY_DB */ + {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", + (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, + 0, 0, 0, 0}, {"bdb", OPT_BDB, "Enable Berkeley DB (if this version of MySQL supports it). \ Disable with --skip-bdb (will save memory).", (gptr*) &opt_bdb, (gptr*) &opt_bdb, 0, GET_BOOL, NO_ARG, 1, 0, 0, @@ -3988,10 +4011,6 @@ master-ssl", (gptr*) &global_system_variables.old_passwords, (gptr*) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"old-rpl-compat", OPT_OLD_RPL_COMPAT, - "Use old LOAD DATA format in the binary log (don't save data in file).", - (gptr*) &opt_old_rpl_compat, (gptr*) &opt_old_rpl_compat, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef ONE_THREAD {"one-thread", OPT_ONE_THREAD, "Only use one thread (for debugging under Linux).", 0, 0, 0, GET_NO_ARG, @@ -4348,15 +4367,15 @@ replicating a LOAD DATA INFILE command.", (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG, REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, - "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.", + "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system", (gptr*) &lower_case_table_names, - (gptr*) &lower_case_table_names, 0, GET_BOOL, NO_ARG, + (gptr*) &lower_case_table_names, 0, GET_UINT, OPT_ARG, #ifdef FN_NO_CASE_SENCE 1 #else 0 #endif - , 0, 1, 0, 1, 0}, + , 0, 2, 0, 1, 0}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "Max packetlength to send/receive from to server.", (gptr*) &global_system_variables.max_allowed_packet, @@ -4568,7 +4587,7 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG, REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, {"read-only", OPT_READONLY, - "Make all tables readonly, with the expections for replications (slave) threads and users with the SUPER privilege.", + "Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege", (gptr*) &opt_readonly, (gptr*) &opt_readonly, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, @@ -4617,7 +4636,8 @@ The minimum value for this variable is 4096.", "The number of seconds the server waits for activity on a connection before closing it.", (gptr*) &global_system_variables.net_wait_timeout, (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, - REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT), + 0, 1, 0}, {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, "Binary logs will be rotated after expire-log-days days ", (gptr*) &expire_logs_days, @@ -5463,7 +5483,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } #ifdef HAVE_BERKELEY_DB case OPT_BDB_NOSYNC: - berkeley_env_flags|=DB_TXN_NOSYNC; + /* Deprecated option */ + opt_sync_bdb_logs= 0; + /* Fall through */ + case OPT_BDB_SYNC: + if (!opt_sync_bdb_logs) + berkeley_env_flags|= DB_TXN_NOSYNC; + else + berkeley_env_flags&= ~DB_TXN_NOSYNC; break; case OPT_BDB_NO_RECOVER: berkeley_init_flags&= ~(DB_RECOVER); @@ -5589,6 +5616,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), sf_malloc_quick=1; #endif break; + case OPT_LOWER_CASE_TABLE_NAMES: + lower_case_table_names= argument ? atoi(argument) : 1; + break; } return 0; } @@ -5779,18 +5809,6 @@ static void fix_paths(void) exit(1); } #endif /* HAVE_REPLICATION */ - - /* - Ensure that lower_case_table_names is set on system where we have case - insensitive names. If this is not done the users MyISAM tables will - get corrupted if accesses with names of different case. - */ - if (!lower_case_table_names && - test_if_case_insensitive(mysql_real_data_home) == 1) - { - sql_print_error("Warning: Setting lower_case_table_names=1 becasue file system %s is case insensitive", mysql_real_data_home); - lower_case_table_names= 1; - } } @@ -5798,7 +5816,7 @@ static void fix_paths(void) set how many open files we want to be able to handle SYNOPSIS - set_maximum_open_files() + set_maximum_open_files() max_file_limit Files to open NOTES diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4c9f3700ef1..6f97a5afe94 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -289,6 +289,7 @@ typedef struct st_qsel_param { char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH], max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; bool quick; // Don't calulate possible keys + COND *cond; } PARAM; static SEL_TREE * get_mm_parts(PARAM *param,COND *cond_func,Field *field, @@ -495,6 +496,7 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) return 0; // OOM } increment_use_count(1); + tmp->color= color; return tmp; } @@ -655,7 +657,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, param.table=head; param.keys=0; param.mem_root= &alloc; - thd->no_errors=1; // Don't warn about NULL init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc, @@ -839,6 +840,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE) DBUG_RETURN(0); // Can't be calculated + param->cond= cond; + if (cond_func->functype() == Item_func::BETWEEN) { if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) @@ -1061,14 +1064,15 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, max_str[0]= min_str[0]=0; like_error= my_like_range(field->charset(), - res->ptr(),res->length(), - wild_prefix,wild_one,wild_many, - field_length, - min_str+offset, max_str+offset, - &min_length,&max_length); - + res->ptr(), res->length(), + ((Item_func_like*)(param->cond))->escape, + wild_one, wild_many, + field_length, + min_str+offset, max_str+offset, + &min_length, &max_length); if (like_error) // Can't optimize with LIKE DBUG_RETURN(0); + if (offset != maybe_null) // Blob { int2store(min_str+maybe_null,min_length); @@ -1717,6 +1721,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) return 0; // OOM tmp->copy_max_to_min(&key); tmp->increment_use_count(key1->use_count+1); + /* Increment key count as it may be used for next loop */ + key.increment_use_count(1); new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part); key1=key1->insert(new_arg); break; @@ -2789,15 +2795,17 @@ int QUICK_SELECT_DESC::get_next() ((range->flag & NEAR_MAX) ? HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV)); #else - /* Heikki changed Sept 11, 2002: since InnoDB does not store the cursor - position if READ_KEY_EXACT is used to a primary key with all - key columns specified, we must use below HA_READ_KEY_OR_NEXT, - so that InnoDB stores the cursor position and is able to move - the cursor one step backward after the search. */ - - /* Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will - * do the right thing - go past all keys which match the prefix */ - + /* + Heikki changed Sept 11, 2002: since InnoDB does not store the cursor + position if READ_KEY_EXACT is used to a primary key with all + key columns specified, we must use below HA_READ_KEY_OR_NEXT, + so that InnoDB stores the cursor position and is able to move + the cursor one step backward after the search. + */ + /* + Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will + do the right thing - go past all keys which match the prefix + */ result=file->index_read(record, (byte*) range->max_key, range->max_length, ((range->flag & NEAR_MAX) ? diff --git a/sql/set_var.cc b/sql/set_var.cc index 073330e06be..7f5cf9503bf 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -96,6 +96,8 @@ static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); static void fix_max_binlog_size(THD *thd, enum_var_type type); static void fix_max_relay_log_size(THD *thd, enum_var_type type); static void fix_max_connections(THD *thd, enum_var_type type); +static void fix_thd_mem_root(THD *thd, enum_var_type type); +static void fix_trans_mem_root(THD *thd, enum_var_type type); static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); static byte *get_error_count(THD *thd); @@ -260,13 +262,17 @@ sys_var_long_ptr sys_query_cache_size("query_cache_size", sys_var_thd_ulong sys_range_alloc_block_size("range_alloc_block_size", &SV::range_alloc_block_size); sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size", - &SV::query_alloc_block_size); + &SV::query_alloc_block_size, + fix_thd_mem_root); sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size", - &SV::query_prealloc_size); + &SV::query_prealloc_size, + fix_thd_mem_root); sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size", - &SV::trans_alloc_block_size); + &SV::trans_alloc_block_size, + fix_trans_mem_root); sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size", - &SV::trans_prealloc_size); + &SV::trans_prealloc_size, + fix_trans_mem_root); #ifdef HAVE_QUERY_CACHE sys_var_long_ptr sys_query_cache_limit("query_cache_limit", @@ -653,7 +659,7 @@ struct show_var_st init_vars[]= { {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS}, {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS}, {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS}, - {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_MY_BOOL}, + {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_INT}, {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet, SHOW_SYS}, {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS}, {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS}, @@ -1016,6 +1022,24 @@ static void fix_max_connections(THD *thd, enum_var_type type) resize_thr_alarm(max_connections + max_insert_delayed_threads + 10); } + +static void fix_thd_mem_root(THD *thd, enum_var_type type) +{ + if (type != OPT_GLOBAL) + reset_root_defaults(&thd->mem_root, + thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); +} + + +static void fix_trans_mem_root(THD *thd, enum_var_type type) +{ + if (type != OPT_GLOBAL) + reset_root_defaults(&thd->transaction.mem_root, + thd->variables.trans_alloc_block_size, + thd->variables.trans_prealloc_size); +} + bool sys_var_long_ptr::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; @@ -1332,9 +1356,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (var_type != OPT_DEFAULT) { - net_printf(thd, - var_type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : - ER_GLOBAL_VARIABLE, name); + net_printf(thd, ER_INCORRECT_GLOBAL_LOCAL_VAR, + name, var_type == OPT_GLOBAL ? "LOCAL" : "GLOBAL"); return 0; } /* As there was no local variable, return the global value */ diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 35d7fddf4c7..70a32fe8ac4 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -250,6 +250,7 @@ character-set=latin2 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -300,5 +301,5 @@ character-set=latin2 "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", "The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 7dded1e961c..a0067918fd2 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -207,7 +207,7 @@ character-set=latin1 "Denne handling kunne ikke udføres med kørende slave, brug først kommandoen STOP SLAVE", "Denne handling kræver en kørende slave. Konfigurer en slave og brug kommandoen START SLAVE", "Denne server er ikke konfigureret som slave. Ret in config-filen eller brug kommandoen CHANGE MASTER TO", -"Kunne ikke initialisere master info-struktur. Check om rettigheder i master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Kunne ikke danne en slave-tråd. Check systemressourcerne", "Brugeren %-.64s har allerede mere end 'max_user_connections' aktive forbindelser", "Du må kun bruge konstantudtryk med SET", @@ -244,6 +244,7 @@ character-set=latin1 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", ++ "Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -293,6 +294,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 95a9010ea27..4941ec5c3b1 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -215,7 +215,7 @@ character-set=latin1 "Deze operatie kan niet worden uitgevoerd met een actieve slave, doe eerst STOP SLAVE", "Deze operatie vereist een actieve slave, configureer slave en doe dan START SLAVE", "De server is niet geconfigureerd als slave, fix in configuratie bestand of met CHANGE MASTER TO", -"Kon master info structuur niet initialiseren, controleer permissies in master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Kon slave thread niet aanmaken, controleer systeem resources", "Gebruiker %-.64s heeft reeds meer dan 'max_user_connections' actieve verbindingen", "U mag alleen constante expressies gebruiken bij SET", @@ -252,6 +252,7 @@ character-set=latin1 "Deze versie van MySQL ondersteunt nog geen '%s'", "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -301,6 +302,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 9632b4e1fd5..513370d80d0 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -241,6 +241,7 @@ character-set=latin1 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,4 +293,4 @@ character-set=latin1 "'%s' is deprecated, use '%s' instead", "The target table %-.100s of the %s is not updatable", "The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 46a34dbfd25..9c44e82c4fc 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -246,6 +246,7 @@ character-set=latin7 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -295,6 +296,6 @@ character-set=latin7 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index ab29cf44a6a..1b79323ddbf 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -241,6 +241,7 @@ character-set=latin1 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -290,6 +291,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index ac470c826c0..53f7c762af0 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -216,7 +216,7 @@ character-set=latin1 "Diese Operation kann nicht bei einem aktiven Slave durchgeführt werden. Bitte zuerst STOP SLAVE ausführen", "Diese Operation benötigt einen aktiven Slave. Bitte Slave konfigurieren und mittels START SLAVE aktivieren", "Der Server ist nicht als Slave konfiguriert. Bitte in der Konfigurationsdatei oder mittels CHANGE MASTER TO beheben", -"Konnte Master-Info-Struktur nicht initialisieren. Bitte Berechtigungen von master.info prüfen", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Konnte keinen Slave-Thread starten. Bitte System-Ressourcen überprüfen", "Benutzer '%-.64s' hat mehr als max_user_connections aktive Verbindungen", "Bei SET dürfen nur konstante Ausdrücke verwendet werden", @@ -253,6 +253,7 @@ character-set=latin1 "Diese MySQL-Version unterstützt '%s' nicht", "Schwerer Fehler %d: '%-.128s vom Master beim Lesen des binären Logs aufgetreten", "Slave-SQL-Thread hat die Abfrage aufgrund von replicate-*-table-Regeln ignoriert", +"Variable '%-.64s' is a %s variable", "Falsche Fremdschlüssel-Definition für '%-64s': %s", "Schlüssel- und Tabellenverweis passen nicht zusammen", "Operand solle %d Spalte(n) enthalten", @@ -302,6 +303,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 7d88a72faf1..ead697d6fb0 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -241,6 +241,7 @@ character-set=greek "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -290,6 +291,6 @@ character-set=greek "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index b935413b212..1cc15e647a2 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -243,6 +243,7 @@ character-set=latin2 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,6 +293,6 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index cfe65c40bbf..09c9577d166 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -204,7 +204,7 @@ character-set=latin1 "Questa operazione non puo' essere eseguita con un database 'slave' che gira, lanciare prima STOP SLAVE", "Questa operaione richiede un database 'slave', configurarlo ed eseguire START SLAVE", "Il server non e' configurato come 'slave', correggere il file di configurazione cambiando CHANGE MASTER TO", -"Impossibile inizializzare la struttura 'master info', controllare i permessi sul file master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Impossibile creare il thread 'slave', controllare le risorse di sistema", "L'utente %-.64s ha gia' piu' di 'max_user_connections' connessioni attive", "Si possono usare solo espressioni costanti con SET", @@ -241,6 +241,7 @@ character-set=latin1 "Questa versione di MySQL non supporta ancora '%s'", "Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -290,6 +291,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 124863219c4..11af58c116c 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -243,6 +243,7 @@ character-set=ujis "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,6 +293,6 @@ character-set=ujis "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 4b51ac04a96..133b1ce68f2 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -241,6 +241,7 @@ character-set=euckr "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -290,6 +291,6 @@ character-set=euckr "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 3313c8ea045..fa9eed5503c 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -243,6 +243,7 @@ character-set=latin1 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,6 +293,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 0c83f2278f1..a5afec86b99 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -243,6 +243,7 @@ character-set=latin1 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,6 +293,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 4f2c6e230c6..fca1af7fb04 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -245,6 +245,7 @@ character-set=latin2 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -294,6 +295,6 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateble", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index d4d47a24d7f..40d89ccb99c 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -205,7 +205,7 @@ character-set=latin1 "Esta operação não pode ser realizada com um 'slave' em execução. Execute STOP SLAVE primeiro", "Esta operação requer um 'slave' em execução. Configure o 'slave' e execute START SLAVE", "O servidor não está configurado como 'slave'. Acerte o arquivo de configuração ou use CHANGE MASTER TO", -"Não pode inicializar a estrutura de informação do 'master'. Verifique as permissões em 'master.info'", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Não conseguiu criar 'thread' de 'slave'. Verifique os recursos do sistema", "Usuário '%-.64s' já possui mais que o valor máximo de conexões (max_user_connections) ativas", "Você pode usar apenas expressões constantes com SET", @@ -242,6 +242,7 @@ character-set=latin1 "Esta versão de MySQL não suporta ainda '%s'", "Obteve fatal erro %d: '%-.128s' do master quando lendo dados do binary log", "Slave SQL thread ignorado a consulta devido às normas de replicação-*-tabela", +"Variable '%-.64s' is a %s variable", "Definição errada da chave estrangeira para '%-.64s': %s", "Referência da chave e referência da tabela não coincidem", "Operand should contain %d column(s)", @@ -290,7 +291,7 @@ character-set=latin1 "Key cache desconhecida '%-.100s'", "MySQL foi inicializado em modo --skip-name-resolve. Você necesita reincializá-lo sem esta opção para este grant funcionar", "Motor de tabela desconhecido '%s'", -"'%s' é desatualizado. Use '%s' em seu lugar.", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"'%s' é desatualizado. Use '%s' em seu lugar", +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 1721dd4e751..d21e40ef07c 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -245,6 +245,7 @@ character-set=latin2 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -294,6 +295,6 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 302f755f89f..d2f593bb19f 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -206,7 +206,7 @@ character-set=koi8r "üÔÕ ÏÐÅÒÁÃÉÀ ÎÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÐÒÉ ÒÁÂÏÔÁÀÝÅÍ ÐÏÔÏËÅ ÐÏÄÞÉÎÅÎÎÏÇÏ ÓÅÒ×ÅÒÁ. óÎÁÞÁÌÁ ×ÙÐÏÌÎÉÔÅ STOP SLAVE", "äÌÑ ÜÔÏÊ ÏÐÅÒÁÃÉÉ ÔÒÅÂÕÅÔÓÑ ÒÁÂÏÔÁÀÝÉÊ ÐÏÄÞÉÎÅÎÎÙÊ ÓÅÒ×ÅÒ. óÎÁÞÁÌÁ ×ÙÐÏÌÎÉÔÅ START SLAVE", "üÔÏÔ ÓÅÒ×ÅÒ ÎÅ ÎÁÓÔÒÏÅÎ ËÁË ÐÏÄÞÉÎÅÎÎÙÊ. ÷ÎÅÓÉÔÅ ÉÓÐÒÁ×ÌÅÎÉÑ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÍ ÆÁÊÌÅ ÉÌÉ Ó ÐÏÍÏÝØÀ CHANGE MASTER TO", -"îÅ×ÏÚÍÏÖÎÏ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÓÔÒÕËÔÕÒÕ ÄÌÑ ÉÎÆÏÒÍÁÃÉÉ Ï ÇÏÌÏ×ÎÏÍ ÓÅÒ×ÅÒÅ. ðÒÏ×ÅÒØÔÅ ÐÒÁ×Á ÎÁ ÆÁÊÌ master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÐÏÔÏË ÐÏÄÞÉÎÅÎÎÏÇÏ ÓÅÒ×ÅÒÁ. ðÒÏ×ÅÒØÔÅ ÓÉÓÔÅÍÎÙÅ ÒÅÓÕÒÓÙ", "õ ÐÏÌØÚÏ×ÁÔÅÌÑ %-.64s ÕÖÅ ÂÏÌØÛÅ ÞÅÍ 'max_user_connections' ÁËÔÉ×ÎÙÈ ÓÏÅÄÉÎÅÎÉÊ", "÷Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ × SET ÔÏÌØËÏ ËÏÎÓÔÁÎÔÎÙÅ ×ÙÒÁÖÅÎÉÑ", @@ -243,6 +243,7 @@ character-set=koi8r "üÔÁ ×ÅÒÓÉÑ MySQL ÐÏËÁ ÅÝÅ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ '%s'", "ðÏÌÕÞÅÎÁ ÎÅÉÓÐÒÁ×ÉÍÁÑ ÏÛÉÂËÁ %d: '%-.128s' ÏÔ ÇÏÌÏ×ÎÏÇÏ ÓÅÒ×ÅÒÁ × ÐÒÏÃÅÓÓÅ ×ÙÂÏÒËÉ ÄÁÎÎÙÈ ÉÚ Ä×ÏÉÞÎÏÇÏ ÖÕÒÎÁÌÁ", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "ïÐÅÒÁÎÄ ÄÏÌÖÅÎ ÓÏÄÅÒÖÁÔØ %d ËÏÌÏÎÏË", @@ -293,5 +294,5 @@ character-set=koi8r "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", "ôÁÂÌÉÃÁ %-.100s × %s ÎÅ ÍÏÖÅÔ ÉÚÍÅÎÑÔÓÑ", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index e0ec6102f4c..e490ebfd43b 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -249,6 +249,7 @@ character-set=latin2 "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -298,6 +299,6 @@ character-set=latin2 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index cdfa6329b1f..d8af0c461b9 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -206,7 +206,7 @@ character-set=latin1 "Esta operación no puede ser hecha con el esclavo funcionando, primero use STOP SLAVE", "Esta operación necesita el esclavo funcionando, configure esclavo y haga el START SLAVE", "El servidor no está configurado como esclavo, edite el archivo config file o con CHANGE MASTER TO", -"No puedo inicializar la estructura info del master, verifique permisiones en el master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "No puedo crear el thread esclavo, verifique recursos del sistema", "Usario %-.64s ya tiene mas que 'max_user_connections' conexiones activas", "Tu solo debes usar expresiones constantes con SET", @@ -243,6 +243,7 @@ character-set=latin1 "Esta versión de MySQL no soporta todavia '%s'", "Recibió fatal error %d: '%-.128s' del master cuando leyendo datos del binary log", "Slave SQL thread ignorado el query debido a las reglas de replicación-*-tabla", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "Operand should contain %d column(s)", @@ -292,6 +293,6 @@ character-set=latin1 "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The target table %-.100s of the %s is not updateable", +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 2f656dd8d99..1ab57a6f6e2 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -204,7 +204,7 @@ character-set=latin1 "Denna operation kan inte göras under replikering; Gör STOP SLAVE först", "Denna operation kan endast göras under replikering; Konfigurera slaven och gör START SLAVE", "Servern är inte konfigurerade som en replikationsslav. Ändra konfigurationsfilen eller gör CHANGE MASTER TO", -"Kunde inte initialisera replikationsstrukturerna. Kontrollera privilegerna för 'master.info'", +"Kunde inte initialisera replikationsstrukturerna. See MySQL fel fil för mera information", "Kunde inte starta en tråd för replikering", "Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar", "Man kan endast använda konstantuttryck med SET", @@ -241,6 +241,7 @@ character-set=latin1 "Denna version av MySQL kan ännu inte utföra '%s'", "Fick fatalt fel %d: '%-.128s' från master vid läsning av binärloggen", "Slav SQL tråden ignorerade frågan pga en replicate-*-table regel", +"Variabel '%-.64s' är av typ %s", "Felaktig FOREIGN KEY-definition för '%-.64s': %s", "Nyckelreferensen och tabellreferensen stämmer inte överens", "Operand should contain %d column(s)", @@ -282,14 +283,14 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect index name '%-.100s'", -"Incorrect catalog name '%-.100s'", +"Felaktigt index namn '%-.100s'", +"Felaktigt katalog namn '%-.100s'", "Storleken av "Query cache" kunde inte sättas till %lu, ny storlek är %lu", "Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index", -"Unknown key cache '%-.100s'", +"Okänd nyckel cache '%-.100s'", "MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work", -"Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", -"The target table %-.100s of the %s is not updatable", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"Tabel %-.100s använd med '%s' är inte uppdateringsbar", +"'%s' är inte aktiverad; För att aktivera detta måste du bygga om MySQL med '%s' definerad", +"MySQL är started i --skip-grant-tables mod. Pga av detta kan du inte använda detta program", + diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 77c6e437f5b..73e1a6a5a63 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -209,7 +209,7 @@ character-set=koi8u "ïÐÅÒÁÃ¦Ñ ÎÅ ÍÏÖÅ ÂÕÔÉ ×ÉËÏÎÁÎÁ Ú ÚÁÐÕÝÅÎÉÍ Ð¦ÄÌÅÇÌÉÍ, ÓÐÏÞÁÔËÕ ×ÉËÏÎÁÊÔÅ STOP SLAVE", "ïÐÅÒÁÃ¦Ñ ×ÉÍÁÇÁ¤ ÚÁÐÕÝÅÎÏÇÏ Ð¦ÄÌÅÇÌÏÇÏ, ÚËÏÎƦÇÕÒÕÊÔŠЦÄÌÅÇÌÏÇÏ ÔÁ ×ÉËÏÎÁÊÔÅ START SLAVE", "óÅÒ×ÅÒ ÎÅ ÚËÏÎƦÇÕÒÏ×ÁÎÏ ÑË Ð¦ÄÌÅÇÌÉÊ, ×ÉÐÒÁ×ÔÅ ÃÅ Õ ÆÁÊ̦ ËÏÎƦÇÕÒÁæ§ ÁÂÏ Ú CHANGE MASTER TO", -"îÅ ÍÏÖÕ ¦Î¦Ã¦Á̦ÚÕ×ÁÔÉ ÓÔÒÕËÔÕÒÕ ÉÎÆÏÒÍÁæ§ ÇÏÌÏ×ÎÏÇÏ, ÐÅÒÅצÒÔÅ ÐÒÁ×Á ÄÏÓÔÕÐÕ ÎÁ master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "îÅ ÍÏÖÕ ÓÔ×ÏÒÉÔÉ Ð¦ÄÌÅÇÌÕ Ç¦ÌËÕ, ÐÅÒÅצÒÔÅ ÓÉÓÔÅÍΦ ÒÅÓÕÒÓÉ", "ëÏÒÉÓÔÕ×ÁÞ %-.64s ×ÖÅ ÍÁ¤ ¦ÌØÛÅ Î¦Ö 'max_user_connections' ÁËÔÉ×ÎÉÈ Ú'¤ÄÎÁÎØ", "íÏÖÎÁ ×ÉËÏÒÉÓÔÏ×Õ×ÁÔÉ ÌÉÛÅ ×ÉÒÁÚÉ Ú¦ ÓÔÁÌÉÍÉ Õ SET", @@ -246,6 +246,7 @@ character-set=koi8u "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", "Slave SQL thread ignored the query because of replicate-*-table rules", +"Variable '%-.64s' is a %s variable", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", "ïÐÅÒÁÎÄ ÍÁ¤ ÓËÌÁÄÁÔÉÓÑ Ú %d ÓÔÏ×Âæ×", @@ -296,5 +297,5 @@ character-set=koi8u "Unknown table engine '%s'", "'%s' is deprecated, use '%s' instead", "ôÁÂÌÉÃÑ %-.100s Õ %s ÎÅ ÍÏÖÅ ÏÎÏ×ÌÀ×ÁÔÉÓØ", -"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working" -"MySQL is started in --skip-grant-tables mode. You can't use this command" +"The '%s' feature was disabled; you need MySQL built with '%s' define to have it working", +"MySQL is started in --skip-grant-tables mode. You can't use this command", diff --git a/sql/slave.cc b/sql/slave.cc index 968293369a8..bbf1741183b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3303,6 +3303,14 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) if (unlikely(!num_bytes)) /* eof */ { net_write_command(net, 0, "", 0, "", 0);/* 3.23 master wants it */ + /* + If we wrote Create_file_log_event, then we need to write + Execute_load_log_event. If we did not write Create_file_log_event, + then this is an empty file and we can just do as if the LOAD DATA + INFILE had not existed, i.e. write nothing. + */ + if (unlikely(cev_not_written)) + break; Execute_load_log_event xev(thd,0,0); xev.log_pos = mi->master_log_pos; if (unlikely(mi->rli.relay_log.append(&xev))) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 17b4a4a0eee..9329ea3fd28 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2642,7 +2642,7 @@ void grant_reload(THD *thd) /**************************************************************************** Check grants - All errors are written directly to the client if command name is given ! + All errors are written directly to the client if no_errors is given ! ****************************************************************************/ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0ededa80ad6..19e6e37d43e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -488,6 +488,11 @@ void close_temporary_tables(THD *thd) query_buf_size= 50; // Enough for DROP ... TABLE for (table=thd->temporary_tables ; table ; table=table->next) + /* + We are going to add 4 ` around the db/table names, so 1 does not look + enough; indeed it is enough, because table->key_length is greater (by 8, + because of server_id and thread_id) than db||table. + */ query_buf_size+= table->key_length+1; if ((query = alloc_root(&thd->mem_root, query_buf_size))) @@ -504,8 +509,8 @@ void close_temporary_tables(THD *thd) Here we assume table_cache_key always starts with \0 terminated db name */ - end = strxmov(end,"`",table->table_cache_key,"`", - ".`",table->real_name,"`,", NullS); + end = strxmov(end,"`",table->table_cache_key,"`.`", + table->real_name,"`,", NullS); } next=table->next; close_temporary(table); @@ -808,8 +813,12 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, { if (table->key_length == key_length && !memcmp(table->table_cache_key,key,key_length) && - !my_strcasecmp(system_charset_info,table->table_name,alias)) + !my_strcasecmp(system_charset_info, table->table_name, alias) && + table->query_id != thd->query_id) + { + table->query_id=thd->query_id; goto reset; + } } my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias); DBUG_RETURN(0); @@ -1342,15 +1351,47 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, error=1; } else - { thd->clear_error(); // Clear error message - } pthread_mutex_lock(&LOCK_open); unlock_table_name(thd,&table_list); if (error) goto err; } + /* + If we are here, there was no fatal error (but error may be still + unitialized). + */ + if (unlikely(entry->file->implicit_emptied)) + { + entry->file->implicit_emptied= 0; + if (mysql_bin_log.is_open()) + { + char *query, *end; + uint query_buf_size= 20 + 2*NAME_LEN + 1; + if ((query= (char*)my_malloc(query_buf_size,MYF(MY_WME)))) + { + end = strxmov(strmov(query, "DELETE FROM `"), + db,"`.`",name,"`", NullS); + Query_log_event qinfo(thd, query, (ulong)(end-query), 0); + mysql_bin_log.write(&qinfo); + my_free(query, MYF(0)); + } + else + { + /* + As replication is maybe going to be corrupted, we need to warn the + DBA on top of warning the client (which will automatically be done + because of MYF(MY_WME) in my_malloc() above). + */ + sql_print_error("Error: when opening HEAP table, could not allocate \ +memory to write 'DELETE FROM `%s`.`%s`' to the binary log",db,name); + if (entry->file) + closefrm(entry); + goto err; + } + } + } DBUG_RETURN(0); err: DBUG_RETURN(1); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cbac11ac42e..e7f867ccd61 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -647,6 +647,8 @@ bool select_send::send_data(List<Item> &items) } } thd->sent_row_count++; + if (!thd->net.vio) + DBUG_RETURN(0); if (!thd->net.report_error) DBUG_RETURN(protocol->write()); DBUG_RETURN(1); diff --git a/sql/sql_class.h b/sql/sql_class.h index 9d971b1a196..d79cb186de2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1035,11 +1035,11 @@ class select_create: public select_insert { MYSQL_LOCK *lock; Field **field; public: - select_create (const char *db_name, const char *table_name, - HA_CREATE_INFO *create_info_par, - List<create_field> &fields_par, - List<Key> &keys_par, - List<Item> &select_fields,enum_duplicates duplic) + select_create(const char *db_name, const char *table_name, + HA_CREATE_INFO *create_info_par, + List<create_field> &fields_par, + List<Key> &keys_par, + List<Item> &select_fields,enum_duplicates duplic) :select_insert (NULL, &select_fields, duplic), db(db_name), name(table_name), extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), lock(0) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b9da6ffd3f4..0323e90a166 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -307,11 +307,19 @@ exit2: /* - Drop all tables in a database. + Drop all tables in a database and the database itself - db-name is already validated when we come here - If thd == 0, do not write any messages; This is useful in replication - when we want to remove a stale database before replacing it with the new one + SYNOPSIS + mysql_rm_db() + thd Thread handle + db Database name in the case given by user + It's already validated when we come here + if_exists Don't give error if database doesn't exists + silent Don't generate errors + + RETURN + 0 ok (Database dropped) + -1 Error generated */ @@ -319,7 +327,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { long deleted=0; int error = 0; - char path[FN_REFLEN+16]; + char path[FN_REFLEN+16], tmp_db[NAME_LEN+1]; MY_DIR *dirp; DBUG_ENTER("mysql_rm_db"); @@ -351,6 +359,14 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } goto exit; } + if (lower_case_table_names) + { + /* Convert database to lower case */ + strmov(tmp_db, db); + my_casedn_str(system_charset_info, tmp_db); + db= tmp_db; + } + pthread_mutex_lock(&LOCK_open); remove_db_from_cache(db); pthread_mutex_unlock(&LOCK_open); @@ -426,7 +442,7 @@ exit2: /* Removes files with known extensions plus all found subdirectories that - are 2 digits (raid directories). + are 2 hex digits (raid directories). thd MUST be set when calling this function! */ @@ -451,8 +467,10 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, DBUG_PRINT("info",("Examining: %s", file->name)); /* Check if file is a raid directory */ - if (my_isdigit(&my_charset_latin1,file->name[0]) && - my_isdigit(&my_charset_latin1,file->name[1]) && + if ((my_isdigit(&my_charset_latin1, file->name[0]) || + (file->name[0] >= 'a' && file->name[0] <= 'f')) && + (my_isdigit(&my_charset_latin1, file->name[1]) || + (file->name[1] >= 'a' && file->name[1] <= 'f')) && !file->name[2] && !level) { char newpath[FN_REFLEN]; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 897aa37ba11..d0f241b3291 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -287,14 +287,13 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, int dblen; TABLE **ptr; - if (!db || ! *db) - db= thd->db ? thd->db : ""; - dblen=strlen(db)+1; + DBUG_ASSERT(db); + dblen= strlen(db); ptr= &(thd->handler_tables); for (TABLE *table= *ptr; table ; table= *ptr) { - if (!memcmp(table->table_cache_key, db, dblen) && + if ((db == any_db || !memcmp(table->table_cache_key, db, dblen)) && !my_strcasecmp(system_charset_info, (is_alias ? table->table_name : table->real_name), table_name)) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 58c3d143a4f..6ed3dca63e3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -534,7 +534,14 @@ int write_record(TABLE *table,COPY_INFO *info) } else /* DUP_REPLACE */ { - if (last_uniq_key(table,key_nr)) + /* + The manual defines the REPLACE semantics that it is either + an INSERT or DELETE(s) + INSERT; FOREIGN KEY checks in + InnoDB do not function in the defined way if we allow MySQL + to convert the latter operation internally to an UPDATE. + */ + if (last_uniq_key(table,key_nr) && + !table->file->referenced_by_foreign_key()) { if ((error=table->file->update_row(table->record[1], table->record[0]))) @@ -1552,8 +1559,8 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) DBUG_ENTER("select_create::prepare"); unit= u; - table=create_table_from_items(thd, create_info, db, name, - extra_fields, keys, &values, &lock); + table= create_table_from_items(thd, create_info, db, name, + extra_fields, keys, &values, &lock); if (!table) DBUG_RETURN(-1); // abort() deletes table diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 175791ef31e..f910e947720 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -94,7 +94,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, #endif char *db = table_list->db; // This is never null /* If no current database, use database where table is located */ - char *tdb= thd->db ? thd->db : db; + char *tdb= thd->db ? thd->db : db; // Result is never null bool transactional_table, log_delayed; ulong skip_lines= ex->skip_lines; DBUG_ENTER("mysql_load"); @@ -237,7 +237,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } #ifndef EMBEDDED_LIBRARY - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (mysql_bin_log.is_open()) { lf_info.thd = thd; lf_info.ex = ex; @@ -313,7 +313,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (transactional_table) ha_autocommit_or_rollback(thd,error); #ifndef EMBEDDED_LIBRARY - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (mysql_bin_log.is_open()) { /* Make sure last block (the one which caused the error) gets logged. @@ -360,28 +360,16 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, #ifndef EMBEDDED_LIBRARY if (mysql_bin_log.is_open()) { - if (opt_old_rpl_compat) - { - if (!read_file_from_client) - { - Load_log_event qinfo(thd, ex, db, table->table_name, fields, - handle_duplicates, log_delayed); - mysql_bin_log.write(&qinfo); - } - } - else + /* + As already explained above, we need to call end_io_cache() or the last + block will be logged only after Execute_load_log_event (which is wrong), + when read_info is destroyed. + */ + read_info.end_io_cache(); + if (lf_info.wrote_create_file) { - /* - As already explained above, we need to call end_io_cache() or the last - block will be logged only after Execute_load_log_event (which is wrong), - when read_info is destroyed. - */ - read_info.end_io_cache(); - if (lf_info.wrote_create_file) - { - Execute_load_log_event e(thd, db, log_delayed); - mysql_bin_log.write(&e); - } + Execute_load_log_event e(thd, db, log_delayed); + mysql_bin_log.write(&e); } } #endif /*!EMBEDDED_LIBRARY*/ @@ -698,7 +686,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, if (get_it_from_net) cache.read_function = _my_b_net_read; - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (mysql_bin_log.is_open()) cache.pre_read = cache.pre_close = (IO_CACHE_CALLBACK) log_loaded_block; #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index caa9528298c..6acb5901efc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -52,12 +52,12 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); -static bool single_table_command_access(THD *thd, ulong privilege, - TABLE_LIST *tables, int *res); static void remove_escape(char *name); static void refresh_status(void); -static bool append_file_to_dir(THD *thd, char **filename_ptr, - char *table_name); +static bool append_file_to_dir(THD *thd, const char **filename_ptr, + const char *table_name); +static int check_one_table_access(THD *thd, ulong privilege, + TABLE_LIST *tables, bool no_errors); const char *any_db="*any*"; // Special symbol for check_access @@ -1160,9 +1160,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT))) DBUG_RETURN(1); - if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege,0,0)) - goto err; - if (grant_option && check_grant(thd, SELECT_ACL, table_list, 0, 0)) + if (check_one_table_access(thd, SELECT_ACL, table_list, 0)) goto err; thd->free_list = 0; thd->query_length=(uint) strlen(tbl_name); @@ -1483,9 +1481,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_casedn_str(files_charset_info, table_list.real_name); remove_escape(table_list.real_name); // This can't have wildcards - if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access,0,0)) + if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege, + 0, 0)) break; - table_list.grant.privilege=thd->col_access; if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2,0)) break; mysqld_list_fields(thd,&table_list,fields); @@ -1502,10 +1500,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CREATE_DB: // QQ: To be removed { + char *db=thd->strdup(packet), *alias; + statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); - char *db=thd->strdup(packet); // null test to handle EOM - if (!db || !strip_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) || + check_db_name(db)) { net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1513,15 +1513,16 @@ 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,db,0,0); + mysql_create_db(thd,(lower_case_table_names == 2 ? alias : db),0,0); break; } case COM_DROP_DB: // QQ: To be removed { statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); - char *db=thd->strdup(packet); + char *db=thd->strdup(packet), *alias; // null test to handle EOM - if (!db || !strip_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) || + check_db_name(db)) { net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1534,7 +1535,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } mysql_log.write(thd,command,db); - mysql_rm_db(thd,db,0,0); + mysql_rm_db(thd,alias,0,0); break; } #ifndef EMBEDDED_LIBRARY @@ -1799,7 +1800,9 @@ mysql_execute_command(THD *thd) Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated */ - if (table_rules_on && tables && !tables_ok(thd,tables)) + if (table_rules_on && tables && !tables_ok(thd,tables) && + ((lex->sql_command != SQLCOM_DELETE_MULTI) || + !tables_ok(thd,(TABLE_LIST *)thd->lex->auxilliary_table_list.first))) { /* we warn the slave SQL thread */ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); @@ -2131,6 +2134,7 @@ mysql_execute_command(THD *thd) ulong 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, @@ -2216,12 +2220,8 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_CREATE_INDEX: - if (!tables->db) - tables->db=thd->db; - if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0)) + if (check_one_table_access(thd, INDEX_ACL, tables, 0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,INDEX_ACL,tables,0,0)) - goto error; thd->slow_command=TRUE; if (end_active_trans(thd)) res= -1; @@ -2277,8 +2277,6 @@ mysql_execute_command(THD *thd) res=0; break; } - if (!tables->db) - tables->db=thd->db; if (!select_lex->db) select_lex->db=tables->db; if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege,0,0) || @@ -2287,8 +2285,6 @@ mysql_execute_command(THD *thd) (TABLE_LIST *) lex->create_info.merge_list.first)) goto error; /* purecov: inspected */ - if (!tables->db) - tables->db=thd->db; if (grant_option) { if (check_grant(thd,ALTER_ACL,tables,0,0)) @@ -2484,16 +2480,15 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_UPDATE: - if (check_db_used(thd,tables)) - goto error; - - if (single_table_command_access(thd, UPDATE_ACL, tables, &res)) - goto error; if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); DBUG_VOID_RETURN; } + if (check_db_used(thd,tables)) + goto error; + if (check_one_table_access(thd, UPDATE_ACL, tables, 0)) + goto error; res= mysql_update(thd,tables, select_lex->item_list, lex->value_list, @@ -2506,36 +2501,48 @@ mysql_execute_command(THD *thd) res= -1; break; case SQLCOM_UPDATE_MULTI: - if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege,0,0)) - goto error; - if (grant_option && check_grant(thd,UPDATE_ACL,tables,0,0)) - goto error; + { + const char *msg= 0; + TABLE_LIST *table; + if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); DBUG_VOID_RETURN; } + /* + Ensure that we have UPDATE or SELECT privilege for each table + The exact privilege is checked in mysql_multi_update() + */ + for (table= tables ; table ; table= table->next) { - const char *msg= 0; - if (select_lex->order_list.elements) - msg= "ORDER BY"; - else if (select_lex->select_limit && select_lex->select_limit != - HA_POS_ERROR) - msg= "LIMIT"; - if (msg) - { - net_printf(thd, ER_WRONG_USAGE, "UPDATE", msg); - res= 1; - break; - } - res= mysql_multi_update(thd,tables, - &select_lex->item_list, - &lex->value_list, - select_lex->where, - select_lex->options, - lex->duplicates, unit, select_lex); + TABLE_LIST *save= table->next; + table->next= 0; + if (check_one_table_access(thd, UPDATE_ACL, table, 1) && + check_one_table_access(thd, SELECT_ACL, table, 0)) + goto error; + table->next= save; + } + + if (select_lex->order_list.elements) + msg= "ORDER BY"; + else if (select_lex->select_limit && select_lex->select_limit != + HA_POS_ERROR) + msg= "LIMIT"; + if (msg) + { + net_printf(thd, ER_WRONG_USAGE, "UPDATE", msg); + res= 1; + break; } + res= mysql_multi_update(thd,tables, + &select_lex->item_list, + &lex->value_list, + select_lex->where, + select_lex->options, + lex->duplicates, unit, select_lex); break; + } case SQLCOM_REPLACE: case SQLCOM_INSERT: { @@ -2543,7 +2550,7 @@ mysql_execute_command(THD *thd) ulong privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL | update); - if (single_table_command_access(thd, privilege, tables, &res)) + if (check_one_table_access(thd, privilege, tables, 0)) goto error; if (select_lex->item_list.elements != lex->value_list.elements) { @@ -2569,13 +2576,10 @@ mysql_execute_command(THD *thd) INSERT_ACL | DELETE_ACL : INSERT_ACL); TABLE_LIST *save_next=tables->next; tables->next=0; - if (check_access(thd, privilege, - tables->db,&tables->grant.privilege,0,0) || - (grant_option && check_grant(thd, privilege, tables,0,0))) + if (check_one_table_access(thd, privilege, tables, 0)) goto error; - tables->next=save_next; - if ((res=check_table_access(thd, SELECT_ACL, save_next,0))) + if (check_table_access(thd, SELECT_ACL, save_next, 0)) goto error; } @@ -2616,9 +2620,7 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_TRUNCATE: - if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege,0,0)) - goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,DELETE_ACL,tables,0,0)) + if (check_one_table_access(thd, DELETE_ACL, tables, 0)) goto error; /* Don't allow this within a transaction because we want to use @@ -2633,7 +2635,7 @@ mysql_execute_command(THD *thd) break; case SQLCOM_DELETE: { - if (single_table_command_access(thd, DELETE_ACL, tables, &res)) + if (check_one_table_access(thd, DELETE_ACL, tables, 0)) goto error; // Set privilege for the WHERE clause tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); @@ -2758,8 +2760,8 @@ mysql_execute_command(THD *thd) DROP / * 40005 TEMPORARY * / TABLE that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE MASTER TO), while the temporary table has already been dropped. - To not generate such irrelevant "table does not exist errors", we - silently add IF EXISTS if TEMPORARY was used. + To not generate such irrelevant "table does not exist errors", + we silently add IF EXISTS if TEMPORARY was used. */ if (thd->slave_thread) lex->drop_if_exists= 1; @@ -2768,12 +2770,8 @@ mysql_execute_command(THD *thd) } break; case SQLCOM_DROP_INDEX: - if (!tables->db) - tables->db=thd->db; - if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0)) + if (check_one_table_access(thd, INDEX_ACL, tables, 0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,INDEX_ACL,tables,0,0)) - goto error; if (end_active_trans(thd)) res= -1; else @@ -2882,16 +2880,11 @@ mysql_execute_command(THD *thd) #else { char *db=tables->db; - if (!*db) - { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ - goto error; /* purecov: inspected */ - } remove_escape(db); // Fix escaped '_' remove_escape(tables->real_name); - if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access,0,0)) + if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, + &tables->grant.privilege, 0, 0)) goto error; /* purecov: inspected */ - tables->grant.privilege=thd->col_access; if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0)) goto error; res= mysqld_show_fields(thd,tables, @@ -2907,18 +2900,11 @@ mysql_execute_command(THD *thd) #else { char *db=tables->db; - if (!db) - { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ - goto error; /* purecov: inspected */ - } remove_escape(db); // Fix escaped '_' remove_escape(tables->real_name); - if (!tables->db) - tables->db=thd->db; - if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) - goto error; /* purecov: inspected */ - tables->grant.privilege=thd->col_access; + if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, + &tables->grant.privilege, 0, 0)) + goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0)) goto error; res= mysqld_show_keys(thd,tables); @@ -2947,9 +2933,7 @@ mysql_execute_command(THD *thd) send_error(thd,ER_NOT_ALLOWED_COMMAND); goto error; } - if (check_access(thd,privilege,tables->db,&tables->grant.privilege,0, - 0) || - grant_option && check_grant(thd,privilege,tables,0,0)) + if (check_one_table_access(thd, privilege, tables, 0)) goto error; } res=mysql_load(thd, lex->exchange, tables, lex->field_list, @@ -2998,7 +2982,9 @@ mysql_execute_command(THD *thd) break; case SQLCOM_CREATE_DB: { - if (!strip_sp(lex->name) || check_db_name(lex->name)) + char *alias; + if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) || + check_db_name(lex->name)) { net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; @@ -3021,12 +3007,15 @@ mysql_execute_command(THD *thd) #endif if (check_access(thd,CREATE_ACL,lex->name,0,1,0)) break; - res=mysql_create_db(thd,lex->name,&lex->create_info,0); + res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name), + &lex->create_info, 0); break; } case SQLCOM_DROP_DB: { - if (!strip_sp(lex->name) || check_db_name(lex->name)) + char *alias; + if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) || + check_db_name(lex->name)) { net_printf(thd, ER_WRONG_DB_NAME, lex->name); break; @@ -3054,7 +3043,7 @@ mysql_execute_command(THD *thd) send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } - res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0); + res=mysql_rm_db(thd,alias,lex->drop_if_exists,0); break; } case SQLCOM_ALTER_DB: @@ -3407,19 +3396,19 @@ error: tables belong to subselects. SYNOPSIS - single_table_command_access() - thd - Thread handler - privilege - asked privelage - tables - table list of command - res - pointer on result code variable + check_one_table_access() + thd Thread handler + privilege requested privelage + tables table list of command + no_errors Don't send error to client RETURN 0 - OK - 1 - access denied + 1 - access denied, error is sent to client */ -static bool single_table_command_access(THD *thd, ulong privilege, - TABLE_LIST *tables, int *res) +static int check_one_table_access(THD *thd, ulong privilege, + TABLE_LIST *tables, bool no_errors) { if (check_access(thd, privilege, tables->db, &tables->grant.privilege,0,0)) @@ -3435,7 +3424,7 @@ static bool single_table_command_access(THD *thd, ulong privilege, if (subselects_tables) { tables->next= subselects_tables; - if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables,0))) + if ((check_table_access(thd, SELECT_ACL, subselects_tables,0))) return 1; } return 0; @@ -3953,12 +3942,12 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (default_value) { - if (type == FIELD_TYPE_TIMESTAMP) - { - net_printf(thd, ER_INVALID_DEFAULT, field_name); - DBUG_RETURN(1); - } - else if (default_value->type() == Item::NULL_ITEM) + /* + We allow specifying value for first TIMESTAMP column + altough it is silently ignored. This should be fixed in 4.1 + (by proper warning or real support for default values) + */ + if (default_value->type() == Item::NULL_ITEM) { default_value=0; if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == @@ -4704,7 +4693,8 @@ static void refresh_status(void) /* If pointer is not a null pointer, append filename to it */ -static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) +static bool append_file_to_dir(THD *thd, const char **filename_ptr, + const char *table_name) { char buff[FN_REFLEN],*ptr, *end; if (!*filename_ptr) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 3ab6621f35b..6cff90ff613 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -112,19 +112,31 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { db_type table_type; char name[FN_REFLEN]; - new_table=ren_table->next; + const char *new_alias, *old_alias; + new_table=ren_table->next; + if (lower_case_table_names == 2) + { + old_alias= ren_table->alias; + new_alias= new_table->alias; + } + else + { + old_alias= ren_table->real_name; + new_alias= new_table->real_name; + } sprintf(name,"%s/%s/%s%s",mysql_data_home, - new_table->db,new_table->real_name, - reg_ext); + new_table->db, new_alias, reg_ext); + unpack_filename(name, name); if (!access(name,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_alias); DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, - ren_table->db,ren_table->real_name, + ren_table->db, old_alias, reg_ext); + unpack_filename(name, name); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN) { my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); @@ -132,8 +144,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) DBUG_RETURN(ren_table); } else if (mysql_rename_table(table_type, - ren_table->db, ren_table->real_name, - new_table->db, new_table->real_name)) + ren_table->db, old_alias, + new_table->db, new_alias)) { if (!skip_error) DBUG_RETURN(ren_table); diff --git a/sql/sql_repl.h b/sql/sql_repl.h index fe1b7167d4a..e7001c1fe1e 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -12,7 +12,7 @@ typedef struct st_slave_info THD* thd; } SLAVE_INFO; -extern my_bool opt_show_slave_auth_info, opt_old_rpl_compat; +extern my_bool opt_show_slave_auth_info; extern char *master_host, *master_info_file; extern bool server_id_supplied; extern I_List<i_string> binlog_do_db, binlog_ignore_db; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0e1a25bc42b..69e3469bd7f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2144,8 +2144,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, bool optimizable=0; for (uint i=0; i<num_values; i++) { - used_tables|=(*value)->used_tables(); - if (!((*value)->used_tables() & (field->table->map | RAND_TABLE_BIT))) + used_tables|=(value[i])->used_tables(); + if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT))) optimizable=1; } if (!optimizable) @@ -2645,7 +2645,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, read_time+=record_count/(double) TIME_FOR_COMPARE; if (join->sort_by_table && - join->sort_by_table != join->positions[join->const_tables].table->table) + join->sort_by_table != + join->positions[join->const_tables].table->table) read_time+=record_count; // We have to make a temp table if (read_time < join->best_read) { @@ -2817,7 +2818,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, will match */ if (table->quick_keys.is_set(key) && - table->quick_key_parts[key] <= max_key_part) + table->quick_key_parts[key] == max_key_part) tmp=records= (double) table->quick_rows[key]; else { @@ -2859,7 +2860,15 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, } records=(ulong) tmp; } - if (found_ref_or_null) + /* + If quick_select was used on a part of this key, we know + the maximum number of rows that the key can match. + */ + if (table->quick_keys.is_set(key) && + table->quick_key_parts[key] <= max_key_part && + records > (double) table->quick_rows[key]) + tmp= records= (double) table->quick_rows[key]; + else if (found_ref_or_null) { /* We need to do two key searches to find key */ tmp*= 2.0; @@ -3335,9 +3344,15 @@ store_val_in_field(Field *field,Item *item) bool error; THD *thd=current_thd; ha_rows cuted_fields=thd->cuted_fields; + /* + we should restore old value of count_cuted_fields because + store_val_in_field can be called from mysql_insert + with select_insert, which make count_cuted_fields= 1 + */ + enum_check_fields old_count_cuted_fields= thd->count_cuted_fields; thd->count_cuted_fields= CHECK_FIELD_WARN; error= item->save_in_field(field, 1); - thd->count_cuted_fields= CHECK_FIELD_IGNORE; + thd->count_cuted_fields= old_count_cuted_fields; return error || cuted_fields != thd->cuted_fields; } @@ -3569,6 +3584,7 @@ make_join_readinfo(JOIN *join, uint options) { uint i; SELECT_LEX *select_lex= &join->thd->lex->select_lex; + bool statistics= test(!(join->select_options & SELECT_DESCRIBE)); DBUG_ENTER("make_join_readinfo"); for (i=join->const_tables ; i < join->tables ; i++) @@ -3662,7 +3678,8 @@ make_join_readinfo(JOIN *join, uint options) { join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED; tab->read_first_record= join_init_quick_read_record; - statistic_increment(select_range_check_count, &LOCK_status); + if (statistics) + statistic_increment(select_range_check_count, &LOCK_status); } else { @@ -3671,24 +3688,28 @@ make_join_readinfo(JOIN *join, uint options) { if (tab->select && tab->select->quick) { - statistic_increment(select_range_count, &LOCK_status); + if (statistics) + statistic_increment(select_range_count, &LOCK_status); } else { join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED; - statistic_increment(select_scan_count, &LOCK_status); + if (statistics) + statistic_increment(select_scan_count, &LOCK_status); } } else { if (tab->select && tab->select->quick) { - statistic_increment(select_full_range_join_count, &LOCK_status); + if (statistics) + statistic_increment(select_full_range_join_count, &LOCK_status); } else { join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED; - statistic_increment(select_full_join_count, &LOCK_status); + if (statistics) + statistic_increment(select_full_join_count, &LOCK_status); } } if (!table->no_keyread) @@ -6700,8 +6721,11 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) /* We can remove binary fields and numerical fields except float, as float comparison isn't 100 % secure + We have to keep binary strings to be able to check for end spaces */ if (field->binary() && + field->real_type() != FIELD_TYPE_STRING && + field->real_type() != FIELD_TYPE_VAR_STRING && (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0)) { return !store_val_in_field(field,right_item); @@ -7914,6 +7938,29 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, } +/* + Intitialize the GROUP BY list. + + SYNOPSIS + setup_group() + thd Thread handler + ref_pointer_array We store references to all fields that was not in + 'fields' here. + fields All fields in the select part. Any item in 'order' + that is part of these list is replaced by a pointer + to this fields. + all_fields Total list of all unique fields used by the select. + All items in 'order' that was not part of fields will + be added first to this list. + order The fields we should do GROUP BY on. + hidden_group_fields Pointer to flag that is set to 1 if we added any fields + to all_fields. + + RETURN + 0 ok + 1 error (probably out of memory) +*/ + int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List<Item> &fields, List<Item> &all_fields, ORDER *order, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f076e2fe802..8ed44d618fb 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -692,11 +692,6 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, if (!wild || !wild[0] || !wild_case_compare(system_charset_info, field->field_name,wild)) { -#ifdef NOT_USED - if (thd->col_access & TABLE_ACLS || - ! check_grant_column(thd,table,field->field_name, - (uint) strlen(field->field_name),1)) -#endif { byte *pos; uint flags=field->flags; @@ -711,6 +706,12 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, if (verbose) protocol->store(field->has_charset() ? field->charset()->name : "NULL", system_charset_info); + /* + Altough TIMESTAMP fields can't contain NULL as its value they + will accept NULL if you will try to insert such value and will + convert it to current TIMESTAMP. So YES here means that NULL + is allowed for assignment but can't be returned. + */ pos=(byte*) ((flags & NOT_NULL_FLAG) && field->type() != FIELD_TYPE_TIMESTAMP ? "" : "YES"); @@ -720,7 +721,11 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); protocol->store((char*) pos, system_charset_info); - if (field->type() == FIELD_TYPE_TIMESTAMP || + /* + We handle first TIMESTAMP column in special way because its + default value is ignored and current timestamp used instead. + */ + if (table->timestamp_field == field || field->unireg_check == Field::NEXT_NUMBER) null_default_value=1; if (!null_default_value && !field->is_null()) @@ -995,9 +1000,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) protocol->store_null(); /* Check if we have a key part that only uses part of the field */ - if (!key_part->field || - key_part->length != - table->field[key_part->fieldnr-1]->key_length()) + if (!(key_info->flags & HA_FULLTEXT) && (!key_part->field || + key_part->length != table->field[key_part->fieldnr-1]->key_length())) protocol->store_tiny((longlong) key_part->length); else protocol->store_null(); @@ -1206,7 +1210,7 @@ static int store_create_info(THD *thd, TABLE *table, String *packet) { List<Item> field_list; - char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end; + char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end, *alias; String type(tmp, sizeof(tmp),&my_charset_bin); Field **ptr,*field; uint primary_key; @@ -1232,7 +1236,9 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append("CREATE TEMPORARY TABLE ", 23); else packet->append("CREATE TABLE ", 13); - append_identifier(thd,packet, table->real_name, strlen(table->real_name)); + alias= (lower_case_table_names == 2 ? table->table_name : + table->real_name); + append_identifier(thd, packet, alias, strlen(alias)); packet->append(" (\n", 3); for (ptr=table->field ; (field= *ptr); ptr++) @@ -1280,7 +1286,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" NOT NULL", 9); has_default= (field->type() != FIELD_TYPE_BLOB && - field->type() != FIELD_TYPE_TIMESTAMP && + table->timestamp_field != field && field->unireg_check != Field::NEXT_NUMBER); if (has_default) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index e76c7902210..c6eda5f9fb2 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -699,11 +699,56 @@ void String::qs_append(const char &c) } -int sortcmp(const String *x,const String *y, CHARSET_INFO *cs) +/* + Compare strings according to collation, without end space. + + SYNOPSIS + sortcmp() + s First string + t Second string + cs Collation + + NOTE: + Normally this is case sensitive comparison + + RETURN + < 0 s < t + 0 s == t + > 0 s > t +*/ + + +int sortcmp(const String *s,const String *t, CHARSET_INFO *cs) +{ + return cs->coll->strnncollsp(cs, + (unsigned char *) s->ptr(),s->length(), + (unsigned char *) t->ptr(),t->length()); +} + + +/* + Compare strings byte by byte. End spaces are also compared. + + SYNOPSIS + stringcmp() + s First string + t Second string + + NOTE: + Strings are compared as a stream of unsigned chars + + RETURN + < 0 s < t + 0 s == t + > 0 s > t +*/ + + +int stringcmp(const String *s,const String *t) { - return cs->coll->strnncollsp(cs, - (unsigned char *) x->ptr(),x->length(), - (unsigned char *) y->ptr(),y->length()); + uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len); + int cmp= memcmp(s->ptr(), t->ptr(), len); + return (cmp) ? cmp : (int) (s_len - t_len); } diff --git a/sql/sql_string.h b/sql/sql_string.h index 163156fdfe2..cdfb00276d4 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -221,6 +221,7 @@ public: inline void caseup() { my_caseup(str_charset,Ptr,str_length); } inline void casedn() { my_casedn(str_charset,Ptr,str_length); } friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); + friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); uint32 numchars(); int charpos(int i,uint32 offset=0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9faabb265e1..fb86e446fb7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -179,11 +179,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN]; + char path[FN_REFLEN], *alias; String wrong_tables; - db_type table_type; int error; - bool some_tables_deleted=0, tmp_table_deleted=0; + bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; DBUG_ENTER("mysql_rm_table_part2"); if (lock_table_names(thd, tables)) @@ -212,13 +211,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, drop_locked_tables(thd,db,table->real_name); if (thd->killed) DBUG_RETURN(-1); - + alias= (lower_case_table_names == 2) ? table->alias : table->real_name; /* remove form file and isam files */ - strxmov(path, mysql_data_home, "/", db, "/", table->real_name, reg_ext, - NullS); + strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS); (void) unpack_filename(path,path); - - table_type=get_table_type(path); } if (drop_temporary || access(path,F_OK)) { @@ -232,10 +228,16 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; - *(end=fn_ext(path))=0; // Remove extension + db_type table_type= get_table_type(path); + *(end=fn_ext(path))=0; // Remove extension for delete error=ha_delete_table(table_type, path); if (error == ENOENT && if_exists) error = 0; + if (error == HA_ERR_ROW_IS_REFERENCED) + { + /* the table is referenced by a foreign key constraint */ + foreign_key_error=1; + } if (!error || error == ENOENT) { /* Delete the table definition file */ @@ -272,7 +274,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, error= 0; if (wrong_tables.length()) { - my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); + if (!foreign_key_error) + my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); + else + my_error(ER_ROW_IS_REFERENCED,MYF(0)); error= 1; } DBUG_RETURN(error); @@ -373,7 +378,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, uint select_field_count) { char path[FN_REFLEN]; - const char *key_name; + const char *key_name, *alias; create_field *sql_field,*dup_field; int error= -1; uint db_options,field,null_fields,blob_columns; @@ -386,10 +391,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, enum db_type new_db_type; DBUG_ENTER("mysql_create_table"); - /* - Check for duplicate fields and check type of table to create - */ - + /* Check for duplicate fields and check type of table to create */ if (!fields.elements) { my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); @@ -411,6 +413,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, db_options=create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) db_options|=HA_OPTION_PACK_RECORD; + alias= table_case_name(create_info, table_name); file=get_new_handler((TABLE*) 0, create_info->db_type); if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && @@ -960,7 +963,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; } else - (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext); + (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,alias,reg_ext); unpack_filename(path,path); /* Check if table already exists */ if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) @@ -971,7 +974,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); } - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); DBUG_RETURN(-1); } if (wait_if_global_read_lock(thd, 0)) @@ -1116,7 +1119,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(0); if (!(table=open_table(thd,db,name,name,(bool*) 0))) { - quick_rm_table(create_info->db_type,db,name); + quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); DBUG_RETURN(0); } table->reginfo.lock_type=TL_WRITE; @@ -1125,7 +1128,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, VOID(pthread_mutex_lock(&LOCK_open)); hash_delete(&open_cache,(byte*) table); VOID(pthread_mutex_unlock(&LOCK_open)); - quick_rm_table(create_info->db_type,db,name); + quick_rm_table(create_info->db_type,db,table_case_name(create_info, name)); DBUG_RETURN(0); } table->file->extra(HA_EXTRA_WRITE_CACHE); @@ -1140,18 +1143,32 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, bool mysql_rename_table(enum db_type base, const char *old_db, - const char * old_name, + const char *old_name, const char *new_db, - const char * new_name) + const char *new_name) { - char from[FN_REFLEN],to[FN_REFLEN]; + char from[FN_REFLEN], to[FN_REFLEN]; + char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1]; handler *file=get_new_handler((TABLE*) 0, base); int error=0; DBUG_ENTER("mysql_rename_table"); + + if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) + { + /* Table handler expects to get all file names as lower case */ + strmov(tmp_from, old_name); + my_casedn_str(system_charset_info, tmp_from); + old_name= tmp_from; + + strmov(tmp_to, new_name); + my_casedn_str(system_charset_info, tmp_to); + new_name= tmp_to; + } (void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name); (void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name); fn_format(from,from,"","",4); fn_format(to,to, "","",4); + if (!(error=file->rename_table((const char*) from,(const char *) to))) { if (rename_file_ext(from,to,reg_ext)) @@ -1167,6 +1184,7 @@ mysql_rename_table(enum db_type base, DBUG_RETURN(error != 0); } + /* Force all other threads to stop using the table @@ -1211,7 +1229,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, Close a cached table SYNOPSIS - clsoe_cached_table() + close_cached_table() thd Thread handler table Table to remove from cache @@ -1988,8 +2006,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { TABLE *table,*new_table; int error; - char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN], - *table_name,*db; + char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; + char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; bool use_timestamp=0; ha_rows copied,deleted; @@ -2000,9 +2018,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->proc_info="init"; table_name=table_list->real_name; + alias= (lower_case_table_names == 2) ? table_list->alias : table_name; + db=table_list->db; - if (!new_db || !strcmp(new_db,db)) - new_db=db; + if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) + { + new_db= db; + } used_fields=create_info->used_fields; mysql_ha_closeall(thd, table_list); @@ -2010,7 +2032,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (tablespace_op != NO_TABLESPACE_OP) DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, - tablespace_op)); + tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -2018,18 +2040,32 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (new_name) { strmov(new_name_buff,new_name); - fn_same(new_name_buff,table_name,3); + strmov(new_alias= new_alias_buff, new_name); if (lower_case_table_names) - my_casedn_str(system_charset_info,new_name); - if (!my_strcasecmp(table_alias_charset, new_name_buff, table_name)) - new_name=table_name; // No. Make later check easier + { + if (lower_case_table_names != 2) + { + my_casedn_str(system_charset_info, new_name_buff); + new_alias= new_name; // Create lower case table name + } + my_casedn_str(system_charset_info, new_name); + } + if (new_db == db && + !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) + { + /* + Source and destination table names are equal: make later check + easier. + */ + new_alias= new_name= table_name; + } else { if (table->tmp_table) { if (find_temporary_table(thd,new_db,new_name_buff)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); DBUG_RETURN(-1); } } @@ -2039,14 +2075,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, F_OK)) { /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); DBUG_RETURN(-1); } } } } else - new_name=table_name; + new_alias= new_name= table_name; old_db_type=table->db_type; if (create_info->db_type == DB_TYPE_DEFAULT) @@ -2083,7 +2119,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { *fn_ext(new_name)=0; close_cached_table(thd, table); - if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name)) + if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) error= -1; } VOID(pthread_mutex_unlock(&LOCK_open)); @@ -2108,14 +2144,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); table->file->deactivate_non_unique_index(HA_POS_ERROR); + /* COND_refresh will be signaled in close_thread_tables() */ } else push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), table->table_name); - break; - - /* COND_refresh will be signaled in close_thread_tables() */ break; } } @@ -2147,7 +2181,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) create_info->default_table_charset= table->table_charset; - restore_record(table,default_values); // Empty record for DEFAULT + restore_record(table,default_values); // Empty record for DEFAULT List_iterator<Alter_drop> drop_it(drop_list); List_iterator<create_field> def_it(fields); List_iterator<Alter_column> alter_it(alter_list); @@ -2493,7 +2527,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* Remove link to old table and rename the new one */ close_temporary_table(thd,table->table_cache_key,table_name); - if (rename_temporary_table(thd, new_table, new_db, new_name)) + if (rename_temporary_table(thd, new_table, new_db, new_alias)) { // Fatal error close_temporary_table(thd,new_db,tmp_name); my_free((gptr) new_table,MYF(0)); @@ -2569,12 +2603,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, VOID(quick_rm_table(new_db_type,new_db,tmp_name)); } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, - new_name)) + new_alias)) { // Try to get everything back error=1; - VOID(quick_rm_table(new_db_type,new_db,new_name)); + VOID(quick_rm_table(new_db_type,new_db,new_alias)); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); - VOID(mysql_rename_table(old_db_type,db,old_name,db,table_name)); + VOID(mysql_rename_table(old_db_type,db,old_name,db,alias)); } if (error) { diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 6e8aae54b23..a4461beed29 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -120,6 +120,7 @@ void udf_init() udf_func *tmp; TABLE_LIST tables; READ_RECORD read_record_info; + TABLE *table; int error; DBUG_ENTER("ufd_init"); @@ -152,13 +153,11 @@ void udf_init() if (simple_open_n_lock_tables(new_thd, &tables)) { DBUG_PRINT("error",("Can't open udf table")); - sql_print_error("Can't open mysql/func table"); - close_thread_tables(new_thd); - delete new_thd; - DBUG_VOID_RETURN; + sql_print_error("Can't open the mysql/func table. Please run the mysql_install_db script to create it."); + goto end; } - TABLE *table = tables.table; + table= tables.table; init_read_record(&read_record_info, new_thd, table, NULL,1,0); while (!(error = read_record_info.read_record(&read_record_info))) { @@ -206,6 +205,8 @@ void udf_init() sql_print_error(ER(ER_GET_ERRNO), my_errno); end_read_record(&read_record_info); new_thd->version--; // Force close to free memory + +end: close_thread_tables(new_thd); delete new_thd; /* Remember that we don't have a THD */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index df7b2cf809f..977dd2595de 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -15,8 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Update of records - Multi-table updates were introduced by Monty and Sinisa <sinisa@mysql.com> +/* + Single table and multi table updates of tables. + Multi-table updates were introduced by Sinisa & Monty */ #include "mysql_priv.h" @@ -423,17 +424,31 @@ int mysql_multi_update(THD *thd, int res; multi_update *result; TABLE_LIST *tl; + table_map item_tables= 0, derived_tables= 0; DBUG_ENTER("mysql_multi_update"); -#ifndef NO_EMBEDDED_ACCESS_CHECKS - table_list->grant.want_privilege=(SELECT_ACL & ~table_list->grant.privilege); -#endif - if ((res=open_and_lock_tables(thd,table_list))) + if ((res=open_and_lock_tables(thd,table_list))) DBUG_RETURN(res); select_lex->select_limit= HA_POS_ERROR; - table_map item_tables= 0, derived_tables= 0; + /* + Ensure that we have update privilege for all tables and columns in the + SET part + */ + for (tl= table_list ; tl ; tl=tl->next) + { + TABLE *table= tl->table; + /* + 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" + */ + if (!tl->derived) + table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege); + } + if (thd->lex->derived_tables) { // Assign table map values to check updatability of derived tables @@ -464,6 +479,9 @@ int mysql_multi_update(THD *thd, for (tl= select_lex->get_table_list() ; tl ; tl= tl->next) { TABLE *table= tl->table; + + /* We only need SELECT privilege for columns in the values list */ + table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege); if (table->timestamp_field) { table->time_stamp=0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c5b75180c69..009840b03b8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -597,7 +597,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_table_alias %type <table> - table_ident references + table_ident table_ident_ref references %type <simple_string> remember_name remember_end opt_ident opt_db text_or_password @@ -4623,8 +4623,13 @@ field_ident: table_ident: ident { $$=new Table_ident($1); } | ident '.' ident { $$=new Table_ident(YYTHD, $1,$3,0);} - | '.' ident { $$=new Table_ident($2);} - /* For Delphi */; + | '.' ident { $$=new Table_ident($2);} /* For Delphi */ + ; + +table_ident_ref: + ident { LEX_STRING db={(char*) any_db,3}; $$=new Table_ident(YYTHD, db,$1,0); } + | ident '.' ident { $$=new Table_ident(YYTHD, $1,$3,0);} + ; IDENT_sys: IDENT { $$= $1; } @@ -5128,14 +5133,14 @@ handler: if (!lex->current_select->add_table_to_list(lex->thd, $2, $4, 0)) YYABORT; } - | HANDLER_SYM table_ident CLOSE_SYM + | HANDLER_SYM table_ident_ref CLOSE_SYM { LEX *lex= Lex; lex->sql_command = SQLCOM_HA_CLOSE; if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0)) YYABORT; } - | HANDLER_SYM table_ident READ_SYM + | HANDLER_SYM table_ident_ref READ_SYM { LEX *lex=Lex; lex->sql_command = SQLCOM_HA_READ; diff --git a/sql/table.cc b/sql/table.cc index 8fe061af530..dfd0529f62a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -581,7 +581,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { if ((index_flags & HA_KEY_READ_ONLY) && (field->key_type() != HA_KEYTYPE_TEXT || - (!(ha_option & HA_KEY_READ_WRONG_STR) && + (!((ha_option & HA_KEY_READ_WRONG_STR) || + (field->flags & BINARY_FLAG)) && !(keyinfo->flags & HA_FULLTEXT)))) field->part_of_key.set_bit(key); if ((field->key_type() != HA_KEYTYPE_TEXT || diff --git a/sql/time.cc b/sql/time.cc index 9a18a150c50..1dff0c62edf 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -62,6 +62,9 @@ long my_gmt_sec(TIME *t, long *my_timezone) struct tm *l_time,tm_tmp; long diff, current_timezone; + if (t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR) + return 0; + if (t->hour >= 24) { /* Fix for time-loop */ t->day+=t->hour/24; @@ -124,8 +127,10 @@ long my_gmt_sec(TIME *t, long *my_timezone) tmp-=t->minute*60 + t->second; // Move to previous hour } *my_timezone= current_timezone; - if (tmp < 0 && t->year <= 1900+YY_PART_YEAR) + + if (tmp < TIMESTAMP_MIN_VALUE || tmp > TIMESTAMP_MAX_VALUE) tmp= 0; + return (long) tmp; } /* my_gmt_sec */ @@ -634,15 +639,12 @@ time_t str_to_timestamp(const char *str,uint length) { TIME l_time; long not_used; + time_t timestamp= 0; - if (str_to_TIME(str,length,&l_time,0) <= TIMESTAMP_DATETIME_ERROR) - return(0); - if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1) - { + if (str_to_TIME(str,length,&l_time,0) > TIMESTAMP_DATETIME_ERROR && + !(timestamp= my_gmt_sec(&l_time, ¬_used))) current_thd->cuted_fields++; - return(0); - } - return(my_gmt_sec(&l_time, ¬_used)); + return timestamp; } diff --git a/sql/unireg.cc b/sql/unireg.cc index 6ebba313442..357ba016fcb 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -29,6 +29,7 @@ #include <m_ctype.h> #define FCOMP 17 /* Bytes for a packed field */ +#define FCOMP 17 /* Bytes for a packed field */ static uchar * pack_screens(List<create_field> &create_fields, uint *info_length, uint *screens, bool small_file); @@ -150,7 +151,7 @@ int rea_create_table(THD *thd, my_string file_name, my_free((gptr) screen_buff,MYF(0)); my_free((gptr) keybuff, MYF(0)); - if (my_sync(file, MYF(MY_WME))) + if (opt_sync_frm && my_sync(file, MYF(MY_WME))) goto err2; if (my_close(file,MYF(MY_WME)) || ha_create_table(file_name,create_info,0)) |