1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge on pull

BitKeeper/etc/ignore:
  auto-union
mysql-test/r/grant2.result:
  Auto merged
mysql-test/r/sql_mode.result:
  Auto merged
mysql-test/t/grant2.test:
  Auto merged
sql/handler.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
This commit is contained in:
unknown
2004-11-03 13:01:38 +02:00
1304 changed files with 58596 additions and 21834 deletions

View File

@ -29,7 +29,13 @@
#include <io.h>
#endif
const char *primary_key_name= "PRIMARY";
#define tmp_disable_binlog(A) \
ulong save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG;
#define reenable_binlog(A) (A)->options= save_options;
const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
@ -193,7 +199,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
for (table= tables; table; table= table->next_local)
{
char *db=table->db;
mysql_ha_close(thd, table, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL);
if (!close_temporary_table(thd, db, table->real_name))
{
tmp_table_deleted=1;
@ -218,8 +224,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
(void) unpack_filename(path,path);
}
if (drop_temporary || access(path,F_OK) ||
(!drop_view && mysql_frm_type(path) != FRMTYPE_TABLE))
if (drop_temporary ||
(access(path,F_OK) && ha_create_table_from_engine(thd,db,alias,TRUE)) ||
(!drop_view && mysql_frm_type(path) != FRMTYPE_TABLE))
{
if (if_exists)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
@ -362,19 +369,19 @@ static int sort_keys(KEY *a, KEY *b)
*/
void check_duplicates_in_interval(const char *set_or_name,
const char *name, TYPELIB *typelib)
const char *name, TYPELIB *typelib,
CHARSET_INFO *cs)
{
unsigned int old_count= typelib->count;
const char **old_type_names= typelib->type_names;
old_count= typelib->count;
old_type_names= typelib->type_names;
TYPELIB tmp= *typelib;
const char **cur_value= typelib->type_names;
for ( ; typelib->count > 1; cur_value++)
unsigned int *cur_length= typelib->type_lengths;
for ( ; tmp.count > 1; cur_value++, cur_length++)
{
typelib->type_names++;
typelib->count--;
if (find_type((char*)*cur_value,typelib,1))
tmp.type_names++;
tmp.type_lengths++;
tmp.count--;
if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
{
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_DUPLICATED_VALUE_IN_TYPE,
@ -382,8 +389,6 @@ void check_duplicates_in_interval(const char *set_or_name,
name,*cur_value,set_or_name);
}
}
typelib->count= old_count;
typelib->type_names= old_type_names;
}
/*
@ -563,7 +568,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::INTERVAL_FIELD;
check_duplicates_in_interval("ENUM",sql_field->field_name,
sql_field->interval);
sql_field->interval,
sql_field->charset);
break;
case FIELD_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
@ -572,7 +578,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::BIT_FIELD;
check_duplicates_in_interval("SET",sql_field->field_name,
sql_field->interval);
sql_field->interval,
sql_field->charset);
break;
case FIELD_TYPE_DATE: // Rest of string types
case FIELD_TYPE_NEWDATE:
@ -1238,8 +1245,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
bool create_if_not_exists =
create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
if (!create_table_from_handler(db, table_name,
create_if_not_exists))
if (!ha_create_table_from_engine(thd, db, table_name,
create_if_not_exists))
{
DBUG_PRINT("info", ("Table already existed in handler"));
@ -1344,10 +1351,9 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
MYSQL_LOCK **lock)
{
TABLE tmp_table; // Used during 'create_field()'
TABLE *table;
TABLE *table= 0;
tmp_table.table_name=0;
uint select_field_count= items->elements;
Disable_binlog disable_binlog(thd);
DBUG_ENTER("create_table_from_items");
/* Add selected items to field list */
@ -1368,7 +1374,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
field=item->tmp_table_field(&tmp_table);
else
field=create_tmp_field(thd, &tmp_table, item, item->type(),
(Item ***) 0, &tmp_field,0,0);
(Item ***) 0, &tmp_field,0,0,0);
if (!field ||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
((Item_field *)item)->field :
@ -1376,25 +1382,34 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(0);
extra_fields->push_back(cr_field);
}
/* create and lock table */
/* QQ: This should be done atomic ! */
if (mysql_create_table(thd, create_table->db, create_table->real_name,
create_info, *extra_fields, *keys, 0,
select_field_count))
DBUG_RETURN(0);
/*
create and lock table
We don't log the statement, it will be logged later.
If this is a HEAP table, the automatic DELETE FROM which is written to the
binlog when a HEAP table is opened for the first time since startup, must
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
don't want to delete from it) 2) it would be written before the CREATE
TABLE, which is a wrong order. So we keep binary logging disabled.
TABLE, which is a wrong order. So we keep binary logging disabled when we
open_table().
TODO: create and open should be done atomic !
*/
if (!(table= open_table(thd, create_table, &thd->mem_root, (bool*) 0)))
{
quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->real_name));
DBUG_RETURN(0);
tmp_disable_binlog(thd);
if (!mysql_create_table(thd, create_table->db, create_table->real_name,
create_info, *extra_fields, *keys, 0,
select_field_count))
{
if (!(table= open_table(thd, create_table, &thd->mem_root, (bool*) 0)))
quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->real_name));
}
reenable_binlog(thd);
if (!table) // open failed
DBUG_RETURN(0);
}
table->reginfo.lock_type=TL_WRITE;
if (!((*lock)= mysql_lock_tables(thd, &table,1)))
{
@ -1754,7 +1769,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(-1);
mysql_ha_close(thd, tables, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL);
for (table= tables; table; table= table->next_local)
{
char table_name[NAME_LEN*2+2];
@ -2258,31 +2273,32 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
&handler::check));
}
/* table_list should contain just one table */
int mysql_discard_or_import_tablespace(THD *thd,
TABLE_LIST *table_list,
enum tablespace_op_type tablespace_op)
static int
mysql_discard_or_import_tablespace(THD *thd,
TABLE_LIST *table_list,
enum tablespace_op_type tablespace_op)
{
TABLE *table;
my_bool discard;
int error;
DBUG_ENTER("mysql_discard_or_import_tablespace");
/* Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
ALTER TABLE */
/*
Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
ALTER TABLE
*/
thd->proc_info="discard_or_import_tablespace";
if (tablespace_op == DISCARD_TABLESPACE)
discard = TRUE;
else
discard = FALSE;
thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open
and ::external_lock() do not complain when we
lock the table */
mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
discard= test(tablespace_op == DISCARD_TABLESPACE);
/*
We set this flag so that ha_innobase::open and ::external_lock() do
not complain when we lock the table
*/
thd->tablespace_op= TRUE;
if (!(table=open_ltable(thd,table_list,TL_WRITE)))
{
thd->tablespace_op=FALSE;
@ -2296,8 +2312,10 @@ int mysql_discard_or_import_tablespace(THD *thd,
if (error)
goto err;
/* The 0 in the call below means 'not in a transaction', which means
immediate invalidation; that is probably what we wish here */
/*
The 0 in the call below means 'not in a transaction', which means
immediate invalidation; that is probably what we wish here
*/
query_cache_invalidate3(thd, table_list, 0);
/* The ALTER TABLE is always in its own transaction */
@ -2560,8 +2578,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
new_db= db;
used_fields=create_info->used_fields;
mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
@ -2604,7 +2621,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
else
{
if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0),
char dir_buff[FN_REFLEN];
strxnmov(dir_buff, FN_REFLEN, mysql_real_data_home, new_db, NullS);
if (!access(fn_format(new_name_buff,new_name_buff,dir_buff,reg_ext,0),
F_OK))
{
/* Table will be closed in do_command() */
@ -3030,12 +3049,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
else
create_info->data_file_name=create_info->index_file_name=0;
/* We don't log the statement, it will be logged later. */
{
/* We don't log the statement, it will be logged later */
Disable_binlog disable_binlog(thd);
if ((error=mysql_create_table(thd, new_db, tmp_name,
create_info,
create_list,key_list,1,0)))
tmp_disable_binlog(thd);
error= mysql_create_table(thd, new_db, tmp_name,
create_info,create_list,key_list,1,0);
reenable_binlog(thd);
if (error)
DBUG_RETURN(error);
}
if (need_copy_table)
@ -3063,11 +3084,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
}
/*
We don't want update TIMESTAMP fields during ALTER TABLE
and copy_data_between_tables uses only write_row() for new_table so
don't need to set up timestamp_on_update_now member.
*/
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
thd->proc_info="copy to tmp table";
@ -3271,8 +3289,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
my_free((char*) table, MYF(0));
}
else
sql_print_error("Warning: Could not open BDB table %s.%s after rename\n",
new_db,table_name);
sql_print_warning("Could not open BDB table %s.%s after rename\n",
new_db,table_name);
(void) berkeley_flush_logs();
}
#endif
@ -3313,15 +3331,19 @@ copy_data_between_tables(TABLE *from,TABLE *to,
List<Item> all_fields;
ha_rows examined_rows;
bool auto_increment_field_copied= 0;
ulong save_sql_mode;
DBUG_ENTER("copy_data_between_tables");
if (!(copy= new Copy_field[to->fields]))
DBUG_RETURN(-1); /* purecov: inspected */
to->file->external_lock(thd,F_WRLCK);
if (to->file->external_lock(thd, F_WRLCK))
DBUG_RETURN(-1);
from->file->info(HA_STATUS_VARIABLE);
to->file->start_bulk_insert(from->file->records);
save_sql_mode= thd->variables.sql_mode;
List_iterator<create_field> it(create);
create_field *def;
copy_end=copy;
@ -3331,7 +3353,17 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (def->field)
{
if (*ptr == to->next_number_field)
{
auto_increment_field_copied= TRUE;
/*
If we are going to copy contents of one auto_increment column to
another auto_increment column it is sensible to preserve zeroes.
This condition also covers case when we are don't actually alter
auto_increment column.
*/
if (def->field == from->found_next_number_field)
thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
}
(copy_end++)->set(*ptr,def->field,0);
}
@ -3364,7 +3396,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
Turn off recovery logging since rollback of an alter table is to
delete the new table so there is no need to log the changes to it.
*/
error= ha_recovery_logging(thd,FALSE);
error= ha_enable_transaction(thd,FALSE);
if (error)
{
error= 1;
@ -3427,7 +3459,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
ha_recovery_logging(thd,TRUE);
ha_enable_transaction(thd,TRUE);
/*
Ensure that the new table is saved properly to disk so that we
can do a rename
@ -3436,12 +3469,14 @@ copy_data_between_tables(TABLE *from,TABLE *to,
error=1;
if (ha_commit(thd))
error=1;
if (to->file->external_lock(thd,F_UNLCK))
error=1;
err:
thd->variables.sql_mode= save_sql_mode;
free_io_cache(from);
*copied= found_count;
*deleted=delete_count;
if (to->file->external_lock(thd,F_UNLCK))
error=1;
DBUG_RETURN(error > 0 ? -1 : 0);
}