summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-07-05 03:34:56 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-07-05 03:34:56 +0500
commite0f93ca8c1955cc2766c224703a278e66d9c05bc (patch)
tree1f70555dd3fd8c1b9579243c05e3499229bf4906 /sql
parent7edcebc97a817f7b157df86504e937600a2716d2 (diff)
parente2ccd8f8496836a253e7c1621c5d2781d17b18cd (diff)
downloadmariadb-git-e0f93ca8c1955cc2766c224703a278e66d9c05bc.tar.gz
Merge gleb.loc:/home/uchum/work/bk/5.0
into gleb.loc:/home/uchum/work/bk/5.0-opt sql/sql_class.h: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/filesort.cc18
-rw-r--r--sql/log.cc10
-rw-r--r--sql/sql_class.cc5
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_load.cc1
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sql_sort.h9
-rw-r--r--sql/uniques.cc13
8 files changed, 50 insertions, 21 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc
index d518ddbb117..f8868ed6927 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1052,6 +1052,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
BUFFPEK *buffpek;
QUEUE queue;
qsort2_cmp cmp;
+ void *first_cmp_arg;
volatile THD::killed_state *killed= &current_thd->killed;
THD::killed_state not_killable;
DBUG_ENTER("merge_buffers");
@@ -1077,9 +1078,18 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
/* The following will fire if there is not enough space in sort_buffer */
DBUG_ASSERT(maxcount!=0);
+ if (param->unique_buff)
+ {
+ cmp= param->compare;
+ first_cmp_arg= (void *) &param->cmp_context;
+ }
+ else
+ {
+ cmp= get_ptr_compare(sort_length);
+ first_cmp_arg= (void*) &sort_length;
+ }
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
- (queue_compare) (cmp= get_ptr_compare(sort_length)),
- (void*) &sort_length))
+ (queue_compare) cmp, first_cmp_arg))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
@@ -1132,7 +1142,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek= (BUFFPEK*) queue_top(&queue);
if (cmp) // Remove duplicates
{
- if (!(*cmp)(&sort_length, &(param->unique_buff),
+ if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
(uchar**) &buffpek->key))
goto skip_duplicate;
memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
@@ -1184,7 +1194,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
*/
if (cmp)
{
- if (!(*cmp)(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key))
+ if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
{
buffpek->key+= rec_length; // Remove duplicate
--buffpek->mem_count;
diff --git a/sql/log.cc b/sql/log.cc
index 818828f9557..dd989ebd76d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -85,7 +85,7 @@ bool binlog_init()
static int binlog_close_connection(THD *thd)
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
- DBUG_ASSERT(mysql_bin_log.is_open() && !my_b_tell(trans_log));
+ DBUG_ASSERT(!my_b_tell(trans_log));
close_cached_file(trans_log);
my_free((gptr)trans_log, MYF(0));
return 0;
@@ -126,7 +126,7 @@ static int binlog_commit(THD *thd, bool all)
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_commit");
- DBUG_ASSERT(mysql_bin_log.is_open() &&
+ DBUG_ASSERT(
(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))));
if (my_b_tell(trans_log) == 0)
@@ -155,7 +155,7 @@ static int binlog_rollback(THD *thd, bool all)
unnecessary, doing extra work. The cause should be found and eliminated
*/
DBUG_ASSERT(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(my_b_tell(trans_log));
/*
Update the binary log with a BEGIN/ROLLBACK block if we have
cached some queries and we updated some non-transactional
@@ -198,7 +198,7 @@ static int binlog_savepoint_set(THD *thd, void *sv)
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_savepoint_set");
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(my_b_tell(trans_log));
*(my_off_t *)sv= my_b_tell(trans_log);
/* Write it to the binary log */
@@ -210,7 +210,7 @@ static int binlog_savepoint_rollback(THD *thd, void *sv)
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_savepoint_rollback");
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(my_b_tell(trans_log));
/*
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 788026d2f67..117c20352ce 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1209,6 +1209,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] :
field_term_length ? (*exchange->field_term)[0] : INT_MAX);
escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1);
+ is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
line_sep_char= (exchange->line_term->length() ?
(*exchange->line_term)[0] : INT_MAX);
if (!field_term_length)
@@ -1349,7 +1350,9 @@ bool select_export::send_data(List<Item> &items)
NEED_ESCAPING(pos[1])))
{
char tmp_buff[2];
- tmp_buff[0]= escape_char;
+ tmp_buff[0]= ((int) *pos == field_sep_char &&
+ is_ambiguous_field_sep) ?
+ field_sep_char : escape_char;
tmp_buff[1]= *pos ? *pos : '0';
if (my_b_write(&cache,(byte*) start,(uint) (pos-start)) ||
my_b_write(&cache,(byte*) tmp_buff,2))
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d86f097ebe8..23c499aea07 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1926,9 +1926,18 @@ public:
};
+#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
+
+
class select_export :public select_to_file {
uint field_term_length;
int field_sep_char,escape_char,line_sep_char;
+ /*
+ The is_ambiguous_field_sep field is true if a value of the field_sep_char
+ field is one of the 'n', 't', 'r' etc characters
+ (see the READ_INFO::unescape method and the ESCAPE_CHARS constant value).
+ */
+ bool is_ambiguous_field_sep;
bool fixed_row_size;
public:
select_export(sql_exchange *ex) :select_to_file(ex) {}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index c2267ba5dfc..7b1799baaad 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -847,6 +847,7 @@ continue_loop:;
char
READ_INFO::unescape(char chr)
{
+ /* keep this switch synchornous with the ESCAPE_CHARS macro */
switch(chr) {
case 'n': return '\n';
case 't': return '\t';
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 902b298e423..dc1a7bc3bd3 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1909,11 +1909,9 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
if (item->type() == Item::FUNC_ITEM)
{
Item_func *item_func= (Item_func*)item;
- Item **child;
- Item **item_end= (item_func->arguments()) + item_func->argument_count();
- for (child= item_func->arguments(); child != item_end; child++)
+ for (uint i=0; i<item_func->argument_count(); i++)
{
- if (!uses_only_table_name_fields(*child, table))
+ if (!uses_only_table_name_fields(item_func->arguments()[i], table))
return 0;
}
}
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
index da28ca07e2c..1e9322f7f5b 100644
--- a/sql/sql_sort.h
+++ b/sql/sql_sort.h
@@ -50,6 +50,12 @@ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
ulong max_keys; /* Max keys in buffert */
} BUFFPEK;
+struct BUFFPEK_COMPARE_CONTEXT
+{
+ qsort_cmp2 key_compare;
+ void *key_compare_arg;
+};
+
typedef struct st_sort_param {
uint rec_length; /* Length of sorted records */
uint sort_length; /* Length of sorted columns */
@@ -65,6 +71,9 @@ typedef struct st_sort_param {
uchar *unique_buff;
bool not_killable;
char* tmp_buffer;
+ /* The fields below are used only by Unique class */
+ qsort2_cmp compare;
+ BUFFPEK_COMPARE_CONTEXT cmp_context;
} SORTPARAM;
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 9eb827f62a3..7c197d2a2e9 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -361,17 +361,12 @@ Unique::reset()
}
/*
- The comparison function, passed to queue_init() in merge_walk() must
+ The comparison function, passed to queue_init() in merge_walk() and in
+ merge_buffers() when the latter is called from Uniques::get() must
use comparison function of Uniques::tree, but compare members of struct
BUFFPEK.
*/
-struct BUFFPEK_COMPARE_CONTEXT
-{
- qsort_cmp2 key_compare;
- void *key_compare_arg;
-};
-
C_MODE_START
static int buffpek_compare(void *arg, byte *key_ptr1, byte *key_ptr2)
@@ -630,6 +625,10 @@ bool Unique::get(TABLE *table)
sort_param.unique_buff= sort_buffer+(sort_param.keys*
sort_param.sort_length);
+ sort_param.compare= (qsort2_cmp) buffpek_compare;
+ sort_param.cmp_context.key_compare= tree.compare;
+ sort_param.cmp_context.key_compare_arg= tree.custom_arg;
+
/* Merge the buffers to one file, removing duplicates */
if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&file))
goto err;