summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
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.cc2
-rw-r--r--sql/ha_ndbcluster.cc5
-rw-r--r--sql/item.cc21
-rw-r--r--sql/item.h1
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/sql_db.cc74
-rw-r--r--sql/sql_prepare.cc5
-rw-r--r--sql/sql_select.cc14
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/table.h3
14 files changed, 115 insertions, 24 deletions
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc
index d4e3b961223..503f3f6b1fe 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/examples/ha_archive.cc
@@ -18,7 +18,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <mysql_priv.h>
+#include "../mysql_priv.h"
#ifdef HAVE_ARCHIVE_DB
#include "ha_archive.h"
diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h
index 7ab463b6661..52300fda8a2 100644
--- a/sql/examples/ha_archive.h
+++ b/sql/examples/ha_archive.h
@@ -58,7 +58,7 @@ public:
ha_archive(TABLE *table): handler(table)
{
/* Set our original buffer from pre-allocated memory */
- buffer.set(byte_buffer, IO_SIZE, system_charset_info);
+ buffer.set((char*)byte_buffer, IO_SIZE, system_charset_info);
/* The size of the offset value we will use for position() */
ref_length = sizeof(z_off_t);
diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc
index 31e4e97c5c7..b3edce5ba4a 100644
--- a/sql/examples/ha_example.cc
+++ b/sql/examples/ha_example.cc
@@ -67,7 +67,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <mysql_priv.h>
+#include "../mysql_priv.h"
#ifdef HAVE_EXAMPLE_DB
#include "ha_example.h"
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 3109c314f6c..d1de0bd100e 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3258,7 +3258,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("Table schema version: %d",
tab->getObjectVersion()));
// Check if thread has stale local cache
- if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+ // New transaction must not use old tables... (trans != 0)
+ // Running might...
+ if ((trans && tab->getObjectStatus() != NdbDictionary::Object::Retrieved)
+ || tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
invalidate_dictionary_cache(FALSE);
if (!(tab= dict->getTable(m_tabname, &tab_info)))
diff --git a/sql/item.cc b/sql/item.cc
index b3d2932acf6..2ae56d17b07 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1230,7 +1230,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
CHARSET_INFO *tocs= thd->variables.collation_connection;
uint32 dummy_offset;
- value.cs_info.character_set_client= fromcs;
+ value.cs_info.character_set_of_placeholder= fromcs;
/*
Setup source and destination character sets so that they
are different only if conversion is necessary: this will
@@ -1482,10 +1482,17 @@ const String *Item_param::query_val_str(String* str) const
buf= str->c_ptr_quick();
ptr= buf;
- *ptr++= '\'';
- ptr+= escape_string_for_mysql(str_value.charset(), ptr,
- str_value.ptr(), str_value.length());
- *ptr++= '\'';
+ if (value.cs_info.character_set_client->escape_with_backslash_is_dangerous)
+ {
+ ptr= str_to_hex(ptr, str_value.ptr(), str_value.length());
+ }
+ else
+ {
+ *ptr++= '\'';
+ ptr+= escape_string_for_mysql(str_value.charset(), ptr,
+ str_value.ptr(), str_value.length());
+ *ptr++='\'';
+ }
str->length(ptr - buf);
break;
}
@@ -1515,10 +1522,10 @@ bool Item_param::convert_str_value(THD *thd)
here only if conversion is really necessary.
*/
if (value.cs_info.final_character_set_of_str_value !=
- value.cs_info.character_set_client)
+ value.cs_info.character_set_of_placeholder)
{
rc= thd->convert_string(&str_value,
- value.cs_info.character_set_client,
+ value.cs_info.character_set_of_placeholder,
value.cs_info.final_character_set_of_str_value);
}
else
diff --git a/sql/item.h b/sql/item.h
index c71769b5129..080b804c730 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -532,6 +532,7 @@ public:
struct CONVERSION_INFO
{
CHARSET_INFO *character_set_client;
+ CHARSET_INFO *character_set_of_placeholder;
/*
This points at character set of connection if conversion
to it is required (i. e. if placeholder typecode is not BLOB).
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 4d260763491..66c732e8cb0 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -207,7 +207,7 @@ static inline int read_str(char * &buf, char *buf_end, char * &str,
/*
Transforms a string into "" or its expression in 0x... form.
*/
-static char *str_to_hex(char *to, char *from, uint len)
+char *str_to_hex(char *to, const char *from, uint len)
{
char *p= to;
if (len)
diff --git a/sql/log_event.h b/sql/log_event.h
index 7ae4e863fc2..5c81d0c92f0 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1069,5 +1069,5 @@ public:
bool is_valid() { return 1; }
};
#endif
-
+char *str_to_hex(char *to, const char *from, uint len);
#endif /* _log_event_h */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b5a292fec28..2e38ec98c08 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -152,6 +152,7 @@ int deny_severity = LOG_WARNING;
#define zVOLSTATE_MAINTENANCE 3
#ifdef __NETWARE__
+#include <nks/netware.h>
#include <nks/vm.h>
#include <library.h>
#include <monitor.h>
@@ -4327,7 +4328,7 @@ Disable with --skip-bdb (will save memory).",
(gptr*) &default_collation_name, (gptr*) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"default-storage-engine", OPT_STORAGE_ENGINE,
- "Set the default storage engine (table tyoe) for tables.", 0, 0,
+ "Set the default storage engine (table type) for tables.", 0, 0,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"default-table-type", OPT_STORAGE_ENGINE,
"(deprecated) Use --default-storage-engine.", 0, 0,
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index ad6845572e1..6dcc7be0904 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -25,14 +25,20 @@
#include <direct.h>
#endif
+#define MAX_DROP_TABLE_Q_LEN 1024
+
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
- const char *db, const char *path,
- uint level);
+ const char *db, const char *path, uint level,
+ TABLE_LIST** dropped_tables);
+
+static inline void write_to_binlog(THD* thd, char* query, uint q_len,
+ char* db, uint db_len);
+
/* Database options hash */
static HASH dboptions;
static my_bool dboptions_init= 0;
@@ -57,6 +63,19 @@ static byte* dboptions_get_key(my_dbopt_t *opt, uint *length,
return (byte*) opt->name;
}
+/*
+ Helper function to write a query to binlog used by mysql_rm_db()
+ */
+static inline void write_to_binlog(THD* thd, char* query, uint q_len,
+ char* db, uint db_len)
+{
+ Query_log_event qinfo(thd, query, q_len, 0, 0);
+ qinfo.error_code= 0;
+ qinfo.db= db;
+ qinfo.db_len= db_len;
+ mysql_bin_log.write(&qinfo);
+}
+
/*
Function to free dboptions hash element
@@ -585,6 +604,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
char path[FN_REFLEN+16], tmp_db[NAME_LEN+1];
MY_DIR *dirp;
uint length;
+ TABLE_LIST* dropped_tables= 0;
DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
@@ -621,8 +641,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
remove_db_from_cache(db);
pthread_mutex_unlock(&LOCK_open);
+
error= -1;
- if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0)) >= 0)
+ if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
+ &dropped_tables)) >= 0)
{
ha_drop_database(path);
query_cache_invalidate1(db);
@@ -672,6 +694,45 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
send_ok(thd, (ulong) deleted);
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
}
+ else if (mysql_bin_log.is_open())
+ {
+ char* query= thd->alloc(MAX_DROP_TABLE_Q_LEN);
+
+ if (!query)
+ goto exit; /* not much else we can do */
+ char* p= strmov(query,"drop table ");
+ char* p_end= query + MAX_DROP_TABLE_Q_LEN;
+ TABLE_LIST* tbl;
+ bool last_query_needs_write= 0;
+ uint db_len= strlen(db);
+
+ for (tbl= dropped_tables;tbl;tbl= tbl->next)
+ {
+ if (!tbl->was_dropped)
+ continue;
+
+ /* 3 for the quotes and the comma*/
+ uint tbl_name_len= strlen(tbl->real_name) + 3;
+ if (p + tbl_name_len + 1 >= p_end)
+ {
+ *--p= 0; /* kill , */
+ write_to_binlog(thd, query, p - query, db, db_len);
+ p= query + 11; /* reuse the initial "drop table" */
+ }
+
+ *p++ = '`';
+ p= strmov(p,tbl->real_name);
+ *p++ = '`';
+ *p++ = ',';
+ last_query_needs_write= 1;
+ }
+
+ if (last_query_needs_write)
+ {
+ *--p= 0;
+ write_to_binlog(thd, query, p - query, db, db_len);
+ }
+ }
exit:
start_waiting_global_read_lock(thd);
@@ -716,7 +777,7 @@ exit2:
*/
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
- const char *org_path, uint level)
+ const char *org_path, uint level, TABLE_LIST** dropped_tables)
{
long deleted=0;
ulong found_other_files=0;
@@ -758,7 +819,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
{
DBUG_PRINT("my",("New subdir found: %s", newpath));
- if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0)
+ if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
goto err;
if (!(copy_of_path= thd->memdup(newpath, length+1)) ||
!(dir= new (thd->mem_root) String(copy_of_path, length,
@@ -818,6 +879,9 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
}
my_dirend(dirp);
+ if (dropped_tables)
+ *dropped_tables= tot_list;
+
/*
If the directory is a symbolic link, remove the link first, then
remove the directory the symbolic link pointed at
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 6507de37a71..8a50d0bd50e 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -528,7 +528,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
param->set_param_func= set_param_str;
- param->value.cs_info.character_set_client= &my_charset_bin;
+ param->value.cs_info.character_set_of_placeholder= &my_charset_bin;
+ param->value.cs_info.character_set_client=
+ thd->variables.character_set_client;
param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
param->item_type= Item::STRING_ITEM;
param->item_result_type= STRING_RESULT;
@@ -544,6 +546,7 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
CHARSET_INFO *tocs= thd->variables.collation_connection;
uint32 dummy_offset;
+ param->value.cs_info.character_set_of_placeholder= fromcs;
param->value.cs_info.character_set_client= fromcs;
/*
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9984cb4138f..b676cbb1fea 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4899,7 +4899,15 @@ static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
item->name, table, item->unsigned_flag);
break;
case STRING_RESULT:
- if (item->max_length > 255)
+ enum enum_field_types type;
+ /*
+ DATE/TIME fields have STRING_RESULT result type. To preserve
+ type they needed to be handled separately.
+ */
+ if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
+ type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
+ new_field= item->tmp_table_field_from_field_type(table);
+ else if (item->max_length > 255)
{
if (convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null,
@@ -8517,9 +8525,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
li.rewind();
while ((item=li++))
{
- if (item->const_item() || item->with_sum_func)
- continue;
- if (!item->marker)
+ if (!item->const_item() && !item->with_sum_func && !item->marker)
{
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 87b864c73fa..80ac9e007b9 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -220,6 +220,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
for (table=tables ; table ; table=table->next)
{
char *db=table->db;
+ table->was_dropped= 0;
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL);
if (!close_temporary_table(thd, db, table->real_name))
{
@@ -280,6 +281,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
wrong_tables.append(',');
wrong_tables.append(String(table->real_name,system_charset_info));
}
+ else
+ table->was_dropped= 1;
}
thd->tmp_table_used= tmp_table_deleted;
error= 0;
diff --git a/sql/table.h b/sql/table.h
index 77153e5d8cd..fb742acf804 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -235,6 +235,9 @@ typedef struct st_table_list
bool cacheable_table; /* stop PS caching */
/* used in multi-upd privelege check */
bool table_in_update_from_clause;
+
+ /* used for proper partially successful DROP DATABASE binlogging */
+ bool was_dropped;
} TABLE_LIST;
typedef struct st_changed_table_list