Added ALTER TABLE ... ORDER BY ...
Docs/manual.texi: Added documentation for ALTER TABLE ... ORDER BY ... sql/mysql_priv.h: Exported make_unireg_sortorder Exported setup_order sql/sql_base.cc: Changes for ALTER TABLE ... ORDER BY ... sql/sql_parse.cc: Changes for ALTER TABLE ... ORDER BY ... sql/sql_select.cc: Moved make_unireg_sortorder and setup_order prototypes to mysql_priv.h and made them non-static so that they can be used elsewhere. Needed for ALTER TABLE ... ORDER BY ...
This commit is contained in:
parent
1acd5898ce
commit
c0f040274d
@ -17683,7 +17683,7 @@ using @code{myisampack}. @xref{Compressed format}.
|
|||||||
@section @code{ALTER TABLE} Syntax
|
@section @code{ALTER TABLE} Syntax
|
||||||
|
|
||||||
@example
|
@example
|
||||||
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
|
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...] [ORDER BY col]
|
||||||
|
|
||||||
alter_specification:
|
alter_specification:
|
||||||
ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
|
ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
|
||||||
@ -17832,6 +17832,14 @@ index exists, it drops the first @code{UNIQUE} index in the table.
|
|||||||
(@strong{MySQL} marks the first @code{UNIQUE} key as the @code{PRIMARY KEY}
|
(@strong{MySQL} marks the first @code{UNIQUE} key as the @code{PRIMARY KEY}
|
||||||
if no @code{PRIMARY KEY} was specified explicitly.)
|
if no @code{PRIMARY KEY} was specified explicitly.)
|
||||||
|
|
||||||
|
@findex ORDER BY
|
||||||
|
@item
|
||||||
|
@code {ORDER BY} allows you to create the new table with the rows in a
|
||||||
|
specific order. Note that the table will not remain in this order after
|
||||||
|
inserts and deletes. In some cases, it may make sorting easier for
|
||||||
|
@strong{MySQL} if the table is in order by the column that you wish to
|
||||||
|
order it by later.
|
||||||
|
|
||||||
@findex ALTER TABLE
|
@findex ALTER TABLE
|
||||||
@item
|
@item
|
||||||
If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique
|
If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique
|
||||||
@ -38312,6 +38320,9 @@ a temporary table
|
|||||||
@item
|
@item
|
||||||
@code{CHANGE MASTER TO} without specifying @code{MASTER_LOG_POS} would
|
@code{CHANGE MASTER TO} without specifying @code{MASTER_LOG_POS} would
|
||||||
set it to 0 instead of 4 and hit the magic number in the master binlog.
|
set it to 0 instead of 4 and hit the magic number in the master binlog.
|
||||||
|
@item
|
||||||
|
@code{ALTER TABLE ... ORDER BY ...} syntax added. This will create the
|
||||||
|
new table with the rows in a specific order.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
@ -281,6 +281,10 @@ bool net_store_data(String *packet,const char *from,uint length);
|
|||||||
bool net_store_data(String *packet,struct tm *tmp);
|
bool net_store_data(String *packet,struct tm *tmp);
|
||||||
bool net_store_data(String* packet, I_List<i_string>* str_list);
|
bool net_store_data(String* packet, I_List<i_string>* str_list);
|
||||||
|
|
||||||
|
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
|
||||||
|
int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
|
||||||
|
List <Item> &all_fields, ORDER *order);
|
||||||
|
|
||||||
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
|
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
|
||||||
List<Item_func_match> &ftfuncs,
|
List<Item_func_match> &ftfuncs,
|
||||||
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
|
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
|
||||||
@ -307,6 +311,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
|||||||
List<create_field> &fields,
|
List<create_field> &fields,
|
||||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||||
List<Alter_column> &alter_list,
|
List<Alter_column> &alter_list,
|
||||||
|
ORDER *order,
|
||||||
bool drop_primary,
|
bool drop_primary,
|
||||||
enum enum_duplicates handle_duplicates);
|
enum enum_duplicates handle_duplicates);
|
||||||
bool mysql_rename_table(enum db_type base,
|
bool mysql_rename_table(enum db_type base,
|
||||||
|
@ -1905,7 +1905,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
|||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
create_info.db_type=DB_TYPE_DEFAULT;
|
||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||||
&create_info, table_list,
|
&create_info, table_list,
|
||||||
fields, keys, drop, alter, FALSE, DUP_ERROR));
|
fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1920,7 +1920,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
|
|||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
create_info.db_type=DB_TYPE_DEFAULT;
|
||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||||
&create_info, table_list,
|
&create_info, table_list,
|
||||||
fields, keys, drop, alter, FALSE, DUP_ERROR));
|
fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -1158,6 +1158,7 @@ mysql_execute_command(void)
|
|||||||
&lex->create_info,
|
&lex->create_info,
|
||||||
tables, lex->create_list,
|
tables, lex->create_list,
|
||||||
lex->key_list, lex->drop_list, lex->alter_list,
|
lex->key_list, lex->drop_list, lex->alter_list,
|
||||||
|
(ORDER *) lex->order_list.first,
|
||||||
lex->drop_primary, lex->duplicates);
|
lex->drop_primary, lex->duplicates);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1262,6 +1263,7 @@ mysql_execute_command(void)
|
|||||||
res= mysql_alter_table(thd, NullS, NullS, &create_info,
|
res= mysql_alter_table(thd, NullS, NullS, &create_info,
|
||||||
tables, lex->create_list,
|
tables, lex->create_list,
|
||||||
lex->key_list, lex->drop_list, lex->alter_list,
|
lex->key_list, lex->drop_list, lex->alter_list,
|
||||||
|
(ORDER *) 0,
|
||||||
0,DUP_ERROR);
|
0,DUP_ERROR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -112,15 +112,12 @@ static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
|
|||||||
static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
static int remove_dup_with_hash_index(THD *thd, TABLE *table,
|
||||||
uint field_count, Field **first_field,
|
uint field_count, Field **first_field,
|
||||||
ulong key_length);
|
ulong key_length);
|
||||||
static SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
|
|
||||||
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
|
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
|
||||||
static ulong used_blob_length(CACHE_FIELD **ptr);
|
static ulong used_blob_length(CACHE_FIELD **ptr);
|
||||||
static bool store_record_in_cache(JOIN_CACHE *cache);
|
static bool store_record_in_cache(JOIN_CACHE *cache);
|
||||||
static void reset_cache(JOIN_CACHE *cache);
|
static void reset_cache(JOIN_CACHE *cache);
|
||||||
static void read_cached_record(JOIN_TAB *tab);
|
static void read_cached_record(JOIN_TAB *tab);
|
||||||
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
|
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
|
||||||
static int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
|
|
||||||
List <Item> &all_fields, ORDER *order);
|
|
||||||
static int setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
static int setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||||
List<Item> &all_fields, ORDER *order, bool *hidden);
|
List<Item> &all_fields, ORDER *order, bool *hidden);
|
||||||
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||||
@ -5409,8 +5406,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SORT_FIELD *
|
SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
|
||||||
make_unireg_sortorder(ORDER *order, uint *length)
|
|
||||||
{
|
{
|
||||||
uint count;
|
uint count;
|
||||||
SORT_FIELD *sort,*pos;
|
SORT_FIELD *sort,*pos;
|
||||||
@ -5752,8 +5748,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
|
|||||||
** and doesn't exits in the select list, add it the the field list.
|
** and doesn't exits in the select list, add it the the field list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
int setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||||
setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
|
||||||
List<Item> &all_fields, ORDER *order)
|
List<Item> &all_fields, ORDER *order)
|
||||||
{
|
{
|
||||||
thd->where="order clause";
|
thd->where="order clause";
|
||||||
|
@ -32,6 +32,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
|
|||||||
static int copy_data_between_tables(TABLE *from,TABLE *to,
|
static int copy_data_between_tables(TABLE *from,TABLE *to,
|
||||||
List<create_field> &create,
|
List<create_field> &create,
|
||||||
enum enum_duplicates handle_duplicates,
|
enum enum_duplicates handle_duplicates,
|
||||||
|
ORDER *order,
|
||||||
ha_rows *copied,ha_rows *deleted);
|
ha_rows *copied,ha_rows *deleted);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -1049,6 +1050,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
List<create_field> &fields,
|
List<create_field> &fields,
|
||||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||||
List<Alter_column> &alter_list,
|
List<Alter_column> &alter_list,
|
||||||
|
ORDER *order,
|
||||||
bool drop_primary,
|
bool drop_primary,
|
||||||
enum enum_duplicates handle_duplicates)
|
enum enum_duplicates handle_duplicates)
|
||||||
{
|
{
|
||||||
@ -1416,7 +1418,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
thd->proc_info="copy to tmp table";
|
thd->proc_info="copy to tmp table";
|
||||||
next_insert_id=thd->next_insert_id; // Remember for loggin
|
next_insert_id=thd->next_insert_id; // Remember for loggin
|
||||||
error=copy_data_between_tables(table,new_table,create_list,handle_duplicates,
|
error=copy_data_between_tables(table,new_table,create_list,handle_duplicates,
|
||||||
&copied,&deleted);
|
order, &copied,&deleted);
|
||||||
thd->last_insert_id=next_insert_id; // Needed for correct log
|
thd->last_insert_id=next_insert_id; // Needed for correct log
|
||||||
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
|
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
|
||||||
new_table->time_stamp=save_time_stamp;
|
new_table->time_stamp=save_time_stamp;
|
||||||
@ -1569,14 +1571,24 @@ end_temporary:
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
copy_data_between_tables(TABLE *from,TABLE *to,List<create_field> &create,
|
copy_data_between_tables(TABLE *from,TABLE *to,
|
||||||
|
List<create_field> &create,
|
||||||
enum enum_duplicates handle_duplicates,
|
enum enum_duplicates handle_duplicates,
|
||||||
ha_rows *copied,ha_rows *deleted)
|
ORDER *order,
|
||||||
|
ha_rows *copied,
|
||||||
|
ha_rows *deleted)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
Copy_field *copy,*copy_end;
|
Copy_field *copy,*copy_end;
|
||||||
ulong found_count,delete_count;
|
ulong found_count,delete_count;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
|
uint length;
|
||||||
|
SORT_FIELD *sortorder;
|
||||||
|
READ_RECORD info;
|
||||||
|
Field *next_field;
|
||||||
|
TABLE_LIST tables;
|
||||||
|
List<Item> fields;
|
||||||
|
List<Item> all_fields;
|
||||||
DBUG_ENTER("copy_data_between_tables");
|
DBUG_ENTER("copy_data_between_tables");
|
||||||
|
|
||||||
if (!(copy= new Copy_field[to->fields]))
|
if (!(copy= new Copy_field[to->fields]))
|
||||||
@ -1597,11 +1609,25 @@ copy_data_between_tables(TABLE *from,TABLE *to,List<create_field> &create,
|
|||||||
(copy_end++)->set(*ptr,def->field,0);
|
(copy_end++)->set(*ptr,def->field,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_RECORD info;
|
if(order) {
|
||||||
|
from->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||||
|
MYF(MY_FAE | MY_ZEROFILL));
|
||||||
|
bzero((char*) &tables,sizeof(tables));
|
||||||
|
tables.table = from;
|
||||||
|
error=1;
|
||||||
|
|
||||||
|
if (setup_order(thd, &tables, fields, all_fields, order) ||
|
||||||
|
!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||||
|
(from->found_records = filesort(&from, sortorder, length,
|
||||||
|
(SQL_SELECT *) 0, 0L, HA_POS_ERROR))
|
||||||
|
== HA_POS_ERROR)
|
||||||
|
goto err;
|
||||||
|
};
|
||||||
|
|
||||||
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
|
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
|
||||||
|
|
||||||
found_count=delete_count=0;
|
found_count=delete_count=0;
|
||||||
Field *next_field=to->next_number_field;
|
next_field=to->next_number_field;
|
||||||
while (!(error=info.read_record(&info)))
|
while (!(error=info.read_record(&info)))
|
||||||
{
|
{
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
@ -1640,6 +1666,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,List<create_field> &create,
|
|||||||
error=1;
|
error=1;
|
||||||
if (ha_commit(thd) || to->file->external_lock(thd,F_UNLCK))
|
if (ha_commit(thd) || to->file->external_lock(thd,F_UNLCK))
|
||||||
error=1;
|
error=1;
|
||||||
|
err:
|
||||||
|
free_io_cache(from);
|
||||||
*copied= found_count;
|
*copied= found_count;
|
||||||
*deleted=delete_count;
|
*deleted=delete_count;
|
||||||
DBUG_RETURN(error > 0 ? -1 : 0);
|
DBUG_RETURN(error > 0 ? -1 : 0);
|
||||||
|
@ -1030,14 +1030,18 @@ alter:
|
|||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->drop_list.empty();
|
lex->drop_list.empty();
|
||||||
lex->alter_list.empty();
|
lex->alter_list.empty();
|
||||||
|
lex->order_list.elements=0;
|
||||||
|
lex->order_list.first=0;
|
||||||
|
lex->order_list.next= (byte**) &lex->order_list.first;
|
||||||
lex->db=lex->name=0;
|
lex->db=lex->name=0;
|
||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||||
}
|
}
|
||||||
alter_list opt_create_table_options
|
alter_list order_clause opt_create_table_options
|
||||||
|
|
||||||
alter_list:
|
alter_list:
|
||||||
alter_list_item
|
/* empty */
|
||||||
|
| alter_list_item
|
||||||
| alter_list ',' alter_list_item
|
| alter_list ',' alter_list_item
|
||||||
|
|
||||||
add_column:
|
add_column:
|
||||||
@ -1075,7 +1079,7 @@ alter_list_item:
|
|||||||
{ Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); }
|
{ Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); }
|
||||||
| RENAME opt_to table_alias table_ident
|
| RENAME opt_to table_alias table_ident
|
||||||
{ Lex->db=$4->db.str ; Lex->name= $4->table.str; }
|
{ Lex->db=$4->db.str ; Lex->name= $4->table.str; }
|
||||||
| create_table_option
|
| opt_create_table_options
|
||||||
|
|
||||||
opt_column:
|
opt_column:
|
||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user