summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authormonty@mysql.com <>2004-07-12 08:20:24 +0300
committermonty@mysql.com <>2004-07-12 08:20:24 +0300
commit31fe2837f9c0579454cba635ee127536a6ac55ce (patch)
tree4b4523bbabccb4e51b85fc209e3274f249f85ef8 /sql
parentfa7f63d46d033c1c1651d8f5155070e30c607023 (diff)
parent79b3b220be3e914bf2fded18a503895de212389a (diff)
downloadmariadb-git-31fe2837f9c0579454cba635ee127536a6ac55ce.tar.gz
Merge with 4.1
Diffstat (limited to 'sql')
-rw-r--r--sql/examples/ha_archive.cc2
-rw-r--r--sql/examples/ha_archive.h2
-rw-r--r--sql/examples/ha_example.h8
-rw-r--r--sql/field.cc4
-rw-r--r--sql/field.h4
-rw-r--r--sql/ha_berkeley.cc29
-rw-r--r--sql/ha_berkeley.h9
-rw-r--r--sql/ha_heap.h2
-rw-r--r--sql/ha_innodb.h2
-rw-r--r--sql/ha_isam.h2
-rw-r--r--sql/ha_isammrg.h3
-rw-r--r--sql/ha_myisam.h6
-rw-r--r--sql/ha_myisammrg.h6
-rw-r--r--sql/ha_ndbcluster.cc3
-rw-r--r--sql/ha_ndbcluster.h2
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item_cmpfunc.cc9
-rw-r--r--sql/item_geofunc.cc8
-rw-r--r--sql/item_strfunc.cc37
-rw-r--r--sql/log.cc7
-rw-r--r--sql/log_event.cc47
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/mysqld.cc27
-rw-r--r--sql/opt_range.cc195
-rw-r--r--sql/opt_sum.cc13
-rw-r--r--sql/set_var.cc14
-rw-r--r--sql/share/charsets/Index.xml2
-rw-r--r--sql/share/charsets/armscii8.xml2
-rw-r--r--sql/share/czech/errmsg.txt1
-rw-r--r--sql/share/danish/errmsg.txt1
-rw-r--r--sql/share/dutch/errmsg.txt1
-rw-r--r--sql/share/english/errmsg.txt1
-rw-r--r--sql/share/estonian/errmsg.txt1
-rw-r--r--sql/share/french/errmsg.txt1
-rw-r--r--sql/share/german/errmsg.txt1
-rw-r--r--sql/share/greek/errmsg.txt1
-rw-r--r--sql/share/hungarian/errmsg.txt1
-rw-r--r--sql/share/italian/errmsg.txt1
-rw-r--r--sql/share/japanese/errmsg.txt3
-rw-r--r--sql/share/korean/errmsg.txt1
-rw-r--r--sql/share/norwegian-ny/errmsg.txt1
-rw-r--r--sql/share/norwegian/errmsg.txt1
-rw-r--r--sql/share/polish/errmsg.txt1
-rw-r--r--sql/share/portuguese/errmsg.txt1
-rw-r--r--sql/share/romanian/errmsg.txt1
-rw-r--r--sql/share/russian/errmsg.txt1
-rw-r--r--sql/share/serbian/errmsg.txt1
-rw-r--r--sql/share/slovak/errmsg.txt1
-rw-r--r--sql/share/spanish/errmsg.txt5
-rw-r--r--sql/share/swedish/errmsg.txt5
-rw-r--r--sql/share/ukrainian/errmsg.txt5
-rw-r--r--sql/sql_acl.cc5
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_db.cc266
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_select.cc14
-rw-r--r--sql/sql_show.cc10
-rw-r--r--sql/sql_table.cc17
-rw-r--r--sql/sql_update.cc5
-rw-r--r--sql/sql_yacc.yy20
-rw-r--r--sql/table.cc19
61 files changed, 623 insertions, 237 deletions
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc
index e052a819ef8..a4fe2aaa8cc 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/examples/ha_archive.cc
@@ -188,9 +188,9 @@ static int free_share(ARCHIVE_SHARE *share)
hash_delete(&archive_open_tables, (byte*) share);
thr_lock_delete(&share->lock);
pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
if (gzclose(share->archive_write) == Z_ERRNO)
rc= -1;
+ my_free((gptr) share, MYF(0));
}
pthread_mutex_unlock(&archive_mutex);
diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h
index 03e296d0eae..2fab80f0598 100644
--- a/sql/examples/ha_archive.h
+++ b/sql/examples/ha_archive.h
@@ -72,7 +72,7 @@ public:
return (HA_REC_NOT_IN_SEQ | HA_NOT_EXACT_COUNT | HA_NO_AUTO_INCREMENT |
HA_FILE_BASED);
}
- ulong index_flags(uint idx, uint part) const
+ ulong index_flags(uint idx, uint part, bool all_parts) const
{
return 0;
}
diff --git a/sql/examples/ha_example.h b/sql/examples/ha_example.h
index dc8f265c16e..3c6ce4220ee 100644
--- a/sql/examples/ha_example.h
+++ b/sql/examples/ha_example.h
@@ -69,12 +69,16 @@ public:
return 0;
}
/*
- This is a list of flags that says how the storage engine
+ This is a bitmap of flags that says how the storage engine
implements indexes. The current index flags are documented in
handler.h. If you do not implement indexes, just return zero
here.
+
+ part is the key part to check. First key part is 0
+ If all_parts it's set, MySQL want to know the flags for the combined
+ index up to and including 'part'.
*/
- ulong index_flags(uint inx, uint part) const
+ ulong index_flags(uint inx, uint part, bool all_parts) const
{
return 0;
}
diff --git a/sql/field.cc b/sql/field.cc
index 2d3729817b7..26c84575b4d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -431,9 +431,9 @@ void Field::store_time(TIME *ltime,timestamp_type type)
}
-bool Field::optimize_range(uint idx)
+bool Field::optimize_range(uint idx, uint part)
{
- return test(table->file->index_flags(idx) & HA_READ_RANGE);
+ return test(table->file->index_flags(idx, part, 1) & HA_READ_RANGE);
}
/****************************************************************************
diff --git a/sql/field.h b/sql/field.h
index a2fe77e18a3..24faee9d314 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -178,7 +178,7 @@ public:
inline bool real_maybe_null(void) { return null_ptr != 0; }
virtual void make_field(Send_field *)=0;
virtual void sort_string(char *buff,uint length)=0;
- virtual bool optimize_range(uint idx);
+ virtual bool optimize_range(uint idx, uint part);
virtual bool store_for_compare() { return 0; }
virtual void free() {}
Field *new_field(MEM_ROOT *root, struct st_table *new_table)
@@ -1134,7 +1134,7 @@ public:
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_ENUM; }
virtual bool zero_pack() const { return 0; }
- bool optimize_range(uint idx) { return 0; }
+ bool optimize_range(uint idx, uint part) { return 0; }
bool eq_def(Field *field);
bool has_charset(void) const { return TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index e25640280a3..00df84e3797 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -340,6 +340,35 @@ const char **ha_berkeley::bas_ext() const
{ static const char *ext[]= { ha_berkeley_ext, NullS }; return ext; }
+ulong ha_berkeley::index_flags(uint idx, uint part, bool all_parts) const
+{
+ ulong flags= (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEYREAD_ONLY
+ | HA_READ_RANGE);
+ for (uint i= all_parts ? 0 : part ; i <= part ; i++)
+ {
+ if (table->key_info[idx].key_part[i].field->type() == FIELD_TYPE_BLOB)
+ {
+ /* We can't use BLOBS to shortcut sorts */
+ flags&= ~(HA_READ_ORDER | HA_KEYREAD_ONLY | HA_READ_RANGE);
+ break;
+ }
+ switch (table->key_info[idx].key_part[i].field->key_type()) {
+ case HA_KEYTYPE_TEXT:
+ case HA_KEYTYPE_VARTEXT:
+ /*
+ As BDB stores only one copy of equal strings, we can't use key read
+ on these
+ */
+ flags&= ~HA_KEYREAD_ONLY;
+ break;
+ default: // Keep compiler happy
+ break;
+ }
+ }
+ return flags;
+}
+
+
static int
berkeley_cmp_hidden_key(DB* file, const DBT *new_key, const DBT *saved_key)
{
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 3213a81fadf..975d70abf7b 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -94,14 +94,7 @@ class ha_berkeley: public handler
changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) {}
~ha_berkeley() {}
const char *table_type() const { return "BerkeleyDB"; }
- ulong index_flags(uint idx, uint part) const
- {
- ulong flags=HA_READ_NEXT | HA_READ_PREV;
- if (part == (uint)~0 ||
- table->key_info[idx].key_part[part].field->key_type() != HA_KEYTYPE_TEXT)
- flags|= HA_READ_ORDER | HA_KEYREAD_ONLY | HA_READ_RANGE;
- return flags;
- }
+ ulong index_flags(uint idx, uint part, bool all_parts) const;
const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
ulong table_flags(void) const { return int_table_flags; }
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 9d0b9999300..c326f570feb 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -44,7 +44,7 @@ class ha_heap: public handler
HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME |
HA_CAN_INSERT_DELAYED);
}
- ulong index_flags(uint inx, uint part) const
+ ulong index_flags(uint inx, uint part, bool all_parts) const
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 0a86f4adf3c..a158321c5df 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -94,7 +94,7 @@ class ha_innobase: public handler
const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const;
ulong table_flags() const { return int_table_flags; }
- ulong index_flags(uint idx, uint part) const
+ ulong index_flags(uint idx, uint part, bool all_parts) const
{
return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE |
HA_KEYREAD_ONLY);
diff --git a/sql/ha_isam.h b/sql/ha_isam.h
index 521946a17b5..b3e932696cb 100644
--- a/sql/ha_isam.h
+++ b/sql/ha_isam.h
@@ -36,7 +36,7 @@ class ha_isam: public handler
HA_DUPP_POS | HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED)
{}
~ha_isam() {}
- ulong index_flags(uint idx, uint part) const
+ ulong index_flags(uint idx, uint part, bool all_parts) const
{ return HA_READ_NEXT; } // but no HA_READ_PREV here!!!
const char *table_type() const { return "ISAM"; }
const char *index_type(uint key_number) { return "BTREE"; }
diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h
index 166a96cf9e4..657e5060272 100644
--- a/sql/ha_isammrg.h
+++ b/sql/ha_isammrg.h
@@ -34,7 +34,8 @@ class ha_isammrg: public handler
const char **bas_ext() const;
ulong table_flags() const { return (HA_READ_RND_SAME |
HA_REC_NOT_IN_SEQ | HA_FILE_BASED); }
- ulong index_flags(uint idx, uint part) const { DBUG_ASSERT(0); return 0; }
+ ulong index_flags(uint idx, uint part, bool all_parts) const
+ { DBUG_ASSERT(0); return 0; }
uint max_supported_keys() const { return 0; }
bool low_byte_first() const { return 0; }
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index ef3f00577dd..6fde84d6f6f 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -55,11 +55,11 @@ class ha_myisam: public handler
const char *index_type(uint key_number);
const char **bas_ext() const;
ulong table_flags() const { return int_table_flags; }
- ulong index_flags(uint inx, uint part) const
+ ulong index_flags(uint inx, uint part, bool all_parts) const
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY);
+ 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY);
}
uint max_supported_keys() const { return MI_MAX_KEY; }
uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index 995cfe9ad4a..264c580220c 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -38,11 +38,11 @@ class ha_myisammrg: public handler
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
HA_CAN_INSERT_DELAYED);
}
- ulong index_flags(uint inx, uint part) const
+ ulong index_flags(uint inx, uint part, bool all_parts) const
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY);
+ 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY);
}
uint max_supported_keys() const { return MI_MAX_KEY; }
uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index d499218a8c3..5b36d6d2b55 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -524,7 +524,8 @@ inline NDB_INDEX_TYPE ha_ndbcluster::get_index_type(uint idx_no) const
flags depending on the type of the index.
*/
-inline ulong ha_ndbcluster::index_flags(uint idx_no, uint part) const
+inline ulong ha_ndbcluster::index_flags(uint idx_no, uint part,
+ bool all_parts) const
{
DBUG_ENTER("index_flags");
DBUG_PRINT("info", ("idx_no: %d", idx_no));
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 39c1779a27a..f094b79ef35 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -93,7 +93,7 @@ class ha_ndbcluster: public handler
const char * table_type() const { return("ndbcluster");}
const char ** bas_ext() const;
ulong table_flags(void) const { return m_table_flags; }
- ulong index_flags(uint idx, uint part) const;
+ ulong index_flags(uint idx, uint part, bool all_parts) const;
uint max_supported_record_length() const { return NDB_MAX_TUPLE_SIZE; };
uint max_supported_keys() const { return MAX_KEY; }
uint max_supported_key_parts() const
diff --git a/sql/handler.h b/sql/handler.h
index 13874fa6bb0..2cc0858f26c 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -449,7 +449,7 @@ public:
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
virtual ulong table_flags(void) const =0;
- virtual ulong index_flags(uint idx, uint part=~0) const =0;
+ virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
virtual ulong index_ddl_flags(KEY *wanted_index) const
{ return (HA_DDL_SUPPORT); }
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 91257c31fb9..60f80249e94 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -483,7 +483,14 @@ bool Item_in_optimizer::fix_left(THD *thd,
return 1;
cache->setup(args[0]);
- cache->store(args[0]);
+ /*
+ If it is preparation PS only then we do not know values of parameters =>
+ cant't get there values and do not need that values.
+
+ TODO: during merge with 5.0 it should be changed on !thd->only_prepare()
+ */
+ if (!thd->current_statement)
+ cache->store(args[0]);
if (cache->cols() == 1)
{
if ((used_tables_cache= args[0]->used_tables()))
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index d95271a54bb..66a223f0ebf 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -313,12 +313,12 @@ err:
/*
- Functions to concatinate various spatial objects
+ Functions to concatenate various spatial objects
*/
/*
-* Concatinate doubles into Point
+* Concatenate doubles into Point
*/
@@ -343,7 +343,7 @@ String *Item_func_point::val_str(String *str)
/*
- Concatinates various items into various collections
+ Concatenates various items into various collections
with checkings for valid wkb type of items.
For example, MultiPoint can be a collection of Points only.
coll_type contains wkb type of target collection.
@@ -388,7 +388,7 @@ String *Item_func_spatial_collection::val_str(String *str)
const char *data= res->ptr() + 1;
/*
- In the case of named collection we must to check that items
+ In the case of named collection we must check that items
are of specific type, let's do this checking now
*/
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index b0c685c1c46..a8805be7854 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2294,40 +2294,49 @@ inline int hexchar_to_int(char c)
return -1;
}
+
+ /* Convert given hex string to a binary string */
+
String *Item_func_unhex::val_str(String *str)
{
- DBUG_ASSERT(fixed == 1);
- /* Convert given hex string to a binary string */
- String *res= args[0]->val_str(str);
- const char *from=res->ptr(), *end;
+ const char *from, *end;
char *to;
- int r;
- if (!res || tmp_value.alloc((1+res->length())/2))
+ String *res;
+ uint length;
+ DBUG_ASSERT(fixed == 1);
+
+ res= args[0]->val_str(str);
+ if (!res || tmp_value.alloc(length= (1+res->length())/2))
{
null_value=1;
return 0;
}
- null_value=0;
- tmp_value.length((1+res->length())/2);
+
+ from= res->ptr();
+ null_value= 0;
+ tmp_value.length(length);
to= (char*) tmp_value.ptr();
if (res->length() % 2)
{
- *to++= r= hexchar_to_int(*from++);
- if ((null_value= (r == -1)))
+ int hex_char;
+ *to++= hex_char= hexchar_to_int(*from++);
+ if ((null_value= (hex_char == -1)))
return 0;
}
for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
{
- *to= (r= hexchar_to_int(from[0])) << 4;
- if ((null_value= (r == -1)))
+ int hex_char;
+ *to= (hex_char= hexchar_to_int(from[0])) << 4;
+ if ((null_value= (hex_char == -1)))
return 0;
- *to|= r= hexchar_to_int(from[1]);
- if ((null_value= (r == -1)))
+ *to|= hex_char= hexchar_to_int(from[1]);
+ if ((null_value= (hex_char == -1)))
return 0;
}
return &tmp_value;
}
+
void Item_func_binary::print(String *str)
{
str->append("cast(", 5);
diff --git a/sql/log.cc b/sql/log.cc
index 225aaae0549..ed4d6c8521e 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2108,10 +2108,8 @@ bool flush_error_log()
bool MYSQL_LOG::cut_spurious_tail()
{
int error= 0;
- char llbuf1[22], llbuf2[22];
- ulonglong actual_size;
-
DBUG_ENTER("cut_spurious_tail");
+
#ifdef HAVE_INNOBASE_DB
if (have_innodb != SHOW_OPTION_YES)
DBUG_RETURN(0);
@@ -2121,6 +2119,9 @@ bool MYSQL_LOG::cut_spurious_tail()
*/
char *name= ha_innobase::get_mysql_bin_log_name();
ulonglong pos= ha_innobase::get_mysql_bin_log_pos();
+ ulonglong actual_size;
+ char llbuf1[22], llbuf2[22];
+
if (name[0] == 0 || pos == ULONGLONG_MAX)
{
DBUG_PRINT("info", ("InnoDB has not set binlog info"));
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3b69e1c3176..6207bf1b4dc 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2422,9 +2422,9 @@ void Load_log_event::set_fields(List<Item> &field_list)
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
bool use_rli_only_for_errors)
{
+ char *load_data_query= 0;
thd->db= (char*) rewrite_db(db);
DBUG_ASSERT(thd->query == 0);
- thd->query= 0; // Should not be needed
thd->query_length= 0; // Should not be needed
thd->query_error= 0;
clear_all_errors(thd, rli);
@@ -2476,6 +2476,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
{
char llbuff[22];
enum enum_duplicates handle_dup;
+ /*
+ Make a simplified LOAD DATA INFILE query, for the information of the
+ user in SHOW PROCESSLIST. Note that db is known in the 'db' column.
+ */
+ if ((load_data_query= (char *) my_alloca(18 + strlen(fname) + 14 +
+ strlen(tables.real_name) + 8)))
+ {
+ thd->query_length= (uint)(strxmov(load_data_query,
+ "LOAD DATA INFILE '", fname,
+ "' INTO TABLE `", tables.real_name,
+ "` <...>", NullS) - load_data_query);
+ thd->query= load_data_query;
+ }
if (sql_ex.opt_flags & REPLACE_FLAG)
handle_dup= DUP_REPLACE;
else if (sql_ex.opt_flags & IGNORE_FLAG)
@@ -2557,9 +2570,14 @@ Slave: load data infile on table '%s' at log position %s in log \
}
thd->net.vio = 0;
- /* Same reason as in Query_log_event::exec_event() */
- thd->db= thd->catalog= 0;
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->db= thd->catalog= 0;
+ thd->query= 0;
+ thd->query_length= 0;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
close_thread_tables(thd);
+ if (load_data_query)
+ my_afree(load_data_query);
if (thd->query_error)
{
/* this err/sql_errno code is copy-paste from send_error() */
@@ -3114,17 +3132,18 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
> the string constant is still unescaped according to SJIS, not
> according to UCS2.
*/
- char *p, *q;
- if (!(p= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits per byte
+ char *hex_str;
+ CHARSET_INFO *cs;
+
+ if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
break; // no error, as we are 'void'
- str_to_hex(p, val, val_len);
+ str_to_hex(hex_str, val, val_len);
/*
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
specify the variable's collation. It will however cause problems when
people want to mysqlbinlog|mysql into another server not supporting the
character set. But there's not much to do about this and it's unlikely.
*/
- CHARSET_INFO *cs;
if (!(cs= get_charset(charset_number, MYF(0))))
/*
Generate an unusable command (=> syntax error) is probably the best
@@ -3132,8 +3151,8 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
*/
fprintf(file, ":=???;\n");
else
- fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, p, cs->name);
- my_afree(p);
+ fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, hex_str, cs->name);
+ my_afree(hex_str);
}
break;
case ROW_RESULT:
@@ -3601,7 +3620,7 @@ void Create_file_log_event::pack_info(Protocol *protocol)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
{
- char fname_buf[FN_REFLEN+10];
+ char proc_info[17+FN_REFLEN+10], *fname_buf= proc_info+17;
char *p;
int fd = -1;
IO_CACHE file;
@@ -3610,6 +3629,8 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
bzero((char*)&file, sizeof(file));
p = slave_load_file_stem(fname_buf, file_id, server_id);
strmov(p, ".info"); // strmov takes less code than memcpy
+ strnmov(proc_info, "Making temp file ", 17); // no end 0
+ thd->proc_info= proc_info;
if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
MYF(MY_WME))) < 0 ||
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
@@ -3653,6 +3674,7 @@ err:
end_io_cache(&file);
if (fd >= 0)
my_close(fd, MYF(0));
+ thd->proc_info= 0;
return error ? 1 : Log_event::exec_event(rli);
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -3755,13 +3777,15 @@ void Append_block_log_event::pack_info(Protocol *protocol)
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
{
- char fname[FN_REFLEN+10];
+ char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
char *p= slave_load_file_stem(fname, file_id, server_id);
int fd;
int error = 1;
DBUG_ENTER("Append_block_log_event::exec_event");
memcpy(p, ".data", 6);
+ strnmov(proc_info, "Making temp file ", 17); // no end 0
+ thd->proc_info= proc_info;
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
{
slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname);
@@ -3777,6 +3801,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
err:
if (fd >= 0)
my_close(fd, MYF(0));
+ thd->proc_info= 0;
DBUG_RETURN(error ? error : Log_event::exec_event(rli));
}
#endif
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4c4cf6db4be..fbe8489f7e4 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -675,6 +675,8 @@ int mysqld_show_variables(THD *thd,const char *wild);
int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
enum enum_var_type value_type,
pthread_mutex_t *mutex);
+int mysql_find_files(THD *thd,List<char> *files, const char *db,
+ const char *path, const char *wild, bool dir);
int mysqld_show_charsets(THD *thd,const char *wild);
int mysqld_show_collations(THD *thd,const char *wild);
int mysqld_show_storage_engines(THD *thd);
@@ -844,6 +846,9 @@ bool is_keyword(const char *name, uint len);
#define MY_DB_OPT_FILE "db.opt"
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
+bool my_dbopt_init(void);
+void my_dbopt_cleanup(void);
+void my_dbopt_free(void);
/*
External variables
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 564a8090b23..9e14ec490f6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -890,6 +890,7 @@ extern "C" void unireg_abort(int exit_code)
}
#endif
+
void clean_up(bool print_message)
{
DBUG_PRINT("exit",("clean_up"));
@@ -905,6 +906,7 @@ void clean_up(bool print_message)
bitmap_free(&slave_error_mask);
#endif
my_tz_free();
+ my_dbopt_free();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
acl_free(1);
grant_free();
@@ -1303,6 +1305,19 @@ void yyerror(const char *s)
#ifndef EMBEDDED_LIBRARY
+/*
+ Close a connection
+
+ SYNOPSIS
+ close_connection()
+ thd Thread handle
+ errcode Error code to print to console
+ lock 1 if we have have to lock LOCK_thread_count
+
+ NOTES
+ For the connection that is doing shutdown, this is called twice
+*/
+
void close_connection(THD *thd, uint errcode, bool lock)
{
st_vio *vio;
@@ -2282,7 +2297,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
*/
global_system_variables.time_zone= my_tz_SYSTEM;
-
/*
Init mutexes for the global MYSQL_LOG objects.
As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
@@ -2388,6 +2402,9 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
+ if (my_dbopt_init())
+ return 1;
+
return 0;
}
@@ -4755,26 +4772,26 @@ log and this option does nothing anymore.",
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
(gptr*) &dflt_key_cache_var.param_buff_size,
(gptr*) 0,
- 0, (enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
+ 0, (GET_ULL | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
IO_SIZE, 0},
{"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
"The default size of key cache blocks",
(gptr*) &dflt_key_cache_var.param_block_size,
(gptr*) 0,
- 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
+ 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
"The minimum percentage of warm blocks in key cache",
(gptr*) &dflt_key_cache_var.param_division_limit,
(gptr*) 0,
- 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
+ 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
1, 100, 0, 1, 0},
{"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
"This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",
(gptr*) &dflt_key_cache_var.param_age_threshold,
(gptr*) 0,
- 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
+ 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
300, 100, ~0L, 0, 100, 0},
{"long_query_time", OPT_LONG_QUERY_TIME,
"Log all queries that have taken more than long_query_time seconds to execute to file.",
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 9c1d5208bbd..68360f91191 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -343,7 +343,7 @@ typedef struct st_qsel_param {
uint *imerge_cost_buff; /* buffer for index_merge cost estimates */
uint imerge_cost_buff_size; /* size of the buffer */
- /* true if last checked tree->key can be used for ROR-scan */
+ /* TRUE if last checked tree->key can be used for ROR-scan */
bool is_ror_scan;
} PARAM;
@@ -585,7 +585,7 @@ inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
i.e. all conjuncts except the first one are currently dropped.
This is done to avoid producing N*K ways to do index_merge.
- If (a_1||b_1) produce a condition that is always true, NULL is returned
+ If (a_1||b_1) produce a condition that is always TRUE, NULL is returned
and index_merge is discarded (while it is actually possible to try
harder).
@@ -848,7 +848,7 @@ int QUICK_ROR_INTERSECT_SELECT::init()
SYNOPSIS
QUICK_RANGE_SELECT::init_ror_merged_scan()
- reuse_handler If true, use head->file, otherwise create a separate
+ reuse_handler If TRUE, use head->file, otherwise create a separate
handler object
NOTES
@@ -906,7 +906,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
file->close();
goto failure;
}
- free_file= true;
+ free_file= TRUE;
last_rowid= file->ref;
DBUG_RETURN(0);
@@ -920,7 +920,7 @@ failure:
Initialize this quick select to be a part of a ROR-merged scan.
SYNOPSIS
QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan()
- reuse_handler If true, use head->file, otherwise create separate
+ reuse_handler If TRUE, use head->file, otherwise create separate
handler object.
RETURN
0 OK
@@ -941,13 +941,13 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
There is no use of this->file. Use it for the first of merged range
selects.
*/
- if (quick->init_ror_merged_scan(true))
+ if (quick->init_ror_merged_scan(TRUE))
DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
}
while((quick= quick_it++))
{
- if (quick->init_ror_merged_scan(false))
+ if (quick->init_ror_merged_scan(FALSE))
DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
/* All merged scans share the same record buffer in intersection. */
@@ -976,7 +976,7 @@ int QUICK_ROR_INTERSECT_SELECT::reset()
{
int result;
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset");
- result= init_ror_merged_scan(true);
+ result= init_ror_merged_scan(TRUE);
DBUG_RETURN(result);
}
@@ -992,8 +992,8 @@ int QUICK_ROR_INTERSECT_SELECT::reset()
This call can only be made before init() is called.
RETURN
- false OK
- true Out of memory.
+ FALSE OK
+ TRUE Out of memory.
*/
bool
@@ -1037,7 +1037,7 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
int QUICK_ROR_UNION_SELECT::init()
{
if (init_queue(&queue, quick_selects.elements, 0,
- false , QUICK_ROR_UNION_SELECT::queue_cmp,
+ FALSE , QUICK_ROR_UNION_SELECT::queue_cmp,
(void*) this))
{
bzero(&queue, sizeof(QUEUE));
@@ -1084,7 +1084,7 @@ int QUICK_ROR_UNION_SELECT::reset()
QUICK_SELECT_I* quick;
int error;
DBUG_ENTER("QUICK_ROR_UNION_SELECT::reset");
- have_prev_rowid= false;
+ have_prev_rowid= FALSE;
/*
Initialize scans for merged quick selects and put all merged quick
selects into the queue.
@@ -1092,7 +1092,7 @@ int QUICK_ROR_UNION_SELECT::reset()
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++))
{
- if (quick->init_ror_merged_scan(false))
+ if (quick->init_ror_merged_scan(FALSE))
DBUG_RETURN(1);
if ((error= quick->get_next()))
{
@@ -1310,7 +1310,7 @@ public:
ha_rows records; /* estimate of #rows to be examined */
/*
- If true, the scan returns rows in rowid order. This is used only for
+ If TRUE, the scan returns rows in rowid order. This is used only for
scans that can be both ROR and non-ROR.
*/
bool is_ror;
@@ -1320,7 +1320,7 @@ public:
SYNOPSIS
make_quick()
param Parameter from test_quick_select
- retrieve_full_rows If true, created quick select will do full record
+ retrieve_full_rows If TRUE, created quick select will do full record
retrieval.
parent_alloc Memory pool to use, if any.
@@ -1390,7 +1390,7 @@ public:
struct st_ror_scan_info **first_scan;
struct st_ror_scan_info **last_scan; /* End of the above array */
struct st_ror_scan_info *cpk_scan; /* Clustered PK scan, if there is one */
- bool is_covering; /* true if no row retrieval phase is necessary */
+ bool is_covering; /* TRUE if no row retrieval phase is necessary */
double index_scan_costs; /* SUM(cost(index_scan)) */
};
@@ -1449,7 +1449,7 @@ static int fill_used_fields_bitmap(PARAM *param)
uint pk;
if (!(tmp= (uchar*)alloc_root(param->mem_root,param->fields_bitmap_size)) ||
bitmap_init(&param->needed_fields, tmp, param->fields_bitmap_size*8,
- false))
+ FALSE))
return 1;
bitmap_clear_all(&param->needed_fields);
@@ -1644,10 +1644,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
{
double best_read_time= read_time;
TRP_ROR_INTERSECT *new_trp;
- bool can_build_covering= false;
+ bool can_build_covering= FALSE;
/* Get best 'range' plan and prepare data for making other plans */
- if ((best_trp= get_key_scans_params(&param, tree, false,
+ if ((best_trp= get_key_scans_params(&param, tree, FALSE,
best_read_time)))
best_read_time= best_trp->read_cost;
@@ -1705,7 +1705,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (best_trp)
{
records= best_trp->records;
- if (!(quick= best_trp->make_quick(&param, true)) || quick->init())
+ if (!(quick= best_trp->make_quick(&param, TRUE)) || quick->init())
{
delete quick;
quick= NULL;
@@ -1858,13 +1858,13 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
TRP_RANGE **range_scans;
TRP_RANGE **cur_child;
TRP_RANGE **cpk_scan= NULL;
- bool imerge_too_expensive= false;
+ bool imerge_too_expensive= FALSE;
double imerge_cost= 0.0;
ha_rows cpk_scan_records= 0;
ha_rows non_cpk_scan_records= 0;
bool pk_is_clustered= param->table->file->primary_key_is_clustered();
- bool all_scans_ror_able= true;
- bool all_scans_rors= true;
+ bool all_scans_ror_able= TRUE;
+ bool all_scans_rors= TRUE;
uint unique_calc_buff_size;
TABLE_READ_PLAN **roru_read_plans;
TABLE_READ_PLAN **cur_roru_plan;
@@ -1891,7 +1891,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
{
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
"tree in SEL_IMERGE"););
- if (!(*cur_child= get_key_scans_params(param, *ptree, true, read_time)))
+ if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, read_time)))
{
/*
One of index scans in this index_merge is more expensive than entire
@@ -1899,7 +1899,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
any possible ROR-union) will be more expensive then, too. We continue
here only to update SQL_SELECT members.
*/
- imerge_too_expensive= true;
+ imerge_too_expensive= TRUE;
}
if (imerge_too_expensive)
continue;
@@ -2170,7 +2170,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
DBUG_RETURN(NULL);
if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
- param->fields_bitmap_size*8, false))
+ param->fields_bitmap_size*8, FALSE))
DBUG_RETURN(NULL);
bitmap_clear_all(&ror_scan->covered_fields);
@@ -2251,7 +2251,7 @@ typedef struct
const PARAM *param;
MY_BITMAP covered_fields; /* union of fields covered by all scans */
- /* true if covered_fields is a superset of needed_fields */
+ /* TRUE if covered_fields is a superset of needed_fields */
bool is_covering;
double index_scan_costs; /* SUM(cost of 'index-only' scans) */
@@ -2274,7 +2274,7 @@ typedef struct
static void ror_intersect_reinit(ROR_INTERSECT_INFO *info)
{
- info->is_covering= false;
+ info->is_covering= FALSE;
info->index_scan_costs= 0.0f;
info->records_fract= 1.0f;
bitmap_clear_all(&info->covered_fields);
@@ -2286,7 +2286,7 @@ static void ror_intersect_reinit(ROR_INTERSECT_INFO *info)
SYNOPSIS
ror_intersect_init()
param Parameter from test_quick_select
- is_index_only If true, set ROR_INTERSECT_INFO to be covering
+ is_index_only If TRUE, set ROR_INTERSECT_INFO to be covering
RETURN
allocated structure
@@ -2305,7 +2305,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only)
if (!(buf= (uchar*)alloc_root(param->mem_root, param->fields_bitmap_size)))
return NULL;
if (bitmap_init(&info->covered_fields, buf, param->fields_bitmap_size*8,
- false))
+ FALSE))
return NULL;
ror_intersect_reinit(info);
return info;
@@ -2322,7 +2322,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only)
param Parameter from test_quick_select
info ROR-intersection structure to add the scan to.
ror_scan ROR scan info to add.
- is_cpk_scan If true, add the scan as CPK scan (this can be inferred
+ is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred
from other parameters and is passed separately only to
avoid duplicating the inference code)
@@ -2420,12 +2420,12 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only)
and reduce adjacent fractions.
RETURN
- true ROR scan added to ROR-intersection, cost updated.
- false It doesn't make sense to add this ROR scan to this ROR-intersection.
+ TRUE ROR scan added to ROR-intersection, cost updated.
+ FALSE It doesn't make sense to add this ROR scan to this ROR-intersection.
*/
bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
- ROR_SCAN_INFO* ror_scan, bool is_cpk_scan=false)
+ ROR_SCAN_INFO* ror_scan, bool is_cpk_scan=FALSE)
{
int i;
SEL_ARG *sel_arg;
@@ -2504,7 +2504,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
{
/* Don't add this scan if it doesn't improve selectivity. */
DBUG_PRINT("info", ("The scan doesn't improve selectivity."));
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
}
info->records_fract *= selectivity_mult;
@@ -2525,7 +2525,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
&info->covered_fields))
{
DBUG_PRINT("info", ("ROR-intersect is covering now"));
- info->is_covering= true;
+ info->is_covering= TRUE;
}
info->total_cost= info->index_scan_costs;
@@ -2539,7 +2539,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
DBUG_PRINT("info", ("New selectivity= %g", info->records_fract));
DBUG_PRINT("info", ("New cost= %g, %scovering", info->total_cost,
info->is_covering?"" : "non-"));
- DBUG_RETURN(true);
+ DBUG_RETURN(TRUE);
}
@@ -2553,7 +2553,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info,
tree Transformed restriction condition to be used to look
for ROR scans.
read_time Do not return read plans with cost > read_time.
- are_all_covering [out] set to true if union of all scans covers all
+ are_all_covering [out] set to TRUE if union of all scans covers all
fields needed by the query (and it is possible to build
a covering ROR-intersection)
@@ -2621,7 +2621,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
*/
ROR_SCAN_INFO **cur_ror_scan;
ROR_SCAN_INFO *cpk_scan= NULL;
- bool cpk_scan_used= false;
+ bool cpk_scan_used= FALSE;
if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
sizeof(ROR_SCAN_INFO*)*
param->keys)))
@@ -2670,7 +2670,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
/* Create and incrementally update ROR intersection. */
ROR_INTERSECT_INFO *intersect;
- if (!(intersect= ror_intersect_init(param, false)))
+ if (!(intersect= ror_intersect_init(param, FALSE)))
return NULL;
/* [intersect_scans, intersect_scans_best) will hold the best combination */
@@ -2739,7 +2739,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
if (ror_intersect_add(param, intersect, cpk_scan))
{
- cpk_scan_used= true;
+ cpk_scan_used= TRUE;
min_cost= intersect->total_cost;
best_rows= (ha_rows)(intersect->records_fract*
rows2double(param->table->file->records));
@@ -2826,7 +2826,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
uchar buf[MAX_KEY/8+1];
MY_BITMAP covered_fields;
- if (bitmap_init(&covered_fields, buf, nbits, false))
+ if (bitmap_init(&covered_fields, buf, nbits, FALSE))
DBUG_RETURN(0);
bitmap_clear_all(&covered_fields);
@@ -2903,7 +2903,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
DBUG_RETURN(NULL);
memcpy(trp->first_scan, ror_scan_mark, best_num*sizeof(ROR_SCAN_INFO*));
trp->last_scan= trp->first_scan + best_num;
- trp->is_covering= true;
+ trp->is_covering= TRUE;
trp->read_cost= total_cost;
trp->records= records;
@@ -2918,7 +2918,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
get_key_scans_params
param parameters from test_quick_select
tree make range select for this SEL_TREE
- index_read_must_be_used if true, assume 'index only' option will be set
+ index_read_must_be_used if TRUE, assume 'index only' option will be set
(except for clustered PK indexes)
read_time don't create read plans with cost > read_time.
RETURN
@@ -2959,8 +2959,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
(*key)->maybe_flag)
param->needed_reg->set_bit(keynr);
- bool read_index_only= index_read_must_be_used? true :
- (bool)param->table->used_keys.is_set(keynr);
+ bool read_index_only= index_read_must_be_used ? TRUE :
+ (bool) param->table->used_keys.is_set(keynr);
found_records= check_quick_select(param, idx, *key);
if (param->is_ror_scan)
@@ -2970,7 +2970,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
}
if (found_records != HA_POS_ERROR && found_records > 2 &&
read_index_only &&
- (param->table->file->index_flags(keynr) & HA_KEYREAD_ONLY) &&
+ (param->table->file->index_flags(keynr, param.max_key_part,1) &
+ HA_KEYREAD_ONLY) &&
!(pk_is_clustered && keynr == param->table->primary_key))
{
/* We can resolve this by only reading through this key. */
@@ -3038,7 +3039,7 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
range_scan++)
{
if (!(quick= (QUICK_RANGE_SELECT*)
- ((*range_scan)->make_quick(param, false, &quick_imerge->alloc)))||
+ ((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))||
quick_imerge->push_quick_back(quick))
{
delete quick;
@@ -3060,7 +3061,7 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
if ((quick_intrsect=
new QUICK_ROR_INTERSECT_SELECT(param->thd, param->table,
- retrieve_full_rows? (!is_covering):false,
+ retrieve_full_rows? (!is_covering):FALSE,
parent_alloc)))
{
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
@@ -3110,7 +3111,7 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
{
for(scan= first_ror; scan != last_ror; scan++)
{
- if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
+ if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) ||
quick_roru->push_quick_back(quick))
DBUG_RETURN(NULL);
}
@@ -3231,7 +3232,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
param->current_table))
DBUG_RETURN(0); // Can't be calculated yet
if (!(ref_tables & param->current_table))
- DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
+ DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be FALSE or TRUE
/* check field op const */
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
@@ -3372,7 +3373,8 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
uint length,offset,min_length,max_length;
- if (!field->optimize_range(param->real_keynr[key_part->key]))
+ if (!field->optimize_range(param->real_keynr[key_part->key],
+ key_part->part))
DBUG_RETURN(0); // Can't optimize this
if (!(res= value->val_str(&tmp)))
DBUG_RETURN(&null_element);
@@ -3437,7 +3439,8 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
DBUG_RETURN(new SEL_ARG(field,min_str,max_str));
}
- if (!field->optimize_range(param->real_keynr[key_part->key]) &&
+ if (!field->optimize_range(param->real_keynr[key_part->key],
+ key_part->part) &&
type != Item_func::EQ_FUNC &&
type != Item_func::EQUAL_FUNC)
DBUG_RETURN(0); // Can't optimize this
@@ -3454,7 +3457,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
if (value->save_in_field(field, 1) < 0)
{
/* This happens when we try to insert a NULL field in a not null column */
- DBUG_RETURN(&null_element); // cmp with NULL is never true
+ DBUG_RETURN(&null_element); // cmp with NULL is never TRUE
}
/* Get local copy of key */
copies= 1;
@@ -3559,8 +3562,8 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
** If tree is 0 it means that the condition can't be tested. It refers
** to a non existent table or to a field in current table with isn't a key.
** The different tree flags:
-** IMPOSSIBLE: Condition is never true
-** ALWAYS: Condition is always true
+** IMPOSSIBLE: Condition is never TRUE
+** ALWAYS: Condition is always TRUE
** MAYBE: Condition may exists when tables are read
** MAYBE_KEY: Condition refers to a key that may be used in join loop
** KEY_RANGE: Condition uses a key
@@ -3683,7 +3686,7 @@ bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, PARAM* param)
common_keys.intersect(tree2->keys_map);
if (common_keys.is_clear_all())
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
/* trees have a common key, check if they refer to same key part */
SEL_ARG **key1,**key2;
@@ -3695,11 +3698,11 @@ bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, PARAM* param)
key2= tree2->keys + key_no;
if ((*key1)->part == (*key2)->part)
{
- DBUG_RETURN(true);
+ DBUG_RETURN(TRUE);
}
}
}
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
}
static SEL_TREE *
@@ -4669,7 +4672,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
uint key;
DBUG_ENTER("check_quick_select");
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
if (!tree)
DBUG_RETURN(HA_POS_ERROR); // Can't use it
@@ -4686,7 +4689,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
{
/* Records are not ordered by rowid for other types of indexes. */
- cpk_scan= false;
+ cpk_scan= FALSE;
}
else
{
@@ -4707,7 +4710,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
param->table->quick_key_parts[key]=param->max_key_part+1;
if (cpk_scan)
- param->is_ror_scan= true;
+ param->is_ror_scan= TRUE;
}
DBUG_PRINT("exit", ("Records: %lu", (ulong) records));
DBUG_RETURN(records);
@@ -4766,7 +4769,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
(keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
This is not a ROR scan if the key is not Clustered Primary Key.
*/
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
records=check_quick_keys(param,idx,key_tree->left,min_key,min_key_flag,
max_key,max_key_flag);
if (records == HA_POS_ERROR) // Impossible
@@ -4791,7 +4794,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
key_part[key_tree->part].fieldnr - 1;
if (param->table->field[fieldnr]->key_length() !=
param->key[idx][key_tree->part].length)
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
}
if (key_tree->next_key_part &&
@@ -4810,7 +4813,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
else
{
/* The interval for current key part is not c1 <= keyXpartY <= c1 */
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
}
tmp_min_flag=key_tree->min_flag;
@@ -4856,7 +4859,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
!memcmp(min_key,max_key, (uint) (tmp_max_key - max_key)) &&
!key_tree->min_flag && !key_tree->max_flag &&
is_key_scan_ror(param, keynr, key_tree->part + 1)))
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
}
if (tmp_min_flag & GEOM_FLAG)
@@ -4901,7 +4904,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
(keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
This is not a ROR scan if the key is not Clustered Primary Key.
*/
- param->is_ror_scan= false;
+ param->is_ror_scan= FALSE;
tmp=check_quick_keys(param,idx,key_tree->right,min_key,min_key_flag,
max_key,max_key_flag);
if (tmp == HA_POS_ERROR)
@@ -4947,8 +4950,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
Check (2) is made by this function.
RETURN
- true If the scan is ROR-scan
- false otherwise
+ TRUE If the scan is ROR-scan
+ FALSE otherwise
*/
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
@@ -4959,10 +4962,10 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
table_key->key_parts;
if (key_part == key_part_end)
- return true;
+ return TRUE;
uint pk_number= param->table->primary_key;
if (!param->table->file->primary_key_is_clustered() || pk_number == MAX_KEY)
- return false;
+ return FALSE;
KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part;
KEY_PART_INFO *pk_part_end= pk_part +
@@ -4972,7 +4975,7 @@ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
{
if ((key_part->field != pk_part->field) ||
(key_part->length != pk_part->length))
- return false;
+ return FALSE;
}
return (key_part == key_part_end);
}
@@ -5173,7 +5176,7 @@ bool QUICK_RANGE_SELECT::unique_key_range()
}
-/* Returns true if any part of the key is NULL */
+/* Returns TRUE if any part of the key is NULL */
static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
{
@@ -5311,7 +5314,7 @@ err:
/*
Fetch all row ids into unique.
- If table has a clustered primary key that covers all rows (true for bdb
+ If table has a clustered primary key that covers all rows (TRUE for bdb
and innodb currently) and one of the index_merge scans is a scan on PK,
then
primary key scan rowids are not put into Unique and also
@@ -5380,11 +5383,11 @@ int QUICK_INDEX_MERGE_SELECT::prepare_unique()
if (result)
DBUG_RETURN(1);
- }while(true);
+ }while(TRUE);
/* ok, all row ids are in Unique */
result= unique->get(head);
- doing_pk_scan= false;
+ doing_pk_scan= FALSE;
init_read_record(&read_record, thd, head, NULL, 1, 1);
/* index_merge currently doesn't support "using index" at all */
head->file->extra(HA_EXTRA_NO_KEYREAD);
@@ -5419,7 +5422,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
/* All rows from Unique have been retrieved, do a clustered PK scan */
if(pk_quick_select)
{
- doing_pk_scan= true;
+ doing_pk_scan= TRUE;
if ((result= pk_quick_select->init()))
DBUG_RETURN(result);
DBUG_RETURN(pk_quick_select->get_next());
@@ -5567,8 +5570,8 @@ int QUICK_ROR_UNION_SELECT::get_next()
if (!have_prev_rowid)
{
/* No rows have been returned yet */
- dup_row= false;
- have_prev_rowid= true;
+ dup_row= FALSE;
+ have_prev_rowid= TRUE;
}
else
dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid);
@@ -5691,8 +5694,8 @@ int QUICK_RANGE_SELECT_GEOM::get_next()
index_merge quick select.
RETURN
- true if current row will be retrieved by this quick select
- false if not
+ TRUE if current row will be retrieved by this quick select
+ FALSE if not
*/
bool QUICK_RANGE_SELECT::row_in_ranges()
@@ -5889,7 +5892,7 @@ int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
/*
- * True if this range will require using HA_READ_AFTER_KEY
+ * TRUE if this range will require using HA_READ_AFTER_KEY
See comment in get_next() about this
*/
@@ -5901,7 +5904,7 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
}
-/* True if we are reading over a key that may have a NULL value */
+/* TRUE if we are reading over a key that may have a NULL value */
#ifdef NOT_USED
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
@@ -5958,7 +5961,7 @@ void QUICK_RANGE_SELECT::add_info_string(String *str)
void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
{
QUICK_RANGE_SELECT *quick;
- bool first= true;
+ bool first= TRUE;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
str->append("sort_union(");
while ((quick= it++))
@@ -5966,7 +5969,7 @@ void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
if (!first)
str->append(',');
else
- first= false;
+ first= FALSE;
quick->add_info_string(str);
}
if (pk_quick_select)
@@ -5979,7 +5982,7 @@ void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
{
- bool first= true;
+ bool first= TRUE;
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
str->append("intersect(");
@@ -5989,7 +5992,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
if (!first)
str->append(',');
else
- first= false;
+ first= FALSE;
str->append(key_info->name);
}
if (cpk_quick)
@@ -6003,7 +6006,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
{
- bool first= true;
+ bool first= TRUE;
QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
str->append("union(");
@@ -6012,7 +6015,7 @@ void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
if (!first)
str->append(',');
else
- first= false;
+ first= FALSE;
quick->add_info_string(str);
}
str->append(')');
@@ -6035,14 +6038,14 @@ void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
{
char buf[64];
uint length;
- bool first= true;
+ bool first= TRUE;
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
if (first)
- first= false;
+ first= FALSE;
else
{
key_names->append(',');
@@ -6070,14 +6073,14 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
{
char buf[64];
uint length;
- bool first= true;
+ bool first= TRUE;
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
KEY *key_info= head->key_info + quick->index;
if (first)
- first= false;
+ first= FALSE;
else
{
key_names->append(',');
@@ -6102,13 +6105,13 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
String *used_lengths)
{
- bool first= true;
+ bool first= TRUE;
QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++))
{
if (first)
- first= false;
+ first= FALSE;
else
{
used_lengths->append(',');
@@ -6222,7 +6225,7 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
DBUG_VOID_RETURN;
DBUG_LOCK_FILE;
- quick->dbug_dump(0, true);
+ quick->dbug_dump(0, TRUE);
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
DBUG_UNLOCK_FILE;
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 75b00b97ce7..f4c39462d0c 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -629,7 +629,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
if (!(field->flags & PART_KEY_FLAG))
return 0; // Not key field
*prefix_len= 0;
-
+
TABLE *table= field->table;
uint idx= 0;
@@ -637,16 +637,17 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->keys ;
keyinfo != keyinfo_end;
keyinfo++,idx++)
- {
- if (!(table->file->index_flags(idx) & HA_READ_ORDER))
- break;
-
+ {
KEY_PART_INFO *part,*part_end;
key_part_map key_part_to_use= 0;
+ uint jdx= 0;
for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts ;
part != part_end ;
- part++, key_part_to_use= (key_part_to_use << 1) | 1)
+ part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1)
{
+ if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
+ return 0;
+
if (field->eq(part->field))
{
ref->key= idx;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 1066c6f4465..07ab6620e4b 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -813,6 +813,9 @@ struct show_var_st init_vars[]= {
{sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS},
#endif
{sys_sync_frm.name, (char*) &sys_sync_frm, SHOW_SYS},
+#ifdef HAVE_TZNAME
+ {"system_time_zone", system_time_zone, SHOW_CHAR},
+#endif
{"table_cache", (char*) &table_cache_size, SHOW_LONG},
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
@@ -821,9 +824,6 @@ struct show_var_st init_vars[]= {
#endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG},
{sys_time_format.name, (char*) &sys_time_format, SHOW_SYS},
-#ifdef HAVE_TZNAME
- {"system_time_zone", system_time_zone, SHOW_CHAR},
-#endif
{"time_zone", (char*) &sys_time_zone, SHOW_SYS},
{sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
{"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR},
@@ -1755,10 +1755,10 @@ bool sys_var_collation::check(THD *thd, set_var *var)
}
else // INT_RESULT
{
- if (!(tmp=get_charset(var->value->val_int(),MYF(0))))
+ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
{
char buf[20];
- int10_to_str(var->value->val_int(), buf, -10);
+ int10_to_str((int) var->value->val_int(), buf, -10);
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
return 1;
}
@@ -1794,10 +1794,10 @@ bool sys_var_character_set::check(THD *thd, set_var *var)
}
else // INT_RESULT
{
- if (!(tmp=get_charset(var->value->val_int(),MYF(0))))
+ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
{
char buf[20];
- int10_to_str(var->value->val_int(), buf, -10);
+ int10_to_str((int) var->value->val_int(), buf, -10);
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
return 1;
}
diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml
index 44eb6f386d4..5e75cde5f2a 100644
--- a/sql/share/charsets/Index.xml
+++ b/sql/share/charsets/Index.xml
@@ -402,7 +402,7 @@ To make maintaining easier please:
<description>ARMSCII-8 Armenian</description>
<alias>armscii-8</alias>
<collation name="armscii8_general_ci" id="32" order="Armenian" flag="primary"/>
- <collation name="armscii_bin" id="64" order="Binary" flag="binary"/>
+ <collation name="armscii8_bin" id="64" order="Binary" flag="binary"/>
</charset>
<charset name="utf8">
diff --git a/sql/share/charsets/armscii8.xml b/sql/share/charsets/armscii8.xml
index 1d9e33e3bc8..8ca5675012b 100644
--- a/sql/share/charsets/armscii8.xml
+++ b/sql/share/charsets/armscii8.xml
@@ -114,7 +114,7 @@
</map>
</collation>
-<collation name="armscii_bin" flag="binary"/>
+<collation name="armscii8_bin" flag="binary"/>
</charset>
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 75cbf12f60c..8ca63ce2105 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -312,6 +312,7 @@ character-set=latin2
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index b4b42b41969..4c61f0449ab 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -306,6 +306,7 @@ character-set=latin1
"Modtog temporary fejl %d '%-.100s' fra %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index af0c3a1bc0b..673678543b1 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -314,6 +314,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index 7706257a55d..4e0d7392947 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -303,6 +303,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index ace966b693a..6438934cdda 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -308,6 +308,7 @@ character-set=latin7
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 63568b9ebd7..c4957433a8c 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -303,6 +303,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index d2588b10092..0d6eb180abd 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -315,6 +315,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index 2d099e149f6..6a1c6b99c25 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -303,6 +303,7 @@ character-set=greek
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index ac9539b35cf..f9391613018 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -305,6 +305,7 @@ character-set=latin2
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 33ea2cb2a9d..525fd7eced9 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -303,6 +303,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 6bb82cc9749..fdff7cff4e3 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -304,7 +304,8 @@ character-set=ujis
"Got NDB error %d '%-.100s'",
"Got temporary NDB error %d '%-.100s'",
"Unknown or incorrect time zone: '%-.64s'",
-+ "Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 884ce735815..ee038dd9ec6 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -303,6 +303,7 @@ character-set=euckr
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 27ebe984c7e..10cb75fdb7b 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -305,6 +305,7 @@ character-set=latin1
"Mottok temporary feil %d '%-.100s' fra %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 764032da9da..d17c12c13e3 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -305,6 +305,7 @@ character-set=latin1
"Mottok temporary feil %d '%-.100s' fra %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 68464d0b8f1..38d707d9174 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -307,6 +307,7 @@ character-set=latin2
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index 7561f12cb7c..391c10c8bbc 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -304,6 +304,7 @@ character-set=latin1
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 03dd45fb6c2..8cc218f3831 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -307,6 +307,7 @@ character-set=latin2
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 3b0286ea3f8..b317265f9ac 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -305,6 +305,7 @@ character-set=koi8r
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt
index a64d9056701..6a5b24666c3 100644
--- a/sql/share/serbian/errmsg.txt
+++ b/sql/share/serbian/errmsg.txt
@@ -309,6 +309,7 @@ character-set=cp1250
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index ebd64f34f88..ba851763bf6 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -311,6 +311,7 @@ character-set=latin2
"Got temporary error %d '%-.100s' from %s",
"Unknown or incorrect time zone: '%-.64s'",
"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index 042df901a5e..fe19bdbb7ac 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -301,6 +301,11 @@ character-set=latin1
"Incorrecta definición de tabla; Solamente debe haber una columna TIMESTAMP con CURRENT_TIMESTAMP en DEFAULT o ON UPDATE cláusula"
"Inválido ON UPDATE cláusula para campo '%-.64s'",
"This command is not supported in the prepared statement protocol yet",
+"Got error %d '%-.100s' from %s",
+"Got temporary error %d '%-.100s' from %s",
+"Unknown or incorrect time zone: '%-.64s'",
+"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 26e00bfbcca..3a616479dba 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -299,6 +299,11 @@ character-set=latin1
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
+"Got error %d '%-.100s' from %s",
+"Got temporary error %d '%-.100s' from %s",
+"Unknown or incorrect time zone: '%-.64s'",
+"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index 05fcb3d3121..1aeba953e8f 100644
--- a/sql/share/ukrainian/errmsg.txt
+++ b/sql/share/ukrainian/errmsg.txt
@@ -304,6 +304,11 @@ character-set=koi8u
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
+"Got error %d '%-.100s' from %s",
+"Got temporary error %d '%-.100s' from %s",
+"Unknown or incorrect time zone: '%-.64s'",
+"Invalid TIMESTAMP value in column '%s' at row %ld",
+"Invalid %s character string: '%.64s'",
"Can't create a %s from within another stored routine"
"%s %s already exists"
"%s %s does not exist"
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 36926d4526d..810312dea16 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1869,11 +1869,13 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
col_privs->field[3]->pack_length());
key_copy(key,col_privs,0,key_len);
col_privs->field[4]->store("",0, &my_charset_latin1);
- if (col_privs->file->index_read_idx(col_privs->record[0],0,
+ col_privs->file->ha_index_init(0);
+ if (col_privs->file->index_read(col_privs->record[0],
(byte*) col_privs->field[0]->ptr,
key_len, HA_READ_KEY_EXACT))
{
cols = 0; /* purecov: deadcode */
+ col_privs->file->ha_index_end();
return;
}
do
@@ -1893,6 +1895,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
my_hash_insert(&hash_columns, (byte *) mem_check);
} while (!col_privs->file->index_next(col_privs->record[0]) &&
!key_cmp_if_same(col_privs,key,0,key_len));
+ col_privs->file->ha_index_end();
}
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 07c894dc8c1..b86bfb07386 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -549,21 +549,23 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
return FALSE;
}
+
/*
Update some cache variables when character set changes
*/
void THD::update_charset()
{
- charset_is_system_charset= my_charset_same(charset(),system_charset_info);
- charset_is_collation_connection= my_charset_same(charset(),
- variables.
- collation_connection);
+ uint32 not_used;
+ charset_is_system_charset= !String::needs_conversion(0,charset(),
+ system_charset_info,
+ &not_used);
+ charset_is_collation_connection=
+ !String::needs_conversion(0,charset(),variables.collation_connection,
+ &not_used);
}
-
-
/* routings to adding tables to list of changed in transaction tables */
inline static void list_include(CHANGED_TABLE_LIST** prev,
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 947dd559559..9889d4a2b4a 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -40,6 +40,197 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
const char *db, const char *path,
uint level);
+/* Database options hash */
+static HASH dboptions;
+static my_bool dboptions_init= 0;
+static rw_lock_t LOCK_dboptions;
+
+/* Structure for database options */
+typedef struct my_dbopt_st
+{
+ char *name; /* Database name */
+ uint name_length; /* Database length name */
+ CHARSET_INFO *charset; /* Database default character set */
+} my_dbopt_t;
+
+
+/*
+ Function we use in the creation of our hash to get key.
+*/
+static byte* dboptions_get_key(my_dbopt_t *opt, uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length= opt->name_length;
+ return (byte*) opt->name;
+}
+
+
+/*
+ Function to free dboptions hash element
+*/
+
+static void free_dbopt(void *dbopt)
+{
+ my_free((gptr) dbopt, MYF(0));
+}
+
+
+/*
+ Initialize database option hash
+
+ SYNOPSIS
+ my_dbopt_init()
+
+ NOTES
+ Must be called before any other database function is called.
+
+ RETURN
+ 0 ok
+ 1 Fatal error
+*/
+
+bool my_dbopt_init(void)
+{
+ bool error= 0;
+ (void) my_rwlock_init(&LOCK_dboptions, NULL);
+ if (!dboptions_init)
+ {
+ dboptions_init= 1;
+ error= hash_init(&dboptions, lower_case_table_names ?
+ &my_charset_bin : system_charset_info,
+ 32, 0, 0, (hash_get_key) dboptions_get_key,
+ free_dbopt,0);
+ }
+ return error;
+}
+
+
+/*
+ Free database option hash.
+*/
+
+void my_dbopt_free(void)
+{
+ if (dboptions_init)
+ {
+ dboptions_init= 0;
+ hash_free(&dboptions);
+ (void) rwlock_destroy(&LOCK_dboptions);
+ }
+}
+
+
+void my_dbopt_cleanup(void)
+{
+ rw_wrlock(&LOCK_dboptions);
+ hash_free(&dboptions);
+ hash_init(&dboptions, lower_case_table_names ?
+ &my_charset_bin : system_charset_info,
+ 32, 0, 0, (hash_get_key) dboptions_get_key,
+ free_dbopt,0);
+ rw_unlock(&LOCK_dboptions);
+}
+
+
+/*
+ Find database options in the hash.
+
+ DESCRIPTION
+ Search a database options in the hash, usings its path.
+ Fills "create" on success.
+
+ RETURN VALUES
+ 0 on success.
+ 1 on error.
+*/
+
+static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
+{
+ my_dbopt_t *opt;
+ uint length;
+ my_bool error= 1;
+
+ length= (uint) strlen(dbname);
+
+ rw_rdlock(&LOCK_dboptions);
+ if ((opt= (my_dbopt_t*) hash_search(&dboptions, (byte*) dbname, length)))
+ {
+ create->default_table_charset= opt->charset;
+ error= 0;
+ }
+ rw_unlock(&LOCK_dboptions);
+ return error;
+}
+
+
+/*
+ Writes database options into the hash.
+
+ DESCRIPTION
+ Inserts database options into the hash, or updates
+ options if they are already in the hash.
+
+ RETURN VALUES
+ 0 on success.
+ 1 on error.
+*/
+
+static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
+{
+ my_dbopt_t *opt;
+ uint length;
+ my_bool error= 0;
+ DBUG_ENTER("put_dbopt");
+
+ length= (uint) strlen(dbname);
+
+ rw_wrlock(&LOCK_dboptions);
+ if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (byte*) dbname, length)))
+ {
+ /* Options are not in the hash, insert them */
+ char *tmp_name;
+ if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ &opt, (uint) sizeof(*opt), &tmp_name, length+1,
+ NullS))
+ {
+ error= 1;
+ goto end;
+ }
+
+ opt->name= tmp_name;
+ strmov(opt->name, dbname);
+ opt->name_length= length;
+
+ if ((error= my_hash_insert(&dboptions, (byte*) opt)))
+ {
+ my_free((gptr) opt, MYF(0));
+ goto end;
+ }
+ }
+
+ /* Update / write options in hash */
+ opt->charset= create->default_table_charset;
+
+end:
+ rw_unlock(&LOCK_dboptions);
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Deletes database options from the hash.
+*/
+
+void del_dbopt(const char *path)
+{
+ my_dbopt_t *opt;
+ rw_wrlock(&LOCK_dboptions);
+ if ((opt= (my_dbopt_t *)hash_search(&dboptions, path, strlen(path))))
+ hash_delete(&dboptions, (byte*) opt);
+ rw_unlock(&LOCK_dboptions);
+}
+
+
/*
Create database options file:
@@ -57,15 +248,20 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
char buf[256]; // Should be enough for one option
bool error=1;
+ if (!create->default_table_charset)
+ create->default_table_charset= thd->variables.collation_server;
+
+ if (put_dbopt(path, create))
+ return 1;
+
if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
{
ulong length;
- CHARSET_INFO *cs= ((create && create->default_table_charset) ?
- create->default_table_charset :
- thd->variables.collation_server);
- length= my_sprintf(buf,(buf,
- "default-character-set=%s\ndefault-collation=%s\n",
- cs->csname,cs->name));
+ length= (ulong) (strxnmov(buf, sizeof(buf), "default-character-set=",
+ create->default_table_charset->csname,
+ "\ndefault-collation=",
+ create->default_table_charset->name,
+ "\n", NullS) - buf);
/* Error is written by my_write */
if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME)))
@@ -102,6 +298,12 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
bzero((char*) create,sizeof(*create));
create->default_table_charset= thd->variables.collation_server;
+
+ /* Check if options for this database are already in the hash */
+ if (!get_dbopt(path, create))
+ DBUG_RETURN(0);
+
+ /* Otherwise, load options from the .opt file */
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0)
{
IO_CACHE cache;
@@ -138,9 +340,16 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
}
}
}
- error=0;
end_io_cache(&cache);
my_close(file,MYF(0));
+ /*
+ Put the loaded value into the hash.
+ Note that another thread could've added the same
+ entry to the hash after we called get_dbopt(),
+ but it's not an error, as put_dbopt() takes this
+ possibility into account.
+ */
+ error= put_dbopt(path, create);
}
DBUG_RETURN(error);
}
@@ -168,10 +377,11 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
bool silent)
{
char path[FN_REFLEN+16];
- long result=1;
- int error = 0;
+ long result= 1;
+ int error= 0;
MY_STAT stat_info;
- uint create_options = create_info ? create_info->options : 0;
+ uint create_options= create_info ? create_info->options : 0;
+ uint path_len;
DBUG_ENTER("mysql_create_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@@ -185,17 +395,18 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
/* Check directory */
strxmov(path, mysql_data_home, "/", db, NullS);
- unpack_dirname(path,path); // Convert if not unix
+ path_len= unpack_dirname(path,path); // Convert if not unix
+ path[path_len-1]= 0; // Remove last '/' from path
if (my_stat(path,&stat_info,MYF(0)))
{
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{
my_error(ER_DB_CREATE_EXISTS,MYF(0),db);
- error = -1;
+ error= -1;
goto exit;
}
- result = 0;
+ result= 0;
}
else
{
@@ -204,23 +415,23 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
my_error(EE_STAT, MYF(0),path,my_errno);
goto exit;
}
- strend(path)[-1]=0; // Remove last '/' from path
if (my_mkdir(path,0777,MYF(0)) < 0)
{
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
- error = -1;
+ error= -1;
goto exit;
}
}
- unpack_dirname(path, path);
- strcat(path,MY_DB_OPT_FILE);
+ path[path_len-1]= FN_LIBCHAR;
+ strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
if (write_db_opt(thd, path, create_info))
{
/*
Could not create options file.
Restore things to beginning.
*/
+ path[path_len]= 0;
if (rmdir(path) >= 0)
{
error= -1;
@@ -271,7 +482,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
{
char path[FN_REFLEN+16];
long result=1;
- int error = 0;
+ int error= 0;
DBUG_ENTER("mysql_alter_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@@ -281,7 +492,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
goto exit2;
/* Check directory */
- (void)sprintf(path,"%s/%s/%s", mysql_data_home, db, MY_DB_OPT_FILE);
+ strxmov(path, mysql_data_home, "/", db, "/", MY_DB_OPT_FILE, NullS);
fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME));
if ((error=write_db_opt(thd, path, create_info)))
goto exit;
@@ -334,9 +545,11 @@ exit2:
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
long deleted=0;
- int error = 0;
+ int error= 0;
char path[FN_REFLEN+16], tmp_db[NAME_LEN+1];
MY_DIR *dirp;
+ uint length;
+ my_dbopt_t *dbopt;
DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@@ -349,9 +562,13 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
(void) sprintf(path,"%s/%s",mysql_data_home,db);
- unpack_dirname(path,path); // Convert if not unix
+ length= unpack_dirname(path,path); // Convert if not unix
+ strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
+ del_dbopt(path); // Remove dboption hash entry
+ path[length]= '\0'; // Remove file name
+
/* See if the directory exists */
- if (!(dirp = my_dir(path,MYF(MY_DONT_SORT))))
+ if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
{
if (!if_exists)
{
@@ -635,8 +852,10 @@ bool mysql_change_db(THD *thd, const char *name)
int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN];
- ulong db_access;
HA_CREATE_INFO create;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ ulong db_access;
+#endif
DBUG_ENTER("mysql_change_db");
if (!dbname || !(db_length= strlen(dbname)))
@@ -697,4 +916,3 @@ bool mysql_change_db(THD *thd, const char *name)
thd->variables.collation_database= thd->db_charset;
DBUG_RETURN(0);
}
-
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6870721a085..3eea8ae30d3 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5351,6 +5351,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
if (lock_global_read_lock(thd))
return 1;
}
+ my_dbopt_cleanup();
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
}
if (options & REFRESH_HOSTS)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5893b9110d7..974012093e3 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3831,7 +3831,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
Set tmp to (previous record count) * (records / combination)
*/
if ((found_part & 1) &&
- (!(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX) ||
+ (!(table->file->index_flags(key,0,0) & HA_ONLY_WHOLE_INDEX) ||
found_part == PREV_BITS(uint,keyinfo->key_parts)))
{
max_key_part=max_part_bit(found_part);
@@ -8865,14 +8865,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if (!select->quick->reverse_sorted())
{
- int quick_type= select->quick->get_type();
- if (!(table->file->index_flags(ref_key) & HA_READ_PREV) ||
+ /* here used_key_parts >0 */
+ if (!(table->file->index_flags(ref_key,used_key_parts-1, 1)
+ & HA_READ_PREV) ||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)
DBUG_RETURN(0); // Use filesort
- // ORDER BY range_key DESC
+ /* ORDER BY range_key DESC */
QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
used_key_parts);
if (!tmp || tmp->error)
@@ -8892,8 +8893,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
Use a traversal function that starts by reading the last row
with key part (A) and then traverse the index backwards.
*/
- if (!(table->file->index_flags(ref_key) & HA_READ_PREV))
- DBUG_RETURN(0); // Use filesort
+ if (!(table->file->index_flags(ref_key,used_key_parts-1, 1)
+ & HA_READ_PREV))
+ DBUG_RETURN(0); // Use filesort
tab->read_first_record= join_read_last_key;
tab->read_record.read_record= join_read_prev_same;
/* fall through */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 3e99704e80c..62bee1209e1 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -37,9 +37,6 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names};
#endif
-static int mysql_find_files(THD *thd,List<char> *files, const char *db,
- const char *path, const char *wild, bool dir);
-
static int
store_create_info(THD *thd, TABLE *table, String *packet);
@@ -361,7 +358,7 @@ int mysqld_show_column_types(THD *thd)
}
-static int
+int
mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
const char *wild, bool dir)
{
@@ -701,8 +698,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
byte *pos;
uint flags=field->flags;
String type(tmp,sizeof(tmp), system_charset_info);
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
uint col_access;
-
+#endif
protocol->prepare_for_resend();
protocol->store(field->field_name, system_charset_info);
field->sql_type(type);
@@ -995,7 +993,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
str=(key_part->field ? key_part->field->field_name :
"?unknown field?");
protocol->store(str, system_charset_info);
- if (table->file->index_flags(i) & HA_READ_ORDER)
+ if (table->file->index_flags(i, j, 0) & HA_READ_ORDER)
protocol->store(((key_part->key_part_flag & HA_REVERSE_SORT) ?
"D" : "A"), 1, system_charset_info);
else
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 48bd9e572b0..21d41b84e4b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1154,6 +1154,23 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
#endif
+ /*
+ If the table character set was not given explicitely,
+ let's fetch the database default character set and
+ apply it to the table.
+ */
+ if (!create_info->default_table_charset)
+ {
+ HA_CREATE_INFO db_info;
+ uint length;
+ char path[FN_REFLEN];
+ strxmov(path, mysql_data_home, "/", db, NullS);
+ length= unpack_dirname(path,path); // Convert if not unix
+ strmov(path+length, MY_DB_OPT_FILE);
+ load_db_opt(thd, path, &db_info);
+ create_info->default_table_charset= db_info.default_table_charset;
+ }
+
if (mysql_prepare_table(thd, create_info, fields,
keys, tmp_table, db_options, file,
key_info_buffer, &key_count,
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index e0281c813f1..963607f2d0e 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -61,7 +61,10 @@ int mysql_update(THD *thd,
bool safe_update= thd->options & OPTION_SAFE_UPDATES;
bool used_key_is_modified, transactional_table, log_delayed;
int error=0;
- uint used_index, want_privilege;
+ uint used_index;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ uint want_privilege;
+#endif
ulong query_id=thd->query_id, timestamp_query_id;
ha_rows updated, found;
key_map old_used_keys;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf17d38566d..de89983bc51 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1084,7 +1084,7 @@ create:
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.options=$2 | $4;
lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
- lex->create_info.default_table_charset= thd->variables.collation_database;
+ lex->create_info.default_table_charset= NULL;
lex->name=0;
}
create2
@@ -2882,7 +2882,7 @@ alter:
lex->select_lex.db=lex->name=0;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.db_type= DB_TYPE_DEFAULT;
- lex->create_info.default_table_charset= thd->variables.collation_database;
+ lex->create_info.default_table_charset= NULL;
lex->create_info.row_type= ROW_TYPE_NOT_USED;
lex->alter_info.reset();
lex->alter_info.is_simple= 1;
@@ -5704,7 +5704,9 @@ opt_db:
wild:
/* empty */
- | LIKE text_string { Lex->wild= $2; };
+ | LIKE TEXT_STRING_sys
+ { Lex->wild= new (&YYTHD->mem_root) String($2.str, $2.length,
+ system_charset_info); };
opt_full:
/* empty */ { Lex->verbose=0; }
@@ -6202,7 +6204,19 @@ IDENT_sys:
{
THD *thd= YYTHD;
if (thd->charset_is_system_charset)
+ {
+ CHARSET_INFO *cs= system_charset_info;
+ uint wlen= cs->cset->well_formed_len(cs, $1.str,
+ $1.str+$1.length,
+ $1.length);
+ if (wlen < $1.length)
+ {
+ net_printf(YYTHD, ER_INVALID_CHARACTER_STRING, cs->csname,
+ $1.str + wlen);
+ YYABORT;
+ }
$$= $1;
+ }
else
thd->convert_string(&$$, system_charset_info,
$1.str, $1.length, thd->charset());
diff --git a/sql/table.cc b/sql/table.cc
index 5024015c382..7d1c733b116 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -167,9 +167,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->keys= keys= disk_buff[0];
outparam->key_parts= key_parts= disk_buff[1];
}
- outparam->keys_for_keyread.init(keys);
+ outparam->keys_for_keyread.init(0);
outparam->keys_in_use.init(keys);
- outparam->read_only_keys.init(0);
+ outparam->read_only_keys.init(keys);
outparam->quick_keys.init();
outparam->used_keys.init();
outparam->keys_in_use_for_query.init();
@@ -500,13 +500,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (outparam->key_info[key].flags & HA_FULLTEXT)
outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
- /* This has to be done after the above fulltext correction */
- if (!(outparam->file->index_flags(key) & HA_KEYREAD_ONLY))
- {
- outparam->read_only_keys.set_bit(key);
- outparam->keys_for_keyread.clear_bit(key);
- }
-
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
{
/*
@@ -576,9 +569,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (field->key_length() == key_part->length &&
!(field->flags & BLOB_FLAG))
{
- if (outparam->file->index_flags(key, i) & HA_KEYREAD_ONLY)
+ if (outparam->file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
+ {
+ outparam->read_only_keys.clear_bit(key);
+ outparam->keys_for_keyread.set_bit(key);
field->part_of_key.set_bit(key);
- if (outparam->file->index_flags(key, i) & HA_READ_ORDER)
+ }
+ if (outparam->file->index_flags(key, i, 1) & HA_READ_ORDER)
field->part_of_sortkey.set_bit(key);
}
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&