summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc7
-rw-r--r--sql/field.h6
-rw-r--r--sql/filesort.cc42
-rw-r--r--sql/ha_berkeley.cc34
-rw-r--r--sql/ha_berkeley.h9
-rw-r--r--sql/ha_heap.cc1
-rw-r--r--sql/ha_innodb.cc50
-rw-r--r--sql/ha_innodb.h1
-rw-r--r--sql/ha_isam.cc2
-rw-r--r--sql/ha_isam.h2
-rw-r--r--sql/ha_isammrg.h2
-rw-r--r--sql/ha_myisam.cc2
-rw-r--r--sql/ha_myisam.h3
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/ha_myisammrg.h2
-rw-r--r--sql/handler.cc30
-rw-r--r--sql/handler.h16
-rw-r--r--sql/item_cmpfunc.h9
-rw-r--r--sql/item_func.cc6
-rw-r--r--sql/key.cc4
-rw-r--r--sql/log_event.cc20
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/mysql_priv.h14
-rw-r--r--sql/mysqld.cc78
-rw-r--r--sql/opt_range.cc39
-rw-r--r--sql/set_var.cc39
-rw-r--r--sql/share/czech/errmsg.txt5
-rw-r--r--sql/share/danish/errmsg.txt7
-rw-r--r--sql/share/dutch/errmsg.txt7
-rw-r--r--sql/share/english/errmsg.txt3
-rw-r--r--sql/share/estonian/errmsg.txt5
-rw-r--r--sql/share/french/errmsg.txt5
-rw-r--r--sql/share/german/errmsg.txt7
-rw-r--r--sql/share/greek/errmsg.txt5
-rw-r--r--sql/share/hungarian/errmsg.txt5
-rw-r--r--sql/share/italian/errmsg.txt7
-rw-r--r--sql/share/japanese/errmsg.txt5
-rw-r--r--sql/share/korean/errmsg.txt5
-rw-r--r--sql/share/norwegian-ny/errmsg.txt5
-rw-r--r--sql/share/norwegian/errmsg.txt5
-rw-r--r--sql/share/polish/errmsg.txt5
-rw-r--r--sql/share/portuguese/errmsg.txt7
-rw-r--r--sql/share/romanian/errmsg.txt5
-rw-r--r--sql/share/russian/errmsg.txt7
-rw-r--r--sql/share/slovak/errmsg.txt5
-rw-r--r--sql/share/spanish/errmsg.txt7
-rw-r--r--sql/share/swedish/errmsg.txt11
-rw-r--r--sql/share/ukrainian/errmsg.txt7
-rw-r--r--sql/slave.cc8
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc51
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_db.cc34
-rw-r--r--sql/sql_handler.cc7
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_load.cc36
-rw-r--r--sql/sql_parse.cc205
-rw-r--r--sql/sql_rename.cc26
-rw-r--r--sql/sql_repl.h2
-rw-r--r--sql/sql_select.cc43
-rw-r--r--sql/sql_show.cc30
-rw-r--r--sql/sql_string.cc6
-rw-r--r--sql/sql_table.cc122
-rw-r--r--sql/sql_udf.cc11
-rw-r--r--sql/sql_update.cc25
-rw-r--r--sql/sql_yacc.yy15
-rw-r--r--sql/table.cc3
-rw-r--r--sql/time.cc18
-rw-r--r--sql/unireg.cc3
70 files changed, 771 insertions, 457 deletions
diff --git a/sql/field.cc b/sql/field.cc
index cce7446dcff..4ac277dacca 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, &not_used)))
goto err;
- timestamp= my_gmt_sec(&l_time, &not_used);
}
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -5648,8 +5648,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 9a12fd48e54..0d834b48976 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..656224d4a7a 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -174,6 +174,7 @@ void ha_heap::info(uint flag)
index_file_length=info.index_length;
max_data_file_length= info.max_records* info.reclength;
delete_length= info.deleted * info.reclength;
+ implicit_emptied= info.implicit_emptied;
if (flag & HA_STATUS_AUTO)
auto_increment_value= info.auto_increment;
}
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..afeec26f034 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);
+ casedn_str(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);
+ casedn_str(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_cmpfunc.h b/sql/item_cmpfunc.h
index 7e1749ef7a0..4e9628c8db9 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -811,8 +811,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 +827,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 34a61ba0353..b337364c88a 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..84757a0a1f2 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -949,6 +949,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 +960,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 +1004,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;
}
@@ -1368,7 +1369,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,9 +1451,9 @@ 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;
@@ -1664,8 +1665,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
diff --git a/sql/log_event.h b/sql/log_event.h
index d615c0e361b..1a5f0543766 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
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 73e30e72a3c..76acc74a358 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
@@ -829,7 +832,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;
@@ -838,10 +841,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;
@@ -1074,6 +1077,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..d1f42ac865e 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,
@@ -655,7 +656,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 +839,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 +1063,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_prefix, 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 +1720,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 +2794,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 ecb85440068..93de5333f6b 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},
@@ -1017,6 +1023,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;
@@ -1333,9 +1357,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 917b2259e24..1fff3b16910 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 591e007f5a6..9e80f7e6430 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)",
@@ -294,5 +295,5 @@ character-set=latin1
"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/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 3a0d77187bf..44a92db452f 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)",
@@ -302,5 +303,5 @@ character-set=latin1
"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/english/errmsg.txt b/sql/share/english/errmsg.txt
index 38ca4966dfe..ac795af0207 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 f0882d5602b..984a988d169 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)",
@@ -296,5 +297,5 @@ character-set=latin7
"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/french/errmsg.txt b/sql/share/french/errmsg.txt
index d3c7c3ebde1..1b2778e0ddd 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)",
@@ -291,5 +292,5 @@ character-set=latin1
"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/german/errmsg.txt b/sql/share/german/errmsg.txt
index 48eff8831d5..a54f36b9c5c 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",
@@ -303,5 +304,5 @@ character-set=latin1
"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/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index 1e3c436e3d0..c2bfd1ad4a0 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)",
@@ -291,5 +292,5 @@ character-set=greek
"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/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index 402933d7ef7..5ad0aa7d3be 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)",
@@ -293,5 +294,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/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index d9be6ebb32d..20b8f96b078 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)",
@@ -291,5 +292,5 @@ character-set=latin1
"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/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index cc36dd60e85..00a8c53fce7 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)",
@@ -293,5 +294,5 @@ character-set=ujis
"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/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 0bbea735a09..ba2e523e9db 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)",
@@ -291,5 +292,5 @@ character-set=euckr
"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/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 2372e7a9690..f66372b0c35 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)",
@@ -293,5 +294,5 @@ character-set=latin1
"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/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index f946e988fb0..39f368a8b28 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)",
@@ -293,5 +294,5 @@ character-set=latin1
"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/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index c6bb914d38c..e4da21544ac 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)",
@@ -295,5 +296,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/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index 537162fc1d0..5c4e9c68d01 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)",
@@ -292,5 +293,5 @@ character-set=latin1
"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"
+"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 8da92d48883..268d6aed7db 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)",
@@ -295,5 +296,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/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index d5d91deb280..2d41badf981 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 90fbe450bb1..2e4e93d1a83 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)",
@@ -299,5 +300,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/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index 644a5c7a515..9ad72ef2641 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)",
@@ -293,5 +294,5 @@ character-set=latin1
"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/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 22a6cecd773..eaa1c26f5a3 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)",
@@ -288,8 +289,8 @@ character-set=latin1
"Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index",
"Unknown key 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.",
+"Okänd tabell typ '%s'",
+"'%s' är deprikerad. Använd '%s' istället.",
"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/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index 2d4ce67e2e5..84cca8d8fbb 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 c500f0cf1f7..5a03a5b7324 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 b3135202ad6..426e4552004 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1034,11 +1034,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..7a1fd091e7c 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);
+ casedn_str(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..6db97ab3c41 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= *db ? strlen(db)+1 : 0;
ptr= &(thd->handler_tables);
for (TABLE *table= *ptr; table ; table= *ptr)
{
- if (!memcmp(table->table_cache_key, db, dblen) &&
+ if ((!dblen || !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..45b76e44f28 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -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 42ea6039b6c..f7bbfdae2b3 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
@@ -1146,9 +1146,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);
@@ -1453,9 +1451,8 @@ 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))
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);
@@ -1472,10 +1469,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;
@@ -1483,15 +1482,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;
@@ -1504,7 +1504,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
@@ -1769,7 +1769,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));
@@ -2101,6 +2103,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= tables->alias;
if (check_access(thd, want_priv, create_table->db,
&create_table->grant.privilege, 0, 0) ||
check_merge_table_access(thd, create_table->db,
@@ -2186,12 +2189,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;
@@ -2247,8 +2246,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) ||
@@ -2257,8 +2254,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))
@@ -2454,16 +2449,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,
@@ -2476,36 +2470,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:
{
@@ -2513,7 +2519,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)
{
@@ -2539,13 +2545,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;
}
@@ -2586,9 +2589,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
@@ -2603,7 +2604,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);
@@ -2728,8 +2729,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;
@@ -2738,12 +2739,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
@@ -2852,16 +2849,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,
@@ -2877,18 +2869,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))
+ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0))
goto error;
res= mysqld_show_keys(thd,tables);
@@ -2917,9 +2902,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,
@@ -2968,7 +2951,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;
@@ -2991,12 +2976,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.options,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;
@@ -3024,7 +3012,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:
@@ -3377,19 +3365,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))
@@ -3919,12 +3907,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)) ==
@@ -4670,7 +4658,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 ea5050f2550..9cb8bb7b768 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 & ((key_map) 1 << 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)
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4da2522bd3f..0929167ad37 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();
@@ -1146,7 +1150,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;
@@ -1172,7 +1176,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++)
@@ -1220,7 +1226,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 093b85b46b7..422b1ec3b4b 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -701,9 +701,9 @@ void String::qs_append(const char &c)
int sortcmp(const String *x,const String *y, CHARSET_INFO *cs)
{
- return cs->coll->strnncollsp(cs,
- (unsigned char *) x->ptr(),x->length(),
- (unsigned char *) y->ptr(),y->length());
+ return cs->coll->strnncollsp(cs,
+ (unsigned char *) x->ptr(),x->length(),
+ (unsigned char *) y->ptr(),y->length());
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4e66154e2a2..922775083d5 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) &&
@@ -955,7 +958,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)
@@ -966,7 +969,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))
@@ -1111,7 +1114,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;
@@ -1120,7 +1123,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);
@@ -1135,18 +1138,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);
+ casedn_str(tmp_from);
+ old_name= tmp_from;
+
+ strmov(tmp_to, new_name);
+ casedn_str(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))
@@ -1162,6 +1179,7 @@ mysql_rename_table(enum db_type base,
DBUG_RETURN(error != 0);
}
+
/*
Force all other threads to stop using the table
@@ -1206,7 +1224,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
@@ -1969,8 +1987,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;
@@ -1981,9 +1999,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);
@@ -1991,7 +2013,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);
@@ -1999,18 +2021,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);
}
}
@@ -2020,14 +2056,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)
@@ -2064,7 +2100,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));
@@ -2089,14 +2125,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;
}
}
@@ -2128,7 +2162,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);
@@ -2474,7 +2508,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));
@@ -2550,12 +2584,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..1e702a9517c 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,24 @@ 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;
+ 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 +472,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 0dbe8981466..bd51df8810c 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
@@ -4622,8 +4622,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={"",0}; $$=new Table_ident(db,$1,0); }
+ | ident '.' ident { $$=new Table_ident($1,$3,0);}
+ ;
IDENT_sys:
IDENT { $$= $1; }
@@ -5127,14 +5132,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, &not_used)))
current_thd->cuted_fields++;
- return(0);
- }
- return(my_gmt_sec(&l_time, &not_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))