Commit 66e97ba5 authored by guilhem@mysql.com's avatar guilhem@mysql.com

Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/mysql_src/mysql-4.1
parents b03ec0d7 517a287e
...@@ -40,26 +40,26 @@ A ...@@ -40,26 +40,26 @@ A
a a
AD AD
ad ad
AE
ae ae
AE
AF AF
af af
B
b b
B
SS SS
ss ss
U
u u
U
UE UE
ue ue
Ü
ü
Y Y
y y
ü
Ü
Z Z
z z
Å
å å
Å
Ä Ä
ä ä
ß ß
...@@ -69,26 +69,26 @@ A ...@@ -69,26 +69,26 @@ A
a a
AD AD
ad ad
AE
ae ae
AE
AF AF
af af
B
b b
B
SS SS
ss ss
U
u u
U
UE UE
ue ue
Ü
ü
Y Y
y y
ü
Ü
Z Z
z z
Å
å å
Å
Ä Ä
ä ä
ß ß
...@@ -100,23 +100,23 @@ a ...@@ -100,23 +100,23 @@ a
å å
AD AD
ad ad
AE
ae
Ä Ä
ae
AE
ä ä
AF
af af
B AF
b b
SS B
ss
ß ß
ss
SS
U U
u u
UE
ue ue
Ü UE
ü ü
Ü
Y Y
y y
Z Z
...@@ -129,23 +129,23 @@ AD ...@@ -129,23 +129,23 @@ AD
ad ad
AE AE
ae ae
AF
af af
AF
Ä Ä
ä ä
Å Å
å å
B
b b
SS B
ss ss
SS
ß ß
U U
u u
UE UE
ue ue
Ü
ü ü
Ü
Y Y
y y
Z Z
...@@ -187,26 +187,26 @@ A ...@@ -187,26 +187,26 @@ A
a a
AD AD
ad ad
AE
ae ae
AE
AF AF
af af
B
b b
B
SS SS
ss ss
U
u u
U
UE UE
ue ue
Ü
ü
Y Y
y y
ü
Ü
Z Z
z z
Å
å å
Å
Ä Ä
ä ä
ß ß
...@@ -218,23 +218,23 @@ a ...@@ -218,23 +218,23 @@ a
å å
AD AD
ad ad
AE
ae
Ä Ä
ae
AE
ä ä
AF
af af
B AF
b b
SS B
ss
ß ß
ss
SS
U U
u u
UE
ue ue
Ü UE
ü ü
Ü
Y Y
y y
Z Z
...@@ -247,23 +247,23 @@ AD ...@@ -247,23 +247,23 @@ AD
ad ad
AE AE
ae ae
AF
af af
AF
Ä Ä
ä ä
Å Å
å å
B
b b
SS B
ss ss
SS
ß ß
U U
u u
UE UE
ue ue
Ü
ü ü
Ü
Y Y
y y
Z Z
......
...@@ -146,7 +146,7 @@ select grp,group_concat(c) from t1 group by grp; ...@@ -146,7 +146,7 @@ select grp,group_concat(c) from t1 group by grp;
grp group_concat(c) grp group_concat(c)
1 NULL 1 NULL
2 b 2 b
3 E,D,D 3 D,D,E
4 4
5 NULL 5 NULL
Warnings: Warnings:
......
This diff is collapsed.
...@@ -2943,7 +2943,7 @@ String *Item_func_compress::val_str(String *str) ...@@ -2943,7 +2943,7 @@ String *Item_func_compress::val_str(String *str)
*/ */
ulong new_size= (ulong)((res->length()*120)/100)+12; ulong new_size= (ulong)((res->length()*120)/100)+12;
buffer.realloc((uint32)new_size + 4); buffer.realloc((uint32)new_size + 4 + 1);
Byte *body= ((Byte*)buffer.c_ptr()) + 4; Byte *body= ((Byte*)buffer.c_ptr()) + 4;
if ((err= compress(body, &new_size, if ((err= compress(body, &new_size,
...@@ -2956,6 +2956,15 @@ String *Item_func_compress::val_str(String *str) ...@@ -2956,6 +2956,15 @@ String *Item_func_compress::val_str(String *str)
} }
int4store(buffer.c_ptr(),res->length() & 0x3FFFFFFF); int4store(buffer.c_ptr(),res->length() & 0x3FFFFFFF);
/* This is for the stupid char fields which trim ' ': */
char *last_char= ((char*)body)+new_size-1;
if (*last_char == ' ')
{
*++last_char= '.';
new_size++;
}
buffer.length((uint32)new_size + 4); buffer.length((uint32)new_size + 4);
return &buffer; return &buffer;
......
...@@ -3458,7 +3458,7 @@ enum options ...@@ -3458,7 +3458,7 @@ enum options
OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_JOIN_SIZE, OPT_MAX_LENGTH_FOR_SORT_DATA, OPT_MAX_SORT_LENGTH,
OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
OPT_MAX_ERROR_COUNT, OPT_MAX_PREP_STMT, OPT_MAX_ERROR_COUNT, OPT_MAX_PREP_STMT,
...@@ -4164,6 +4164,11 @@ Disable with --skip-innodb (will save memory)", ...@@ -4164,6 +4164,11 @@ Disable with --skip-innodb (will save memory)",
(gptr*) &global_system_variables.max_join_size, (gptr*) &global_system_variables.max_join_size,
(gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
~0L, 1, ~0L, 0, 1, 0}, ~0L, 1, ~0L, 0, 1, 0},
{"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
"Max number of bytes in sorted records",
(gptr*) &global_system_variables.max_length_for_sort_data,
(gptr*) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
{"max_prepared_statements", OPT_MAX_PREP_STMT, {"max_prepared_statements", OPT_MAX_PREP_STMT,
"Max number of prepared_statements for a thread", "Max number of prepared_statements for a thread",
(gptr*) &global_system_variables.max_prep_stmt_count, (gptr*) &global_system_variables.max_prep_stmt_count,
......
...@@ -349,13 +349,13 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables, ...@@ -349,13 +349,13 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
select->head=head; select->head=head;
select->cond=conds; select->cond=conds;
if (head->io_cache) if (head->sort.io_cache)
{ {
select->file= *head->io_cache; select->file= *head->sort.io_cache;
select->records=(ha_rows) (select->file.end_of_file/ select->records=(ha_rows) (select->file.end_of_file/
head->file->ref_length); head->file->ref_length);
my_free((gptr) (head->io_cache),MYF(0)); my_free((gptr) (head->sort.io_cache),MYF(0));
head->io_cache=0; head->sort.io_cache=0;
} }
DBUG_RETURN(select); DBUG_RETURN(select);
} }
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
...@@ -22,6 +23,8 @@ ...@@ -22,6 +23,8 @@
static int rr_quick(READ_RECORD *info); static int rr_quick(READ_RECORD *info);
static int rr_sequential(READ_RECORD *info); static int rr_sequential(READ_RECORD *info);
static int rr_from_tempfile(READ_RECORD *info); static int rr_from_tempfile(READ_RECORD *info);
static int rr_unpack_from_tempfile(READ_RECORD *info);
static int rr_unpack_from_buffer(READ_RECORD *info);
static int rr_from_pointers(READ_RECORD *info); static int rr_from_pointers(READ_RECORD *info);
static int rr_from_cache(READ_RECORD *info); static int rr_from_cache(READ_RECORD *info);
static int init_rr_cache(READ_RECORD *info); static int init_rr_cache(READ_RECORD *info);
...@@ -41,8 +44,16 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, ...@@ -41,8 +44,16 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info->table=table; info->table=table;
info->file= table->file; info->file= table->file;
info->forms= &info->table; /* Only one table */ info->forms= &info->table; /* Only one table */
info->record=table->record[0]; if (table->sort.addon_field)
info->ref_length=table->file->ref_length; {
info->rec_buf= table->sort.addon_buf;
info->ref_length= table->sort.addon_length;
}
else
{
info->record= table->record[0];
info->ref_length= table->file->ref_length;
}
info->select=select; info->select=select;
info->print_error=print_error; info->print_error=print_error;
info->ignore_not_found_rows= 0; info->ignore_not_found_rows= 0;
...@@ -51,11 +62,12 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, ...@@ -51,11 +62,12 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
if (select && my_b_inited(&select->file)) if (select && my_b_inited(&select->file))
tempfile= &select->file; tempfile= &select->file;
else else
tempfile= table->io_cache; tempfile= table->sort.io_cache;
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
{ {
DBUG_PRINT("info",("using rr_from_tempfile")); DBUG_PRINT("info",("using rr_from_tempfile"));
info->read_record=rr_from_tempfile; info->read_record= (table->sort.addon_field ?
rr_unpack_from_tempfile : rr_from_tempfile);
info->io_cache=tempfile; info->io_cache=tempfile;
reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0); reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
info->ref_pos=table->file->ref; info->ref_pos=table->file->ref;
...@@ -85,13 +97,15 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, ...@@ -85,13 +97,15 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
DBUG_PRINT("info",("using rr_quick")); DBUG_PRINT("info",("using rr_quick"));
info->read_record=rr_quick; info->read_record=rr_quick;
} }
else if (table->record_pointers) else if (table->sort.record_pointers)
{ {
DBUG_PRINT("info",("using record_pointers")); DBUG_PRINT("info",("using record_pointers"));
table->file->rnd_init(0); table->file->rnd_init(0);
info->cache_pos=table->record_pointers; info->cache_pos=table->sort.record_pointers;
info->cache_end=info->cache_pos+ table->found_records*info->ref_length; info->cache_end=info->cache_pos+
info->read_record= rr_from_pointers; table->sort.found_records*info->ref_length;
info->read_record= (table->sort.addon_field ?
rr_unpack_from_buffer : rr_from_pointers);
} }
else else
{ {
...@@ -120,6 +134,19 @@ void end_read_record(READ_RECORD *info) ...@@ -120,6 +134,19 @@ void end_read_record(READ_RECORD *info)
} }
if (info->table) if (info->table)
{ {
TABLE *table= info->table;
if (table->sort.record_pointers)
{
my_free((gptr) table->sort.record_pointers,MYF(0));
table->sort.record_pointers=0;
}
if (table->sort.addon_buf)
{
my_free((char *) table->sort.addon_buf, MYF(0));
my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
table->sort.addon_buf=0;
table->sort.addon_field=0;
}
(void) info->file->extra(HA_EXTRA_NO_CACHE); (void) info->file->extra(HA_EXTRA_NO_CACHE);
(void) info->file->rnd_end(); (void) info->file->rnd_end();
info->table=0; info->table=0;
...@@ -200,6 +227,34 @@ tryNext: ...@@ -200,6 +227,34 @@ tryNext:
} /* rr_from_tempfile */ } /* rr_from_tempfile */
/*
Read a result set record from a temporary file after sorting
SYNOPSIS
rr_unpack_from_tempfile()
info Reference to the context including record descriptors
DESCRIPTION
The function first reads the next sorted record from the temporary file.
into a buffer. If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN
0 - Record successfully read.
-1 - There is no record to be read anymore.
*/
static int rr_unpack_from_tempfile(READ_RECORD *info)
{
if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
return -1;
TABLE *table= info->table;
(*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
return 0;
}
static int rr_from_pointers(READ_RECORD *info) static int rr_from_pointers(READ_RECORD *info)
{ {
int tmp; int tmp;
...@@ -228,6 +283,34 @@ tryNext: ...@@ -228,6 +283,34 @@ tryNext:
return tmp; return tmp;
} }
/*
Read a result set record from a buffer after sorting
SYNOPSIS
rr_unpack_from_buffer()
info Reference to the context including record descriptors
DESCRIPTION
The function first reads the next sorted record from the sort buffer.
If a success it calls a callback function that unpacks
the fields values use in the result set from this buffer into their
positions in the regular record buffer.
RETURN
0 - Record successfully read.
-1 - There is no record to be read anymore.
*/
static int rr_unpack_from_buffer(READ_RECORD *info)
{
if (info->cache_pos == info->cache_end)
return -1; /* End of buffer */
TABLE *table= info->table;
(*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
info->cache_pos+= info->ref_length;
return 0;
}
/* cacheing of records from a database */ /* cacheing of records from a database */
static int init_rr_cache(READ_RECORD *info) static int init_rr_cache(READ_RECORD *info)
......
...@@ -167,6 +167,8 @@ sys_var_thd_ulong sys_pseudo_thread_id("pseudo_thread_id", ...@@ -167,6 +167,8 @@ sys_var_thd_ulong sys_pseudo_thread_id("pseudo_thread_id",
sys_var_thd_ha_rows sys_max_join_size("max_join_size", sys_var_thd_ha_rows sys_max_join_size("max_join_size",
&SV::max_join_size, &SV::max_join_size,
fix_max_join_size); fix_max_join_size);
sys_var_thd_ulong sys_max_length_for_sort_data("max_length_for_sort_data",
&SV::max_length_for_sort_data);
#ifndef TO_BE_DELETED /* Alias for max_join_size */ #ifndef TO_BE_DELETED /* Alias for max_join_size */
sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size",
&SV::max_join_size, &SV::max_join_size,
...@@ -385,6 +387,7 @@ sys_var *sys_variables[]= ...@@ -385,6 +387,7 @@ sys_var *sys_variables[]=
&sys_max_error_count, &sys_max_error_count,
&sys_max_heap_table_size, &sys_max_heap_table_size,
&sys_max_join_size, &sys_max_join_size,
&sys_max_length_for_sort_data,
&sys_max_prep_stmt_count, &sys_max_prep_stmt_count,
&sys_max_sort_length, &sys_max_sort_length,
&sys_max_tmp_tables, &sys_max_tmp_tables,
...@@ -541,6 +544,9 @@ struct show_var_st init_vars[]= { ...@@ -541,6 +544,9 @@ struct show_var_st init_vars[]= {
{sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS},
{sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS},
{sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS},
{sys_max_length_for_sort_data.name,
(char*) &sys_max_length_for_sort_data,
SHOW_SYS},
{sys_max_prep_stmt_count.name,(char*) &sys_max_prep_stmt_count, SHOW_SYS}, {sys_max_prep_stmt_count.name,(char*) &sys_max_prep_stmt_count, SHOW_SYS},
{sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
{sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
......
...@@ -245,16 +245,11 @@ static void free_cache_entry(TABLE *table) ...@@ -245,16 +245,11 @@ static void free_cache_entry(TABLE *table)
void free_io_cache(TABLE *table) void free_io_cache(TABLE *table)
{ {
DBUG_ENTER("free_io_cache"); DBUG_ENTER("free_io_cache");
if (table->io_cache) if (table->sort.io_cache)
{ {
close_cached_file(table->io_cache); close_cached_file(table->sort.io_cache);
my_free((gptr) table->io_cache,MYF(0)); my_free((gptr) table->sort.io_cache,MYF(0));
table->io_cache=0; table->sort.io_cache=0;
}
if (table->record_pointers)
{
my_free((gptr) table->record_pointers,MYF(0));
table->record_pointers=0;
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -354,6 +354,7 @@ struct system_variables ...@@ -354,6 +354,7 @@ struct system_variables
ulong max_allowed_packet; ulong max_allowed_packet;
ulong max_error_count; ulong max_error_count;
ulong max_heap_table_size; ulong max_heap_table_size;
ulong max_length_for_sort_data;
ulong max_prep_stmt_count; ulong max_prep_stmt_count;
ulong max_sort_length; ulong max_sort_length;
ulong max_tmp_tables; ulong max_tmp_tables;
......
...@@ -124,11 +124,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, ...@@ -124,11 +124,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
tables.table = table; tables.table = table;
table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_FAE | MY_ZEROFILL));
if (setup_order(thd, 0, &tables, fields, all_fields, order) || if (setup_order(thd, 0, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(thd, table, sortorder, length, (table->sort.found_records = filesort(thd, table, sortorder, length,
(SQL_SELECT *) 0, HA_POS_ERROR, (SQL_SELECT *) 0, HA_POS_ERROR,
&examined_rows)) &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
...@@ -4010,7 +4010,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -4010,7 +4010,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item_sum::AVG_FUNC: /* Place for sum & count */ case Item_sum::AVG_FUNC: /* Place for sum & count */
if (group) if (group)
return new Field_string(sizeof(double)+sizeof(longlong), return new Field_string(sizeof(double)+sizeof(longlong),
maybe_null, item->name,table,&my_charset_bin); 0, item->name,table,&my_charset_bin);
else else
return new Field_double(item_sum->max_length,maybe_null, return new Field_double(item_sum->max_length,maybe_null,
item->name, table, item_sum->decimals); item->name, table, item_sum->decimals);
...@@ -4018,7 +4018,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -4018,7 +4018,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item_sum::STD_FUNC: case Item_sum::STD_FUNC:
if (group) if (group)
return new Field_string(sizeof(double)*2+sizeof(longlong), return new Field_string(sizeof(double)*2+sizeof(longlong),
maybe_null, item->name,table,&my_charset_bin); 0, item->name,table,&my_charset_bin);
else else
return new Field_double(item_sum->max_length, maybe_null, return new Field_double(item_sum->max_length, maybe_null,
item->name,table,item_sum->decimals); item->name,table,item_sum->decimals);
...@@ -5622,11 +5622,11 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -5622,11 +5622,11 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
TABLE *table=jt->table; TABLE *table=jt->table;
join->select_options ^= OPTION_FOUND_ROWS; join->select_options ^= OPTION_FOUND_ROWS;
if (table->record_pointers || if (table->sort.record_pointers ||
(table->io_cache && my_b_inited(table->io_cache))) (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
{ {
/* Using filesort */ /* Using filesort */
join->send_records= table->found_records; join->send_records= table->sort.found_records;
} }
else else
{ {
...@@ -6461,7 +6461,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order, ...@@ -6461,7 +6461,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
if (!(sortorder=make_unireg_sortorder(order,&length))) if (!(sortorder=make_unireg_sortorder(order,&length)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
/* It's not fatal if the following alloc fails */ /* It's not fatal if the following alloc fails */
table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_WME | MY_ZEROFILL)); MYF(MY_WME | MY_ZEROFILL));
table->status=0; // May be wrong if quick_select table->status=0; // May be wrong if quick_select
...@@ -6491,9 +6491,9 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order, ...@@ -6491,9 +6491,9 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
} }
if (table->tmp_table) if (table->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count table->file->info(HA_STATUS_VARIABLE); // Get record count
table->found_records=filesort(thd, table,sortorder, length, table->sort.found_records=filesort(thd, table,sortorder, length,
select, filesort_limit, &examined_rows); select, filesort_limit, &examined_rows);
tab->records=table->found_records; // For SQL_CALC_ROWS tab->records=table->sort.found_records; // For SQL_CALC_ROWS
delete select; // filesort did select delete select; // filesort did select
tab->select=0; tab->select=0;
tab->select_cond=0; tab->select_cond=0;
...@@ -6505,7 +6505,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order, ...@@ -6505,7 +6505,7 @@ create_sort_index(THD *thd, JOIN_TAB *tab, ORDER *order,
table->key_read=0; table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD); table->file->extra(HA_EXTRA_NO_KEYREAD);
} }
DBUG_RETURN(table->found_records == HA_POS_ERROR); DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
err: err:
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
......
...@@ -19,6 +19,30 @@ ...@@ -19,6 +19,30 @@
#define MERGEBUFF 7 #define MERGEBUFF 7
#define MERGEBUFF2 15 #define MERGEBUFF2 15
/*
The structure SORT_ADDON_FIELD describes a fixed layout
for field values appended to sorted values in records to be sorted
in the sort buffer.
Only fixed layout is supported now.
Null bit maps for the appended values is placed before the values
themselves. Offsets are from the last sorted field, that is from the
record referefence, which is still last component of sorted records.
It is preserved for backward compatiblility.
The structure is used tp store values of the additional fields
in the sort buffer. It is used also when these values are read
from a temporary file/buffer. As the reading procedures are beyond the
scope of the 'filesort' code the values have to be retrieved via
the callback function 'unpack_addon_fields'.
*/
typedef struct st_sort_addon_field { /* Sort addon packed field */
Field *field; /* Original field */
uint offset; /* Offset from the last sorted field */
uint null_offset; /* Offset to to null bit from the last sorted field */
uint length; /* Length in the sort buffer */
uint8 null_bit; /* Null bit mask for the field */
} SORT_ADDON_FIELD;
typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
my_off_t file_pos; /* Where we are in the sort file */ my_off_t file_pos; /* Where we are in the sort file */
uchar *base,*key; /* key pointers */ uchar *base,*key; /* key pointers */
...@@ -27,15 +51,18 @@ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */ ...@@ -27,15 +51,18 @@ typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
ulong max_keys; /* Max keys in buffert */ ulong max_keys; /* Max keys in buffert */
} BUFFPEK; } BUFFPEK;
typedef struct st_sort_param { typedef struct st_sort_param {
uint sort_length; /* Length of sort columns */ uint rec_length; /* Length of sorted records */
uint keys; /* Max keys / buffert */ uint sort_length; /* Length of sorted columns */
uint ref_length; /* Length of record ref. */ uint ref_length; /* Length of record ref. */
uint addon_length; /* Length of added packed fields */
uint res_length; /* Length of records in final sorted file/buffer */
uint keys; /* Max keys / buffer */
ha_rows max_rows,examined_rows; ha_rows max_rows,examined_rows;
TABLE *sort_form; /* For quicker make_sortkey */ TABLE *sort_form; /* For quicker make_sortkey */
SORT_FIELD *local_sortorder; SORT_FIELD *local_sortorder;
SORT_FIELD *end; SORT_FIELD *end;
SORT_ADDON_FIELD *addon_field; /* Descriptors for companion fields */
uchar *unique_buff; uchar *unique_buff;
bool not_killable; bool not_killable;
char* tmp_buffer; char* tmp_buffer;
......
...@@ -2342,7 +2342,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -2342,7 +2342,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (order) if (order)
{ {
from->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_FAE | MY_ZEROFILL));
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
tables.table = from; tables.table = from;
...@@ -2355,7 +2355,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -2355,7 +2355,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
setup_order(thd, thd->lex.select_lex.ref_pointer_array, setup_order(thd, thd->lex.select_lex.ref_pointer_array,
&tables, fields, all_fields, order) || &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(from->found_records = filesort(thd, from, sortorder, length, (from->sort.found_records = filesort(thd, from, sortorder, length,
(SQL_SELECT *) 0, HA_POS_ERROR, (SQL_SELECT *) 0, HA_POS_ERROR,
&examined_rows)) &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
...@@ -201,14 +201,14 @@ int mysql_update(THD *thd, ...@@ -201,14 +201,14 @@ int mysql_update(THD *thd,
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
tables.table = table; tables.table = table;
table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_FAE | MY_ZEROFILL));
if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array, if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
order_num)|| order_num)||
setup_order(thd, thd->lex.select_lex.ref_pointer_array, setup_order(thd, thd->lex.select_lex.ref_pointer_array,
&tables, fields, all_fields, order) || &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(thd, table, sortorder, length, (table->sort.found_records = filesort(thd, table, sortorder, length,
(SQL_SELECT *) 0, (SQL_SELECT *) 0,
HA_POS_ERROR, &examined_rows)) HA_POS_ERROR, &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
...@@ -104,6 +104,7 @@ typedef struct st_read_record { /* Parameter to read_record */ ...@@ -104,6 +104,7 @@ typedef struct st_read_record { /* Parameter to read_record */
uint index; uint index;
byte *ref_pos; /* pointer to form->refpos */ byte *ref_pos; /* pointer to form->refpos */
byte *record; byte *record;
byte *rec_buf; /* to read field values after filesort */
byte *cache,*cache_pos,*cache_end,*read_positions; byte *cache,*cache_pos,*cache_end,*read_positions;
IO_CACHE *io_cache; IO_CACHE *io_cache;
bool print_error, ignore_not_found_rows; bool print_error, ignore_not_found_rows;
......
...@@ -44,6 +44,17 @@ typedef struct st_grant_info ...@@ -44,6 +44,17 @@ typedef struct st_grant_info
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2}; enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2};
typedef struct st_filesort_info
{
IO_CACHE *io_cache; /* If sorted through filebyte */
byte *addon_buf; /* Pointer to a buffer if sorted with fields */
uint addon_length; /* Length of the buffer */
struct st_sort_addon_field *addon_field; /* Pointer to the fields info */
void (*unpack)(struct st_sort_addon_field *, byte *); /* To unpack back */
byte *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */
} FILESORT_INFO;
/* Table cache entry struct */ /* Table cache entry struct */
class Field_timestamp; class Field_timestamp;
...@@ -120,9 +131,7 @@ struct st_table { ...@@ -120,9 +131,7 @@ struct st_table {
table_map map; /* ID bit of table (1,2,4,8,16...) */ table_map map; /* ID bit of table (1,2,4,8,16...) */
ulong version,flush_version; ulong version,flush_version;
uchar *null_flags; uchar *null_flags;
IO_CACHE *io_cache; /* If sorted trough filebyte */ FILESORT_INFO sort;
byte *record_pointers; /* If sorted in memory */
ha_rows found_records; /* How many records in sort */
ORDER *group; ORDER *group;
ha_rows quick_rows[MAX_KEY]; ha_rows quick_rows[MAX_KEY];
uint quick_key_parts[MAX_KEY]; uint quick_key_parts[MAX_KEY];
......
...@@ -95,12 +95,12 @@ bool Unique::flush() ...@@ -95,12 +95,12 @@ bool Unique::flush()
bool Unique::get(TABLE *table) bool Unique::get(TABLE *table)
{ {
SORTPARAM sort_param; SORTPARAM sort_param;
table->found_records=elements+tree.elements_in_tree; table->sort.found_records=elements+tree.elements_in_tree;
if (my_b_tell(&file) == 0) if (my_b_tell(&file) == 0)
{ {
/* Whole tree is in memory; Don't use disk if you don't need to */ /* Whole tree is in memory; Don't use disk if you don't need to */
if ((record_pointers=table->record_pointers= (byte*) if ((record_pointers=table->sort.record_pointers= (byte*)
my_malloc(tree.size_of_element * tree.elements_in_tree, MYF(0)))) my_malloc(tree.size_of_element * tree.elements_in_tree, MYF(0))))
{ {
(void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs, (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
...@@ -112,7 +112,7 @@ bool Unique::get(TABLE *table) ...@@ -112,7 +112,7 @@ bool Unique::get(TABLE *table)
if (flush()) if (flush())
return 1; return 1;
IO_CACHE *outfile=table->io_cache; IO_CACHE *outfile=table->sort.io_cache;
BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer; BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
uint maxbuffer= file_ptrs.elements - 1; uint maxbuffer= file_ptrs.elements - 1;
uchar *sort_buffer; uchar *sort_buffer;
...@@ -120,7 +120,7 @@ bool Unique::get(TABLE *table) ...@@ -120,7 +120,7 @@ bool Unique::get(TABLE *table)
bool error=1; bool error=1;
/* Open cached file if it isn't open */ /* Open cached file if it isn't open */
outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_ZEROFILL)); MYF(MY_ZEROFILL));
if (!outfile || ! my_b_inited(outfile) && if (!outfile || ! my_b_inited(outfile) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment