summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-04-08 23:50:10 +0300
committerunknown <bell@sanja.is.com.ua>2004-04-08 23:50:10 +0300
commit38f6c83e7faa799325d8f533aba56cedf3a0dc9c (patch)
tree562e5280dd8a63f7e243056e1e8a9e5f4747b2a7 /sql
parent52a62ce0b08832401741a1340b983620194d9fe6 (diff)
parente51447b1430e854fa0df1f37821e722cdb65d2bb (diff)
downloadmariadb-git-38f6c83e7faa799325d8f533aba56cedf3a0dc9c.tar.gz
merge
sql/mysql_priv.h: Auto merged sql/sql_select.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc98
-rw-r--r--sql/field.h3
-rw-r--r--sql/ha_myisam.cc4
-rw-r--r--sql/handler.cc138
-rw-r--r--sql/handler.h28
-rw-r--r--sql/mysql_priv.h25
-rw-r--r--sql/opt_range.cc341
-rw-r--r--sql/opt_range.h15
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_parse.cc46
-rw-r--r--sql/sql_select.cc74
-rw-r--r--sql/sql_table.cc1895
-rw-r--r--sql/table.cc1
-rw-r--r--sql/unireg.cc53
14 files changed, 1430 insertions, 1299 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 2da84ba1316..d865d2cc9e9 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4359,7 +4359,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
error= 1;
}
- memcpy(ptr+2,from,length);
+ memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length);
int2store(ptr, length);
return error;
}
@@ -4388,18 +4388,18 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void)
{
int not_used;
- uint length=uint2korr(ptr)+2;
+ uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH;
CHARSET_INFO *cs=charset();
- return my_strntod(cs,ptr+2,length,(char**)0, &not_used);
+ return my_strntod(cs, ptr+HA_KEY_BLOB_LENGTH, length, (char**)0, &not_used);
}
longlong Field_varstring::val_int(void)
{
int not_used;
- uint length=uint2korr(ptr)+2;
+ uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH;
CHARSET_INFO *cs=charset();
- return my_strntoll(cs,ptr+2,length,10,NULL, &not_used);
+ return my_strntoll(cs,ptr+HA_KEY_BLOB_LENGTH,length,10,NULL, &not_used);
}
@@ -4407,7 +4407,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr)
{
uint length=uint2korr(ptr);
- val_ptr->set((const char*) ptr+2,length,field_charset);
+ val_ptr->set((const char*) ptr+HA_KEY_BLOB_LENGTH,length,field_charset);
return val_ptr;
}
@@ -4417,18 +4417,21 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
uint a_length=uint2korr(a_ptr);
uint b_length=uint2korr(b_ptr);
int diff;
- diff=my_strnncoll(field_charset,
- (const uchar*)a_ptr+2,min(a_length,b_length),
- (const uchar*)b_ptr+2,min(a_length,b_length));
+ diff= my_strnncoll(field_charset,
+ (const uchar*) a_ptr+HA_KEY_BLOB_LENGTH,
+ min(a_length,b_length),
+ (const uchar*) b_ptr+HA_KEY_BLOB_LENGTH,
+ min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
}
void Field_varstring::sort_string(char *to,uint length)
{
uint tot_length=uint2korr(ptr);
- tot_length=my_strnxfrm(field_charset,
- (unsigned char *) to, length,
- (unsigned char *)ptr+2, tot_length);
+ tot_length= my_strnxfrm(field_charset,
+ (uchar*) to, length,
+ (uchar*) ptr+HA_KEY_BLOB_LENGTH,
+ tot_length);
if (tot_length < length)
field_charset->cset->fill(field_charset, to+tot_length,length-tot_length,
binary() ? (char) 0 : ' ');
@@ -4453,7 +4456,7 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
- memcpy(to, from+2, length);
+ memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
return to+length;
}
@@ -4473,7 +4476,7 @@ const char *Field_varstring::unpack(char *to, const char *from)
to[1] = *from++;
}
if (length)
- memcpy(to+2, from, length);
+ memcpy(to+HA_KEY_BLOB_LENGTH, from, length);
return from+length;
}
@@ -4484,8 +4487,8 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
uint b_length;
if (key_length > 255)
{
- a_length=uint2korr(a); a+=2;
- b_length=uint2korr(b); b+=2;
+ a_length=uint2korr(a); a+= 2;
+ b_length=uint2korr(b); b+= 2;
}
else
{
@@ -4493,32 +4496,32 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
- (const uchar *)a,a_length,
- (const uchar *)b,b_length);
+ (const uchar*) a, a_length,
+ (const uchar*) b, b_length);
}
int Field_varstring::pack_cmp(const char *b, uint key_length)
{
- char *a=ptr+2;
- uint a_length=uint2korr(ptr);
+ char *a= ptr+HA_KEY_BLOB_LENGTH;
+ uint a_length= uint2korr(ptr);
uint b_length;
if (key_length > 255)
{
- b_length=uint2korr(b); b+=2;
+ b_length=uint2korr(b); b+= 2;
}
else
{
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
- (const uchar *)a,a_length,
- (const uchar *)b,b_length);
+ (const uchar*) a, a_length,
+ (const uchar*) b, b_length);
}
uint Field_varstring::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
- return uint2korr(data_ptr)+2;
+ return uint2korr(data_ptr)+HA_KEY_BLOB_LENGTH;
else
return (uint) ((uchar) *data_ptr)+1;
}
@@ -4531,22 +4534,21 @@ uint Field_varstring::max_packed_col_length(uint max_length)
void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
{
- length-= HA_KEY_BLOB_LENGTH;
uint f_length=uint2korr(ptr);
if (f_length > length)
f_length= length;
int2store(buff,length);
- memcpy(buff+2,ptr+2,length);
+ memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, length);
#ifdef HAVE_purify
if (f_length < length)
- bzero(buff+2+f_length, (length-f_length));
+ bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
#endif
}
void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{
length=uint2korr(buff); // Real length is here
- (void) Field_varstring::store(buff+2, length, cs);
+ (void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
}
@@ -4799,7 +4801,6 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
void Field_blob::get_key_image(char *buff,uint length,
CHARSET_INFO *cs, imagetype type)
{
- length-= HA_KEY_BLOB_LENGTH;
uint32 blob_length= get_length(ptr);
char *blob;
@@ -4838,18 +4839,18 @@ void Field_blob::get_key_image(char *buff,uint length,
Must clear this as we do a memcmp in opt_range.cc to detect
identical keys
*/
- bzero(buff+2+blob_length, (length-blob_length));
+ bzero(buff+HA_KEY_BLOB_LENGTH+blob_length, (length-blob_length));
length=(uint) blob_length;
}
int2store(buff,length);
get_ptr(&blob);
- memcpy(buff+2,blob,length);
+ memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
}
void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{
- length=uint2korr(buff);
- (void) Field_blob::store(buff+2,length,cs);
+ length= uint2korr(buff);
+ (void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
}
@@ -4857,16 +4858,16 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{
char *blob1;
uint blob_length=get_length(ptr);
- max_key_length-=2;
memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
return Field_blob::cmp(blob1,min(blob_length, max_key_length),
- (char*) key_ptr+2,uint2korr(key_ptr));
+ (char*) key_ptr+HA_KEY_BLOB_LENGTH,
+ uint2korr(key_ptr));
}
int Field_blob::key_cmp(const byte *a,const byte *b)
{
- return Field_blob::cmp((char*) a+2,uint2korr(a),
- (char*) b+2,uint2korr(b));
+ return Field_blob::cmp((char*) a+HA_KEY_BLOB_LENGTH, uint2korr(a),
+ (char*) b+HA_KEY_BLOB_LENGTH, uint2korr(b));
}
@@ -4882,8 +4883,8 @@ void Field_blob::sort_string(char *to,uint length)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
blob_length=my_strnxfrm(field_charset,
- (unsigned char *)to, length,
- (unsigned char *)blob, blob_length);
+ (uchar*) to, length,
+ (uchar*) blob, blob_length);
if (blob_length < length)
field_charset->cset->fill(field_charset, to+blob_length,
length-blob_length,
@@ -4965,8 +4966,8 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
- (const uchar *)a,a_length,
- (const uchar *)b,b_length);
+ (const uchar*) a, a_length,
+ (const uchar*) b, b_length);
}
@@ -4988,8 +4989,8 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
- (const uchar *)a,a_length,
- (const uchar *)b,b_length);
+ (const uchar*) a, a_length,
+ (const uchar*) b, b_length);
}
/* Create a packed key that will be used for storage from a MySQL row */
@@ -5025,7 +5026,7 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
- memcpy(to, from+2, length);
+ memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
return to+length;
}
@@ -5048,11 +5049,12 @@ uint Field_blob::max_packed_col_length(uint max_length)
void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
{
- length-= HA_KEY_BLOB_LENGTH;
- ulong blob_length= get_length(ptr);
char *blob;
const char *dummy;
MBR mbr;
+ ulong blob_length= get_length(ptr);
+ Geometry_buffer buffer;
+ Geometry *gobj;
if (blob_length < SRID_SIZE)
{
@@ -5060,8 +5062,6 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
return;
}
get_ptr(&blob);
- Geometry_buffer buffer;
- Geometry *gobj;
gobj= Geometry::create_from_wkb(&buffer,
blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj->get_mbr(&mbr, &dummy))
@@ -5554,7 +5554,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
switch (type) {
case FIELD_TYPE_STRING:
case FIELD_TYPE_DECIMAL: return (length);
- case FIELD_TYPE_VAR_STRING: return (length+2);
+ case FIELD_TYPE_VAR_STRING: return (length+HA_KEY_BLOB_LENGTH);
case FIELD_TYPE_YEAR:
case FIELD_TYPE_TINY : return 1;
case FIELD_TYPE_SHORT : return 2;
diff --git a/sql/field.h b/sql/field.h
index 8ebc7412c35..4efabcead18 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -212,7 +212,8 @@ public:
{ memcpy(buff,ptr,length); }
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); }
- virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type)
+ virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
+ imagetype type)
{ get_image(buff,length,cs); }
virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs)
{ set_image(buff,length,cs); }
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index c56009dc0aa..b9d6cec38aa 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -867,7 +867,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
THD *thd=current_thd;
ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows);
- mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*)&size);
+ /* don't enable row cache if too few rows */
+ if (!rows && rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE)
+ mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
can_enable_indexes= (file->s->state.key_map ==
set_bits(ulonglong, file->s->base.keys));
diff --git a/sql/handler.cc b/sql/handler.cc
index ddf2e68db47..2b22563bc3c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1287,3 +1287,141 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
mi_change_key_cache(old_key_cache, new_key_cache);
return 0;
}
+
+
+/*
+ Read first row between two ranges.
+ Store ranges for future calls to read_range_next
+
+ SYNOPSIS
+ read_range_first()
+ start_key Start key. Is 0 if no min range
+ end_key End key. Is 0 if no max range
+ sorted Set to 1 if result should be sorted per key
+
+ NOTES
+ Record is read into table->record[0]
+
+ RETURN
+ 0 Found row
+ HA_ERR_END_OF_FILE No rows in range
+ # Error code
+*/
+
+int handler::read_range_first(const key_range *start_key,
+ const key_range *end_key,
+ bool sorted)
+{
+ int result;
+ DBUG_ENTER("handler::read_range_first");
+
+ end_range= 0;
+ if (end_key)
+ {
+ end_range= &save_end_range;
+ save_end_range= *end_key;
+ key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
+ (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
+ }
+ range_key_part= table->key_info[active_index].key_part;
+
+
+ if (!start_key) // Read first record
+ result= index_first(table->record[0]);
+ else
+ result= index_read(table->record[0],
+ start_key->key,
+ start_key->length,
+ start_key->flag);
+ if (result)
+ DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND ||
+ result == HA_ERR_END_OF_FILE) ? HA_ERR_END_OF_FILE :
+ result);
+
+ DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
+}
+
+
+/*
+ Read next row between two ranges.
+
+ SYNOPSIS
+ read_range_next()
+ eq_range Set to 1 if start_key == end_key
+
+ NOTES
+ Record is read into table->record[0]
+
+ RETURN
+ 0 Found row
+ HA_ERR_END_OF_FILE No rows in range
+ # Error code
+*/
+
+int handler::read_range_next(bool eq_range)
+{
+ int result;
+ DBUG_ENTER("handler::read_range_next");
+
+ if (eq_range)
+ result= index_next_same(table->record[0],
+ end_range->key,
+ end_range->length);
+ else
+ result= index_next(table->record[0]);
+ if (result)
+ DBUG_RETURN(result);
+ DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
+}
+
+
+/*
+ Compare if found key is over max-value
+
+ SYNOPSIS
+ compare_key
+ range key to compare to row
+
+ NOTES
+ For this to work, the row must be stored in table->record[0]
+
+ RETURN
+ 0 Key is equal to range or 'range' == 0 (no range)
+ -1 Key is less than range
+ 1 Key is larger than range
+*/
+
+int handler::compare_key(key_range *range)
+{
+ KEY_PART_INFO *key_part= range_key_part;
+ uint store_length;
+
+ if (!range)
+ return 0; // No max range
+
+ for (const char *key=range->key, *end=key+range->length;
+ key < end;
+ key+= store_length, key_part++)
+ {
+ int cmp;
+ store_length= key_part->store_length;
+ if (key_part->null_bit)
+ {
+ if (*key)
+ {
+ if (!key_part->field->is_null())
+ return 1;
+ continue;
+ }
+ else if (key_part->field->is_null())
+ return 0;
+ key++; // Skip null byte
+ store_length--;
+ }
+ if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0)
+ return -1;
+ if (cmp > 0)
+ return 1;
+ }
+ return key_compare_result_on_equal;
+}
diff --git a/sql/handler.h b/sql/handler.h
index 80a3c2e7f1b..4cb6ab86a37 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -92,10 +92,10 @@
/*
- Bits in index_ddl_flags(KEY *wanted_index)
- for what ddl you can do with index
- If none is set, the wanted type of index is not supported
- by the handler at all. See WorkLog 1563.
+ Bits in index_ddl_flags(KEY *wanted_index)
+ for what ddl you can do with index
+ If none is set, the wanted type of index is not supported
+ by the handler at all. See WorkLog 1563.
*/
#define HA_DDL_SUPPORT 1 /* Supported by handler */
#define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */
@@ -218,6 +218,14 @@ typedef struct st_ha_check_opt
} HA_CHECK_OPT;
+typedef struct st_key_range
+{
+ const byte *key;
+ uint length;
+ enum ha_rkey_function flag;
+} key_range;
+
+
class handler :public Sql_alloc
{
protected:
@@ -239,6 +247,12 @@ public:
time_t create_time; /* When table was created */
time_t check_time;
time_t update_time;
+
+ /* The following are for read_range() */
+ key_range save_end_range, *end_range;
+ KEY_PART_INFO *range_key_part;
+ int key_compare_result_on_equal;
+
uint errkey; /* Last dup key */
uint sortkey, key_used_on_scan;
uint active_index;
@@ -250,6 +264,7 @@ public:
bool auto_increment_column_changed;
bool implicit_emptied; /* Can be !=0 only if HEAP */
+
handler(TABLE *table_arg) :table(table_arg),
ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
delete_length(0), auto_increment_value(0),
@@ -298,6 +313,11 @@ public:
{
return (my_errno=HA_ERR_WRONG_COMMAND);
}
+ virtual int handler::read_range_first(const key_range *start_key,
+ const key_range *end_key,
+ bool sorted);
+ virtual int handler::read_range_next(bool eq_range);
+ int handler::compare_key(key_range *range);
virtual int ft_init()
{ return -1; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 78e0efa7ceb..7b73897eb18 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -516,23 +516,11 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_list,
- uint order_num, ORDER *order, int alter_flags,
+ uint order_num, ORDER *order, uint alter_flags,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
bool simple_alter=0);
-int real_alter_table(THD *thd, char *new_db, char *new_name,
- HA_CREATE_INFO *create_info,
- TABLE_LIST *table_list,
- TABLE *table,
- List<create_field> &fields,
- List<Key> &keys,List<Alter_drop> &drop_list,
- List<Alter_column> &alter_list,
- uint order_num, ORDER *order, int alter_flags,
- enum enum_duplicates handle_duplicates,
- enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
- enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
- bool simple_alter=0);
int mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info,
Table_ident *src_table);
@@ -544,10 +532,6 @@ bool mysql_rename_table(enum db_type base,
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
-int mysql_add_column(THD *thd, TABLE_LIST *table_list,
- List<create_field> &fields);
-int mysql_drop_column(THD *thd, TABLE_LIST *table_list,
- List<Alter_drop> &drop_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit,
@@ -951,9 +935,10 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
void unireg_init(ulong options);
void unireg_end(void);
-int mysql_create_frm(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
- List<create_field> &create_field,
- uint key_count,KEY *key_info,handler *db_type);
+bool mysql_create_frm(THD *thd, my_string file_name,
+ HA_CREATE_INFO *create_info,
+ List<create_field> &create_field,
+ uint key_count,KEY *key_info,handler *db_type);
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
List<create_field> &create_field,
uint key_count,KEY *key_info);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 38ff7f14c40..3ef1323893f 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -177,11 +177,11 @@ public:
if (maybe_null && *min_value)
{
**min_key=1;
- bzero(*min_key+1,length);
+ bzero(*min_key+1,length-1);
}
else
- memcpy(*min_key,min_value,length+(int) maybe_null);
- (*min_key)+= length+(int) maybe_null;
+ memcpy(*min_key,min_value,length);
+ (*min_key)+= length;
}
if (!(max_flag & NO_MAX_RANGE) &&
!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
@@ -189,18 +189,18 @@ public:
if (maybe_null && *max_value)
{
**max_key=1;
- bzero(*max_key+1,length);
+ bzero(*max_key+1,length-1);
}
else
- memcpy(*max_key,max_value,length+(int) maybe_null);
- (*max_key)+= length+(int) maybe_null;
+ memcpy(*max_key,max_value,length);
+ (*max_key)+= length;
}
}
void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
{
SEL_ARG *key_tree= first();
- key_tree->store(key[key_tree->part].part_length,
+ key_tree->store(key[key_tree->part].store_length,
range_key,*range_key_flag,range_key,NO_MAX_RANGE);
*range_key_flag|= key_tree->min_flag;
if (key_tree->next_key_part &&
@@ -213,7 +213,7 @@ public:
void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
{
SEL_ARG *key_tree= last();
- key_tree->store(key[key_tree->part].part_length,
+ key_tree->store(key[key_tree->part].store_length,
range_key, NO_MIN_RANGE, range_key,*range_key_flag);
(*range_key_flag)|= key_tree->max_flag;
if (key_tree->next_key_part &&
@@ -646,6 +646,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
MEM_ROOT *old_root,alloc;
SEL_TREE *tree;
KEY_PART *key_parts;
+ KEY *key_info;
PARAM param;
/* set up parameter that is passed to all functions */
@@ -671,24 +672,26 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
- for (idx=0 ; idx < head->keys ; idx++)
+ key_info= head->key_info;
+ for (idx=0 ; idx < head->keys ; idx++, key_info++)
{
+ KEY_PART_INFO *key_part_info;
if (!keys_to_use.is_set(idx))
continue;
- KEY *key_info= &head->key_info[idx];
if (key_info->flags & HA_FULLTEXT)
continue; // ToDo: ft-keys in non-ft ranges, if possible SerG
param.key[param.keys]=key_parts;
- for (uint part=0 ; part < key_info->key_parts ; part++,key_parts++)
+ key_part_info= key_info->key_part;
+ for (uint part=0 ; part < key_info->key_parts ;
+ part++, key_parts++, key_part_info++)
{
- key_parts->key=param.keys;
- key_parts->part=part;
- key_parts->part_length= key_info->key_part[part].length;
- key_parts->field= key_info->key_part[part].field;
- key_parts->null_bit= key_info->key_part[part].null_bit;
- if (key_parts->field->type() == FIELD_TYPE_BLOB)
- key_parts->part_length+=HA_KEY_BLOB_LENGTH;
+ key_parts->key= param.keys;
+ key_parts->part= part;
+ key_parts->length= key_part_info->length;
+ key_parts->store_length= key_part_info->store_length;
+ key_parts->field= key_part_info->field;
+ key_parts->null_bit= key_part_info->null_bit;
key_parts->image_type =
(key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW;
}
@@ -1043,18 +1046,26 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
DBUG_RETURN(0); // Can only optimize strings
offset=maybe_null;
- length=key_part->part_length;
- if (field->type() == FIELD_TYPE_BLOB)
+ length=key_part->store_length;
+
+ if (length != key_part->length + maybe_null)
{
- offset+=HA_KEY_BLOB_LENGTH;
- field_length=key_part->part_length-HA_KEY_BLOB_LENGTH;
+ /* key packed with length prefix */
+ offset+= HA_KEY_BLOB_LENGTH;
+ field_length= length - HA_KEY_BLOB_LENGTH;
}
else
{
- if (length < field_length)
- length=field_length; // Only if overlapping key
+ if (unlikely(length < field_length))
+ {
+ /*
+ This can only happen in a table created with UNIREG where one key
+ overlaps many fields
+ */
+ length= field_length;
+ }
else
- field_length=length;
+ field_length= length;
}
length+=offset;
if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
@@ -1067,7 +1078,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
res->ptr(), res->length(),
((Item_func_like*)(param->cond))->escape,
wild_one, wild_many,
- field_length,
+ field_length-maybe_null,
min_str+offset, max_str+offset,
&min_length, &max_length);
if (like_error) // Can't optimize with LIKE
@@ -1105,13 +1116,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
if (field->key_type() == HA_KEYTYPE_VARTEXT)
copies= 2;
str= str2= (char*) alloc_root(param->mem_root,
- (key_part->part_length+maybe_null)*copies+1);
+ (key_part->store_length)*copies+1);
if (!str)
DBUG_RETURN(0);
if (maybe_null)
*str= (char) field->is_real_null(); // Set to 1 if null
- field->get_key_image(str+maybe_null,key_part->part_length,
- field->charset(),key_part->image_type);
+ field->get_key_image(str+maybe_null, key_part->length,
+ field->charset(), key_part->image_type);
if (copies == 2)
{
/*
@@ -1120,16 +1131,17 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
all rows between 'X' and 'X ...'
*/
uint length= uint2korr(str+maybe_null);
- str2= str+ key_part->part_length + maybe_null;
+ str2= str+ key_part->store_length;
/* remove end space */
while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ')
length--;
int2store(str+maybe_null, length);
/* Create key that is space filled */
memcpy(str2, str, length + HA_KEY_BLOB_LENGTH + maybe_null);
- bfill(str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null,
- key_part->part_length-length - HA_KEY_BLOB_LENGTH, ' ');
- int2store(str2+maybe_null, key_part->part_length - HA_KEY_BLOB_LENGTH);
+ my_fill_8bit(field->charset(),
+ str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null,
+ key_part->length-length, ' ');
+ int2store(str2+maybe_null, key_part->length);
}
if (!(tree=new SEL_ARG(field,str,str2)))
DBUG_RETURN(0); // out of memory
@@ -1156,39 +1168,39 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
tree->max_flag=NO_MAX_RANGE;
break;
case Item_func::SP_EQUALS_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_DISJOINT_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_INTERSECTS_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_TOUCHES_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_CROSSES_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_WITHIN_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_CONTAINS_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
case Item_func::SP_OVERLAPS_FUNC:
- tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
- tree->max_flag=NO_MAX_RANGE;
- break;
+ tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
+ tree->max_flag=NO_MAX_RANGE;
+ break;
default:
break;
@@ -2236,7 +2248,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
uint tmp_min_flag,tmp_max_flag,keynr;
char *tmp_min_key=min_key,*tmp_max_key=max_key;
- key_tree->store(param->key[idx][key_tree->part].part_length,
+ key_tree->store(param->key[idx][key_tree->part].store_length,
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
uint min_key_length= (uint) (tmp_min_key- param->min_key);
uint max_key_length= (uint) (tmp_max_key- param->max_key);
@@ -2332,8 +2344,14 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
{
QUICK_SELECT *quick;
DBUG_ENTER("get_quick_select");
- if ((quick=new QUICK_SELECT(param->thd, param->table,
- param->real_keynr[idx])))
+
+ if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL)
+ quick=new QUICK_SELECT_GEOM(param->thd, param->table, param->real_keynr[idx],
+ 0);
+ else
+ quick=new QUICK_SELECT(param->thd, param->table, param->real_keynr[idx]);
+
+ if (quick)
{
if (quick->error ||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
@@ -2373,7 +2391,7 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
return 1;
}
char *tmp_min_key=min_key,*tmp_max_key=max_key;
- key_tree->store(key[key_tree->part].part_length,
+ key_tree->store(key[key_tree->part].store_length,
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
if (key_tree->next_key_part &&
@@ -2491,19 +2509,17 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
{
for (const char *end=key+length ;
key < end;
- key+= key_part++->part_length)
+ key+= key_part++->store_length)
{
- if (key_part->null_bit)
- {
- if (*key++)
- return 1;
- }
+ if (key_part->null_bit && *key)
+ return 1;
}
return 0;
}
+
/****************************************************************************
-** Create a QUICK RANGE based on a key
+ Create a QUICK RANGE based on a key
****************************************************************************/
QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
@@ -2541,9 +2557,8 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
key_part->part=part;
key_part->field= key_info->key_part[part].field;
- key_part->part_length= key_info->key_part[part].length;
- if (key_part->field->type() == FIELD_TYPE_BLOB)
- key_part->part_length+=HA_KEY_BLOB_LENGTH;
+ key_part->length= key_info->key_part[part].length;
+ key_part->store_length= key_info->key_part[part].store_length;
key_part->null_bit= key_info->key_part[part].null_bit;
}
if (quick->ranges.push_back(range))
@@ -2585,111 +2600,74 @@ int QUICK_SELECT::get_next()
for (;;)
{
int result;
+ key_range start_key, end_key;
if (range)
- { // Already read through key
- result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ?
- file->index_next_same(record, (byte*) range->min_key,
- range->min_length) :
- file->index_next(record));
-
- if (!result)
- {
- if ((range->flag & GEOM_FLAG) || !cmp_next(*it.ref()))
- DBUG_RETURN(0);
- }
- else if (result != HA_ERR_END_OF_FILE)
+ {
+ // Already read through key
+ result= file->read_range_next(test(range->flag & EQ_RANGE));
+ if (result != HA_ERR_END_OF_FILE)
DBUG_RETURN(result);
}
- if (!(range=it++))
+ if (!(range= it++))
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
- if (range->flag & GEOM_FLAG)
- {
- if ((result = file->index_read(record,
- (byte*) (range->min_key),
- range->min_length,
- (ha_rkey_function)(range->flag ^
- GEOM_FLAG))))
- {
- if (result != HA_ERR_KEY_NOT_FOUND)
- DBUG_RETURN(result);
- range=0; // Not found, to next range
- continue;
- }
- DBUG_RETURN(0);
- }
+ start_key.key= range->min_key;
+ start_key.length= range->min_length;
+ start_key.flag= ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
+ (range->flag & EQ_RANGE) ?
+ HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+ end_key.key= range->max_key;
+ end_key.length= range->max_length;
+ /*
+ We use READ_AFTER_KEY here because if we are reading on a key
+ prefix we want to find all keys with this prefix
+ */
+ end_key.flag= (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
+ HA_READ_AFTER_KEY);
- if (range->flag & NO_MIN_RANGE) // Read first record
- {
- int local_error;
- if ((local_error=file->index_first(record)))
- DBUG_RETURN(local_error); // Empty table
- if (cmp_next(range) == 0)
- DBUG_RETURN(0);
- range=0; // No matching records; go to next range
- continue;
- }
- if ((result = file->index_read(record,
- (byte*) (range->min_key +
- test(range->flag & GEOM_FLAG)),
- range->min_length,
- (range->flag & NEAR_MIN) ?
- HA_READ_AFTER_KEY:
- (range->flag & EQ_RANGE) ?
- HA_READ_KEY_EXACT :
- HA_READ_KEY_OR_NEXT)))
+ result= file->read_range_first(range->min_length ? &start_key : 0,
+ range->max_length ? &end_key : 0,
+ sorted);
+ if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
+ range=0; // Stop searching
- {
- if (result != HA_ERR_KEY_NOT_FOUND)
- DBUG_RETURN(result);
- range=0; // Not found, to next range
- continue;
- }
- if (cmp_next(range) == 0)
- {
- if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
- range=0; // Stop searching
- DBUG_RETURN(0); // Found key is in range
- }
- range=0; // To next range
+ if (result != HA_ERR_END_OF_FILE)
+ DBUG_RETURN(result);
+ range=0; // No matching rows; go to next range
}
}
-/*
- Compare if found key is over max-value
- Returns 0 if key <= range->max_key
-*/
+/* Get next for geometrical indexes */
-int QUICK_SELECT::cmp_next(QUICK_RANGE *range_arg)
+int QUICK_SELECT_GEOM::get_next()
{
- if (range_arg->flag & NO_MAX_RANGE)
- return 0; /* key can't be to large */
+ DBUG_ENTER(" QUICK_SELECT_GEOM::get_next");
- KEY_PART *key_part=key_parts;
- for (char *key=range_arg->max_key, *end=key+range_arg->max_length;
- key < end;
- key+= key_part++->part_length)
+ for (;;)
{
- int cmp;
- if (key_part->null_bit)
+ int result;
+ if (range)
{
- if (*key++)
- {
- if (!key_part->field->is_null())
- return 1;
- continue;
- }
- else if (key_part->field->is_null())
- return 0;
+ // Already read through key
+ result= file->index_next_same(record, (byte*) range->min_key,
+ range->min_length);
+ if (result != HA_ERR_END_OF_FILE)
+ DBUG_RETURN(result);
}
- if ((cmp=key_part->field->key_cmp((byte*) key, key_part->part_length)) < 0)
- return 0;
- if (cmp > 0)
- return 1;
+
+ if (!(range= it++))
+ DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
+
+ result= file->index_read(record,
+ (byte*) range->min_key,
+ range->min_length,
+ (ha_rkey_function)(range->flag ^ GEOM_FLAG));
+ if (result != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(result);
+ range=0; // Not found, to next range
}
- return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
}
@@ -2841,15 +2819,18 @@ int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg)
return 0; /* key can't be to small */
KEY_PART *key_part = key_parts;
+ uint store_length;
+
for (char *key = range_arg->min_key, *end = key + range_arg->min_length;
key < end;
- key += key_part++->part_length)
+ key += store_length, key_part++)
{
int cmp;
+ store_length= key_part->store_length;
if (key_part->null_bit)
{
// this key part allows null values; NULL is lower than everything else
- if (*key++)
+ if (*key)
{
// the range is expecting a null value
if (!key_part->field->is_null())
@@ -2858,9 +2839,11 @@ int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg)
}
else if (key_part->field->is_null())
return 1; // null -- outside the range
+ key++;
+ store_length--;
}
if ((cmp = key_part->field->key_cmp((byte*) key,
- key_part->part_length)) > 0)
+ key_part->length)) > 0)
return 0;
if (cmp < 0)
return 1;
@@ -2888,23 +2871,20 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
uint used_key_parts)
{
- uint offset,end;
+ uint offset, end;
KEY_PART *key_part = key_parts,
*key_part_end= key_part+used_key_parts;
for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ;
offset < end && key_part != key_part_end ;
- offset += key_part++->part_length)
+ offset+= key_part++->store_length)
{
- uint null_length=test(key_part->null_bit);
if (!memcmp((char*) range_arg->min_key+offset,
(char*) range_arg->max_key+offset,
- key_part->part_length + null_length))
- {
- offset+=null_length;
+ key_part->store_length))
continue;
- }
- if (null_length && range_arg->min_key[offset])
+
+ if (key_part->null_bit && range_arg->min_key[offset])
return 1; // min_key is null and max_key isn't
// Range doesn't cover NULL. This is ok if there is no more null parts
break;
@@ -2946,33 +2926,34 @@ static void
print_key(KEY_PART *key_part,const char *key,uint used_length)
{
char buff[1024];
+ const char *key_end= key+used_length;
String tmp(buff,sizeof(buff),&my_charset_bin);
+ uint store_length;
- for (uint length=0;
- length < used_length ;
- length+=key_part->part_length, key+=key_part->part_length, key_part++)
+ for (; key < key_end; key+=store_length, key_part++)
{
- Field *field=key_part->field;
- if (length != 0)
- fputc('/',DBUG_FILE);
+ Field *field= key_part->field;
+ store_length= key_part->store_length;
+
if (field->real_maybe_null())
{
- length++; // null byte is not in part_length
- if (*key++)
+ if (*key)
{
fwrite("NULL",sizeof(char),4,DBUG_FILE);
continue;
}
+ key++; // Skip null byte
+ store_length--;
}
- field->set_key_image((char*) key,key_part->part_length -
- ((field->type() == FIELD_TYPE_BLOB) ?
- HA_KEY_BLOB_LENGTH : 0),
- field->charset());
+ field->set_key_image((char*) key, key_part->length, field->charset());
field->val_str(&tmp);
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
+ if (key+store_length < key_end)
+ fputc('/',DBUG_FILE);
}
}
+
static void print_quick(QUICK_SELECT *quick,const key_map* needed_reg)
{
QUICK_RANGE *range;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index bf10c02c295..2df9d93e1ef 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -35,7 +35,7 @@
typedef struct st_key_part {
- uint16 key,part,part_length;
+ uint16 key,part, store_length, length;
uint8 null_bit;
Field *field;
Field::imagetype image_type;
@@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc {
class QUICK_SELECT {
public:
- bool next,dont_free;
+ bool next,dont_free,sorted;
int error;
uint index, max_used_key_length, used_key_parts;
TABLE *head;
@@ -89,11 +89,20 @@ public:
int init() { return error=file->index_init(index); }
virtual int get_next();
virtual bool reverse_sorted() { return 0; }
- int cmp_next(QUICK_RANGE *range);
bool unique_key_range();
};
+class QUICK_SELECT_GEOM: public QUICK_SELECT
+{
+public:
+ QUICK_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg, bool no_alloc)
+ :QUICK_SELECT(thd, table, index_arg, no_alloc)
+ {};
+ virtual int get_next();
+};
+
+
class QUICK_SELECT_DESC: public QUICK_SELECT
{
public:
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index c6aff403f5b..cc2ba29dbd8 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -260,6 +260,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->proc_info="update";
if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ /*
+ let's *try* to start bulk inserts. It won't necessary
+ start them as values_list.elements should be greater than
+ some - handler dependent - threshold.
+ So we call start_bulk_insert to perform nesessary checks on
+ values_list.elements, and - if nothing else - to initialize
+ the code to make the call of end_bulk_insert() below safe.
+ */
if (lock_type != TL_WRITE_DELAYED)
table->file->start_bulk_insert(values_list.elements);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0a501dd86c2..b6ce2424c96 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4908,6 +4908,52 @@ Item * all_any_subquery_creator(Item *left_expr,
/*
+ CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
+ the proper arguments. This isn't very fast but it should work for most
+ cases.
+
+ In the future ALTER TABLE will notice that only added indexes
+ and create these one by one for the existing table without having to do
+ a full rebuild.
+
+ One should normally create all indexes with CREATE TABLE or ALTER TABLE.
+*/
+
+int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
+{
+ List<create_field> fields;
+ List<Alter_drop> drop;
+ List<Alter_column> alter;
+ HA_CREATE_INFO create_info;
+ DBUG_ENTER("mysql_create_index");
+ bzero((char*) &create_info,sizeof(create_info));
+ create_info.db_type=DB_TYPE_DEFAULT;
+ create_info.default_table_charset= thd->variables.collation_database;
+ DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
+ &create_info, table_list,
+ fields, keys, drop, alter, 0, (ORDER*)0,
+ ALTER_ADD_INDEX, DUP_ERROR));
+}
+
+
+int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
+{
+ List<create_field> fields;
+ List<Key> keys;
+ List<Alter_column> alter;
+ HA_CREATE_INFO create_info;
+ DBUG_ENTER("mysql_drop_index");
+ bzero((char*) &create_info,sizeof(create_info));
+ create_info.db_type=DB_TYPE_DEFAULT;
+ create_info.default_table_charset= thd->variables.collation_database;
+ DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
+ &create_info, table_list,
+ fields, keys, drop, alter, 0, (ORDER*)0,
+ ALTER_DROP_INDEX, DUP_ERROR));
+}
+
+
+/*
Multi update query pre-check
SYNOPSIS
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c634dd0ab0e..bdc5091d386 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3746,7 +3746,8 @@ make_join_readinfo(JOIN *join, uint options)
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- else if (!table->used_keys.is_clear_all() && ! (tab->select && tab->select->quick))
+ else if (!table->used_keys.is_clear_all() &&
+ !(tab->select && tab->select->quick))
{ // Only read index tree
tab->index=find_shortest_key(table, & table->used_keys);
tab->table->file->index_init(tab->index);
@@ -6907,6 +6908,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
key_part_end=key_part+table->key_info[idx].key_parts;
key_part_map const_key_parts=table->const_key_parts[idx];
int reverse=0;
+ DBUG_ENTER("test_if_order_by_key");
for (; order ; order=order->next, const_key_parts>>=1)
{
@@ -6917,25 +6919,24 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
Skip key parts that are constants in the WHERE clause.
These are already skipped in the ORDER BY by const_expression_in_where()
*/
- while (const_key_parts & 1)
- {
- key_part++; const_key_parts>>=1;
- }
+ for (; const_key_parts & 1 ; const_key_parts>>= 1)
+ key_part++;
+
if (key_part == key_part_end || key_part->field != field)
- return 0;
+ DBUG_RETURN(0);
/* set flag to 1 if we can use read-next on key, else to -1 */
- flag=(order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT))
- ? 1 : -1;
+ flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ? 1 : -1);
if (reverse && flag != reverse)
- return 0;
+ DBUG_RETURN(0);
reverse=flag; // Remember if reverse
key_part++;
}
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
- return reverse;
+ DBUG_RETURN(reverse);
}
+
static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
uint min_length= (uint) ~0;
@@ -6958,18 +6959,20 @@ static uint find_shortest_key(TABLE *table, const key_map *usable_keys)
}
/*
+ Test if a second key is the subkey of the first one.
+
SYNOPSIS
is_subkey()
- key_part - first key parts
- ref_key_part - second key parts
- ref_key_part_end - last+1 part of the second key
- DESCRIPTION
- Test if a second key is the subkey of the first one.
+ key_part First key parts
+ ref_key_part Second key parts
+ ref_key_part_end Last+1 part of the second key
+
NOTE
Second key MUST be shorter than the first one.
+
RETURN
- 1 - is the subkey
- 0 - otherwise
+ 1 is a subkey
+ 0 no sub key
*/
inline bool
@@ -6983,20 +6986,21 @@ is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
}
/*
+ Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting
+
SYNOPSIS
test_if_subkey()
- ref - number of key, used for WHERE clause
- usable_keys - keys for testing
- DESCRIPTION
- Test if we can use one of the 'usable_keys' instead of 'ref' key.
+ ref Number of key, used for WHERE clause
+ usable_keys Keys for testing
+
RETURN
- MAX_KEY - if we can't use other key
- the number of found key - otherwise
+ MAX_KEY If we can't use other key
+ the number of found key Otherwise
*/
static uint
test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
- const key_map& usable_keys)
+ const key_map *usable_keys)
{
uint nr;
uint min_length= (uint) ~0;
@@ -7007,7 +7011,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
for (nr= 0 ; nr < table->keys ; nr++)
{
- if (usable_keys.is_set(nr) &&
+ if (usable_keys->is_set(nr) &&
table->key_info[nr].key_length < min_length &&
table->key_info[nr].key_parts >= ref_key_parts &&
is_subkey(table->key_info[nr].key_part, ref_key_part,
@@ -7051,12 +7055,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if ((*tmp_order->item)->type() != Item::FIELD_ITEM)
{
usable_keys.clear_all();
- break;
+ DBUG_RETURN(0);
}
- usable_keys.intersect(
- ((Item_field*) (*tmp_order->item))->field->part_of_sortkey);
+ usable_keys.intersect(((Item_field*) (*tmp_order->item))->
+ field->part_of_sortkey);
if (usable_keys.is_clear_all())
- break; // No usable keys
+ DBUG_RETURN(0); // No usable keys
}
ref_key= -1;
@@ -7092,9 +7096,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
keys
*/
if (table->used_keys.is_set(ref_key))
- usable_keys.merge(table->used_keys);
+ usable_keys.intersect(table->used_keys);
if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
- usable_keys)) < MAX_KEY)
+ &usable_keys)) < MAX_KEY)
{
/* Found key that can be used to retrieve data in sorted order */
if (tab->ref.key >= 0)
@@ -7154,6 +7158,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
/* fall through */
}
}
+ else if (select && select->quick)
+ select->quick->sorted= 1;
DBUG_RETURN(1); /* No need to sort */
}
}
@@ -7292,9 +7298,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
For impossible ranges (like when doing a lookup on NULL on a NOT NULL
field, quick will contain an empty record set.
*/
- if (!(select->quick= tab->type == JT_FT ?
- new FT_SELECT(thd, table, tab->ref.key) :
- get_quick_select_for_ref(thd, table, &tab->ref)))
+ if (!(select->quick= (tab->type == JT_FT ?
+ new FT_SELECT(thd, table, tab->ref.key) :
+ get_quick_select_for_ref(thd, table, &tab->ref))))
goto err;
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 17ea4cd540e..d5f77bf545d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -34,19 +34,19 @@ 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);
static int copy_data_between_tables(TABLE *from,TABLE *to,
- List<create_field> &create,
- enum enum_duplicates handle_duplicates,
- uint order_num, ORDER *order,
- ha_rows *copied,ha_rows *deleted);
+ List<create_field> &create,
+ enum enum_duplicates handle_duplicates,
+ uint order_num, ORDER *order,
+ ha_rows *copied,ha_rows *deleted);
/*
delete (drop) tables.
SYNOPSIS
mysql_rm_table()
- thd Thread handle
- tables List of tables to delete
- if_exists If 1, don't give error if one table doesn't exists
+ thd Thread handle
+ tables List of tables to delete
+ if_exists If 1, don't give error if one table doesn't exists
NOTES
Will delete all tables that can be deleted and give a compact error
@@ -57,13 +57,13 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
RETURN
- 0 ok. In this case ok packet is sent to user
- -1 Error (Error message given but not sent to user)
+ 0 ok. In this case ok packet is sent to user
+ -1 Error (Error message given but not sent to user)
*/
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
- my_bool drop_temporary)
+ my_bool drop_temporary)
{
int error= 0;
DBUG_ENTER("mysql_rm_table");
@@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
if (thd->global_read_lock)
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
- tables->real_name);
+ tables->real_name);
error= 1;
goto err;
}
@@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
SYNOPSIS
mysql_rm_table_part2_with_lock()
- thd Thread handle
- tables List of tables to delete
- if_exists If 1, don't give error if one table doesn't exists
- dont_log_query Don't write query to log files
+ thd Thread handle
+ tables List of tables to delete
+ if_exists If 1, don't give error if one table doesn't exists
+ dont_log_query Don't write query to log files
NOTES
Works like documented in mysql_rm_table(), but don't check
global_read_lock and don't send_ok packet to server.
RETURN
- 0 ok
- 1 error
+ 0 ok
+ 1 error
*/
int mysql_rm_table_part2_with_lock(THD *thd,
- TABLE_LIST *tables, bool if_exists,
- bool drop_temporary, bool dont_log_query)
+ TABLE_LIST *tables, bool if_exists,
+ bool drop_temporary, bool dont_log_query)
{
int error;
thd->mysys_var->current_mutex= &LOCK_open;
@@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd,
VOID(pthread_mutex_lock(&LOCK_open));
error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary,
- dont_log_query);
+ dont_log_query);
pthread_mutex_unlock(&LOCK_open);
@@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd,
SYNOPSIS
mysql_rm_table_part2()
- thd Thread handler
- tables Tables to drop
- if_exists If set, don't give an error if table doesn't exists.
- In this case we give an warning of level 'NOTE'
- drop_temporary Only drop temporary tables
- dont_log_query Don't log the query
+ thd Thread handler
+ tables Tables to drop
+ if_exists If set, don't give an error if table doesn't exists.
+ In this case we give an warning of level 'NOTE'
+ drop_temporary Only drop temporary tables
+ dont_log_query Don't log the query
TODO:
When logging to the binary log, we should log
@@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd,
not all.
RETURN
- 0 ok
- 1 Error
- -1 Thread was killed
+ 0 ok
+ 1 Error
+ -1 Thread was killed
*/
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
- bool drop_temporary, bool dont_log_query)
+ bool drop_temporary, bool dont_log_query)
{
TABLE_LIST *table;
- char path[FN_REFLEN], *alias;
+ char path[FN_REFLEN], *alias;
String wrong_tables;
int error;
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
@@ -195,7 +195,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if (!close_temporary_table(thd, db, table->real_name))
{
tmp_table_deleted=1;
- continue; // removed temporary table
+ continue; // removed temporary table
}
error=0;
@@ -204,13 +204,13 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
abort_locked_tables(thd,db,table->real_name);
while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed)
{
- dropping_tables++;
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- dropping_tables--;
+ dropping_tables++;
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ dropping_tables--;
}
drop_locked_tables(thd,db,table->real_name);
if (thd->killed)
- DBUG_RETURN(-1);
+ DBUG_RETURN(-1);
alias= (lower_case_table_names == 2) ? table->alias : table->real_name;
/* remove form file and isam files */
strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
@@ -219,37 +219,37 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if (drop_temporary || access(path,F_OK))
{
if (if_exists)
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
- table->real_name);
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
+ table->real_name);
else
- error= 1;
+ error= 1;
}
else
{
char *end;
db_type table_type= get_table_type(path);
- *(end=fn_ext(path))=0; // Remove extension for delete
+ *(end=fn_ext(path))=0; // Remove extension for delete
error=ha_delete_table(table_type, path);
if (error == ENOENT && if_exists)
- error = 0;
+ error = 0;
if (error == HA_ERR_ROW_IS_REFERENCED)
{
- /* the table is referenced by a foreign key constraint */
- foreign_key_error=1;
+ /* the table is referenced by a foreign key constraint */
+ foreign_key_error=1;
}
if (!error || error == ENOENT)
{
- /* Delete the table definition file */
- strmov(end,reg_ext);
- if (!(error=my_delete(path,MYF(MY_WME))))
- some_tables_deleted=1;
+ /* Delete the table definition file */
+ strmov(end,reg_ext);
+ if (!(error=my_delete(path,MYF(MY_WME))))
+ some_tables_deleted=1;
}
}
if (error)
{
if (wrong_tables.length())
- wrong_tables.append(',');
+ wrong_tables.append(',');
wrong_tables.append(String(table->real_name,system_charset_info));
}
}
@@ -262,10 +262,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- tmp_table_deleted && !some_tables_deleted);
- mysql_bin_log.write(&qinfo);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ tmp_table_deleted && !some_tables_deleted);
+ mysql_bin_log.write(&qinfo);
}
}
}
@@ -285,19 +285,16 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
int quick_rm_table(enum db_type base,const char *db,
- const char *table_name)
+ const char *table_name)
{
char path[FN_REFLEN];
int error=0;
- if (snprintf(path, sizeof(path), "%s/%s/%s%s",
- mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path))
- return 1;
+ my_snprintf(path, sizeof(path), "%s/%s/%s%s",
+ mysql_data_home, db, table_name, reg_ext);
unpack_filename(path,path);
if (my_delete(path,MYF(0)))
error=1; /* purecov: inspected */
- if (snprintf(path, sizeof(path), "%s/%s/%s",
- mysql_data_home, db, table_name)>= (int)sizeof(path))
- return 1;
+ my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
unpack_filename(path,path);
return ha_delete_table(base,path) || error;
}
@@ -331,32 +328,32 @@ static int sort_keys(KEY *a, KEY *b)
return 1;
}
else if (b->flags & HA_NOSAME)
- return 1; // Prefer b
+ return 1; // Prefer b
if ((a->flags ^ b->flags) & HA_FULLTEXT)
{
return (a->flags & HA_FULLTEXT) ? 1 : -1;
}
/*
- Prefer original key order. usable_key_parts contains here
+ Prefer original key order. usable_key_parts contains here
the original key position.
*/
return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
- (a->usable_key_parts > b->usable_key_parts) ? 1 :
- 0);
+ (a->usable_key_parts > b->usable_key_parts) ? 1 :
+ 0);
}
/*
Check TYPELIB (set or enum) for duplicates
-
+
SYNOPSIS
check_duplicates_in_interval()
set_or_name "SET" or "ENUM" string for warning message
- name name of the checked column
- typelib list of values for the column
+ name name of the checked column
+ typelib list of values for the column
DESCRIPTION
- This function prints an warning for each value in list
+ This function prints an warning for each value in list
which has some duplicates on its right
RETURN VALUES
@@ -364,7 +361,7 @@ 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)
{
unsigned int old_count= typelib->count;
const char **old_type_names= typelib->type_names;
@@ -379,9 +376,9 @@ void check_duplicates_in_interval(const char *set_or_name,
if (find_type((char*)*cur_value,typelib,1))
{
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_DUPLICATED_VALUE_IN_TYPE,
- ER(ER_DUPLICATED_VALUE_IN_TYPE),
- name,*cur_value,set_or_name);
+ ER_DUPLICATED_VALUE_IN_TYPE,
+ ER(ER_DUPLICATED_VALUE_IN_TYPE),
+ name,*cur_value,set_or_name);
}
}
typelib->count= old_count;
@@ -393,34 +390,34 @@ void check_duplicates_in_interval(const char *set_or_name,
SYNOPSIS
mysql_prepare_table()
- thd Thread object
- create_info Create information (like MAX_ROWS)
- fields List of fields to create
- keys List of keys to create
+ thd Thread object
+ create_info Create information (like MAX_ROWS)
+ fields List of fields to create
+ keys List of keys to create
DESCRIPTION
Prepares the table and key structures for table creation.
RETURN VALUES
- 0 ok
- -1 error
+ 0 ok
+ -1 error
*/
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
- List<create_field> &fields,
- List<Key> &keys, bool tmp_table, uint &db_options,
- handler *file, KEY *&key_info_buffer,
- uint &key_count, int select_field_count)
+ List<create_field> &fields,
+ List<Key> &keys, bool tmp_table, uint &db_options,
+ handler *file, KEY *&key_info_buffer,
+ uint *key_count, int select_field_count)
{
- const char *key_name;
- create_field *sql_field,*dup_field;
- uint field,null_fields,blob_columns;
- ulong pos;
- KEY *key_info;
+ const char *key_name;
+ create_field *sql_field,*dup_field;
+ uint field,null_fields,blob_columns;
+ ulong pos;
+ KEY *key_info;
KEY_PART_INFO *key_part_info;
- int timestamps= 0, timestamps_with_niladic= 0;
- int field_no,dup_no;
- int select_field_pos,auto_increment=0;
+ int timestamps= 0, timestamps_with_niladic= 0;
+ int field_no,dup_no;
+ int select_field_pos,auto_increment=0;
DBUG_ENTER("mysql_prepare_table");
List_iterator<create_field> it(fields),it2(fields);
@@ -450,13 +447,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
DBUG_RETURN(-1);
}
-
+
sql_field->create_length_to_internal_length();
/* Don't pack keys in old tables if the user has requested this */
if ((sql_field->flags & BLOB_FLAG) ||
- sql_field->sql_type == FIELD_TYPE_VAR_STRING &&
- create_info->row_type != ROW_TYPE_FIXED)
+ sql_field->sql_type == FIELD_TYPE_VAR_STRING &&
+ create_info->row_type != ROW_TYPE_FIXED)
{
db_options|=HA_OPTION_PACK_RECORD;
}
@@ -473,35 +470,35 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
{
if (my_strcasecmp(system_charset_info,
- sql_field->field_name,
- dup_field->field_name) == 0)
+ sql_field->field_name,
+ dup_field->field_name) == 0)
{
- /*
- If this was a CREATE ... SELECT statement, accept a field
- redefinition if we are changing a field in the SELECT part
- */
- if (field_no < select_field_pos || dup_no >= select_field_pos)
- {
- my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name);
- DBUG_RETURN(-1);
- }
- else
- {
- /* Field redefined */
- sql_field->sql_type= dup_field->sql_type;
- sql_field->charset= (dup_field->charset ?
- dup_field->charset :
- create_info->default_table_charset);
- sql_field->length= dup_field->length;
- sql_field->pack_length= dup_field->pack_length;
- sql_field->create_length_to_internal_length();
- sql_field->decimals= dup_field->decimals;
- sql_field->flags= dup_field->flags;
- sql_field->unireg_check= dup_field->unireg_check;
- it2.remove(); // Remove first (create) definition
- select_field_pos--;
- break;
- }
+ /*
+ If this was a CREATE ... SELECT statement, accept a field
+ redefinition if we are changing a field in the SELECT part
+ */
+ if (field_no < select_field_pos || dup_no >= select_field_pos)
+ {
+ my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name);
+ DBUG_RETURN(-1);
+ }
+ else
+ {
+ /* Field redefined */
+ sql_field->sql_type= dup_field->sql_type;
+ sql_field->charset= (dup_field->charset ?
+ dup_field->charset :
+ create_info->default_table_charset);
+ sql_field->length= dup_field->length;
+ sql_field->pack_length= dup_field->pack_length;
+ sql_field->create_length_to_internal_length();
+ sql_field->decimals= dup_field->decimals;
+ sql_field->flags= dup_field->flags;
+ sql_field->unireg_check= dup_field->unireg_check;
+ it2.remove(); // Remove first (create) definition
+ select_field_pos--;
+ break;
+ }
}
}
it2.rewind();
@@ -522,11 +519,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_LONG_BLOB:
sql_field->pack_flag=FIELDFLAG_BLOB |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
sql_field->unireg_check=Field::BLOB_FIELD;
blob_columns++;
break;
@@ -534,49 +531,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_SPATIAL
if (!(file->table_flags() & HA_HAS_GEOMETRY))
{
- my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
- MYF(0), "GEOMETRY");
- DBUG_RETURN(-1);
+ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
+ MYF(0), "GEOMETRY");
+ DBUG_RETURN(-1);
}
sql_field->pack_flag=FIELDFLAG_GEOM |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
sql_field->unireg_check=Field::BLOB_FIELD;
blob_columns++;
break;
#else
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
+ sym_group_geom.name, sym_group_geom.needed_define);
DBUG_RETURN(-1);
#endif /*HAVE_SPATIAL*/
case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_STRING:
sql_field->pack_flag=0;
if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
break;
case FIELD_TYPE_ENUM:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_INTERVAL;
+ FIELDFLAG_INTERVAL;
if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
+ 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);
break;
case FIELD_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_BITFIELD;
+ FIELDFLAG_BITFIELD;
if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
+ 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);
break;
- case FIELD_TYPE_DATE: // Rest of string types
+ case FIELD_TYPE_DATE: // Rest of string types
case FIELD_TYPE_NEWDATE:
case FIELD_TYPE_TIME:
case FIELD_TYPE_DATETIME:
@@ -587,27 +584,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* We should replace old TIMESTAMP fields with their newer analogs */
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
{
- if (!timestamps)
- {
- sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- timestamps_with_niladic++;
- }
- else
- sql_field->unireg_check= Field::NONE;
+ if (!timestamps)
+ {
+ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ timestamps_with_niladic++;
+ }
+ else
+ sql_field->unireg_check= Field::NONE;
}
else if (sql_field->unireg_check != Field::NONE)
- timestamps_with_niladic++;
-
+ timestamps_with_niladic++;
+
timestamps++;
/* fall-through */
default:
sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- f_settype((uint) sql_field->sql_type) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ f_settype((uint) sql_field->sql_type) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
break;
}
if (!(sql_field->flags & NOT_NULL_FLAG))
@@ -644,13 +641,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List_iterator<Key> key_iterator(keys);
uint key_parts=0, fk_key_count=0;
- List<Key> keys_in_order; // Add new keys here
+ List<Key> keys_in_order; // Add new keys here
bool primary_key=0,unique_key=0;
Key *key;
uint tmp, key_number;
/* Calculate number of key segements */
- key_count=0;
+ *key_count= 0;
while ((key=key_iterator++))
{
@@ -659,16 +656,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
fk_key_count++;
foreign_key *fk_key= (foreign_key*) key;
if (fk_key->ref_columns.elements &&
- fk_key->ref_columns.elements != fk_key->columns.elements)
+ fk_key->ref_columns.elements != fk_key->columns.elements)
{
- my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name :
- "foreign key without name",
- ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
- DBUG_RETURN(-1);
+ my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name :
+ "foreign key without name",
+ ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
+ DBUG_RETURN(-1);
}
continue;
}
- key_count++;
+ (*key_count)++;
tmp=max(file->max_key_parts(),MAX_REF_PARTS);
if (key->columns.elements > tmp)
{
@@ -682,23 +679,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
key_parts+=key->columns.elements;
if (key->name && !tmp_table &&
- !my_strcasecmp(system_charset_info,key->name,primary_key_name))
+ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
{
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
DBUG_RETURN(-1);
}
}
tmp=min(file->max_keys(), MAX_KEY);
- if (key_count > tmp)
+ if (*key_count > tmp)
{
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
DBUG_RETURN(-1);
}
- key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
+ key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)* *key_count);
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
if (!key_info_buffer || ! key_part_info)
- DBUG_RETURN(-1); // Out of memory
+ DBUG_RETURN(-1); // Out of memory
key_iterator.rewind();
key_number=0;
@@ -709,25 +706,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
switch(key->type){
case Key::MULTIPLE:
- key_info->flags = 0;
- break;
+ key_info->flags = 0;
+ break;
case Key::FULLTEXT:
- key_info->flags = HA_FULLTEXT;
- break;
+ key_info->flags = HA_FULLTEXT;
+ break;
case Key::SPATIAL:
#ifdef HAVE_SPATIAL
- key_info->flags = HA_SPATIAL;
- break;
+ key_info->flags = HA_SPATIAL;
+ break;
#else
- my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- DBUG_RETURN(-1);
+ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ DBUG_RETURN(-1);
#endif
case Key::FOREIGN_KEY:
- key_number--; // Skip this key
+ key_number--; // Skip this key
continue;
default:
- key_info->flags = HA_NOSAME;
+ key_info->flags = HA_NOSAME;
}
key_info->key_parts=(uint8) key->columns.elements;
@@ -739,8 +736,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
if (!(file->table_flags() & HA_CAN_FULLTEXT))
{
- my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
- DBUG_RETURN(-1);
+ my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
+ DBUG_RETURN(-1);
}
}
/*
@@ -756,9 +753,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
if (key_info->key_parts != 1)
{
- my_printf_error(ER_WRONG_ARGUMENTS,
- ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX");
- DBUG_RETURN(-1);
+ my_printf_error(ER_WRONG_ARGUMENTS,
+ ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX");
+ DBUG_RETURN(-1);
}
}
else
@@ -767,17 +764,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_RTREE_KEYS
if ((key_info->key_parts & 1) == 1)
{
- my_printf_error(ER_WRONG_ARGUMENTS,
- ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX");
- DBUG_RETURN(-1);
+ my_printf_error(ER_WRONG_ARGUMENTS,
+ ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX");
+ DBUG_RETURN(-1);
}
/* TODO: To be deleted */
my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET),
- MYF(0), "RTREE INDEX");
+ MYF(0), "RTREE INDEX");
DBUG_RETURN(-1);
#else
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
- sym_group_rtree.name, sym_group_rtree.needed_define);
+ sym_group_rtree.name, sym_group_rtree.needed_define);
DBUG_RETURN(-1);
#endif
}
@@ -789,106 +786,106 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
it.rewind();
field=0;
while ((sql_field=it++) &&
- my_strcasecmp(system_charset_info,
- column->field_name,
- sql_field->field_name))
- field++;
+ my_strcasecmp(system_charset_info,
+ column->field_name,
+ sql_field->field_name))
+ field++;
if (!sql_field)
{
- my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS,
- ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
+ my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS,
+ ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
}
/* for fulltext keys keyseg length is 1 for blobs (it's ignored in
- ft code anyway, and 0 (set to column width later) for char's.
- it has to be correct col width for char's, as char data are not
- prefixed with length (unlike blobs, where ft code takes data length
- from a data prefix, ignoring column->length).
+ ft code anyway, and 0 (set to column width later) for char's.
+ it has to be correct col width for char's, as char data are not
+ prefixed with length (unlike blobs, where ft code takes data length
+ from a data prefix, ignoring column->length).
*/
if (key->type == Key::FULLTEXT)
{
- if ((sql_field->sql_type != FIELD_TYPE_STRING &&
- sql_field->sql_type != FIELD_TYPE_VAR_STRING &&
- !f_is_blob(sql_field->pack_flag)) ||
- sql_field->charset == &my_charset_bin ||
- sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet
- (ft_key_charset && sql_field->charset != ft_key_charset))
- {
- my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
- }
- ft_key_charset=sql_field->charset;
- /*
- for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
- code anyway, and 0 (set to column width later) for char's. it has
- to be correct col width for char's, as char data are not prefixed
- with length (unlike blobs, where ft code takes data length from a
- data prefix, ignoring column->length).
- */
- column->length=test(f_is_blob(sql_field->pack_flag));
+ if ((sql_field->sql_type != FIELD_TYPE_STRING &&
+ sql_field->sql_type != FIELD_TYPE_VAR_STRING &&
+ !f_is_blob(sql_field->pack_flag)) ||
+ sql_field->charset == &my_charset_bin ||
+ sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet
+ (ft_key_charset && sql_field->charset != ft_key_charset))
+ {
+ my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
+ }
+ ft_key_charset=sql_field->charset;
+ /*
+ for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
+ code anyway, and 0 (set to column width later) for char's. it has
+ to be correct col width for char's, as char data are not prefixed
+ with length (unlike blobs, where ft code takes data length from a
+ data prefix, ignoring column->length).
+ */
+ column->length=test(f_is_blob(sql_field->pack_flag));
}
else
{
- column->length*= sql_field->charset->mbmaxlen;
-
- if (f_is_blob(sql_field->pack_flag))
- {
- if (!(file->table_flags() & HA_BLOB_KEY))
- {
- my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
- }
- if (!column->length)
- {
- my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
- ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
- }
- }
+ column->length*= sql_field->charset->mbmaxlen;
+
+ if (f_is_blob(sql_field->pack_flag))
+ {
+ if (!(file->table_flags() & HA_BLOB_KEY))
+ {
+ my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
+ }
+ if (!column->length)
+ {
+ my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
+ ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
+ }
+ }
#ifdef HAVE_SPATIAL
- if (key->type == Key::SPATIAL)
- {
- if (!column->length )
- {
- /*
- BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
- Lately we'll extend this code to support more dimensions
- */
- column->length=4*sizeof(double);
- }
- }
+ if (key->type == Key::SPATIAL)
+ {
+ if (!column->length )
+ {
+ /*
+ BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
+ Lately we'll extend this code to support more dimensions
+ */
+ column->length=4*sizeof(double);
+ }
+ }
#endif
- if (!(sql_field->flags & NOT_NULL_FLAG))
- {
- if (key->type == Key::PRIMARY)
- {
- /* Implicitly set primary key fields to NOT NULL for ISO conf. */
- sql_field->flags|= NOT_NULL_FLAG;
- sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
- }
- else
- key_info->flags|= HA_NULL_PART_KEY;
- if (!(file->table_flags() & HA_NULL_KEY))
- {
- my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
- MYF(0),column->field_name);
- DBUG_RETURN(-1);
- }
- if (key->type == Key::SPATIAL)
- {
- my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0));
- DBUG_RETURN(-1);
- }
- }
- if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
- {
- if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY))
- auto_increment--; // Field is used
- }
+ if (!(sql_field->flags & NOT_NULL_FLAG))
+ {
+ if (key->type == Key::PRIMARY)
+ {
+ /* Implicitly set primary key fields to NOT NULL for ISO conf. */
+ sql_field->flags|= NOT_NULL_FLAG;
+ sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
+ }
+ else
+ key_info->flags|= HA_NULL_PART_KEY;
+ if (!(file->table_flags() & HA_NULL_KEY))
+ {
+ my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
+ MYF(0),column->field_name);
+ DBUG_RETURN(-1);
+ }
+ if (key->type == Key::SPATIAL)
+ {
+ my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0));
+ DBUG_RETURN(-1);
+ }
+ }
+ if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
+ {
+ if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY))
+ auto_increment--; // Field is used
+ }
}
key_part_info->fieldnr= field;
@@ -897,79 +894,77 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
uint length=sql_field->pack_length;
if (column->length)
{
- if (f_is_blob(sql_field->pack_flag))
- {
- if ((length=column->length) > file->max_key_length() ||
- length > file->max_key_part_length())
- {
- length=min(file->max_key_length(), file->max_key_part_length());
- if (key->type == Key::MULTIPLE)
- {
- /* not a critical problem */
- char warn_buff[MYSQL_ERRMSG_SIZE];
- if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
- length)>= (int)sizeof(warn_buff))
- DBUG_RETURN(-1);
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TOO_LONG_KEY, warn_buff);
- }
- else
- {
- my_error(ER_TOO_LONG_KEY,MYF(0),length);
- DBUG_RETURN(-1);
- }
- }
- }
- else if (!f_is_geom(sql_field->pack_flag) &&
- (column->length > length ||
- ((f_is_packed(sql_field->pack_flag) ||
- ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
- (key_info->flags & HA_NOSAME))) &&
- column->length != length)))
- {
- my_error(ER_WRONG_SUB_KEY,MYF(0));
- DBUG_RETURN(-1);
- }
- else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
- length=column->length;
+ if (f_is_blob(sql_field->pack_flag))
+ {
+ if ((length=column->length) > file->max_key_length() ||
+ length > file->max_key_part_length())
+ {
+ length=min(file->max_key_length(), file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+ char warn_buff[MYSQL_ERRMSG_SIZE];
+ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
+ length);
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TOO_LONG_KEY, warn_buff);
+ }
+ else
+ {
+ my_error(ER_TOO_LONG_KEY,MYF(0),length);
+ DBUG_RETURN(-1);
+ }
+ }
+ }
+ else if (!f_is_geom(sql_field->pack_flag) &&
+ (column->length > length ||
+ ((f_is_packed(sql_field->pack_flag) ||
+ ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
+ (key_info->flags & HA_NOSAME))) &&
+ column->length != length)))
+ {
+ my_error(ER_WRONG_SUB_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
+ length=column->length;
}
else if (length == 0)
{
- my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
+ my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
}
if (length > file->max_key_part_length())
{
- length=file->max_key_part_length();
- if (key->type == Key::MULTIPLE)
- {
- /* not a critical problem */
- char warn_buff[MYSQL_ERRMSG_SIZE];
- if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
- length)>= (int)sizeof(warn_buff))
- DBUG_RETURN(-1);
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TOO_LONG_KEY, warn_buff);
- }
- else
- {
- my_error(ER_TOO_LONG_KEY,MYF(0),length);
- DBUG_RETURN(-1);
- }
+ length=file->max_key_part_length();
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+ char warn_buff[MYSQL_ERRMSG_SIZE];
+ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
+ length);
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TOO_LONG_KEY, warn_buff);
+ }
+ else
+ {
+ my_error(ER_TOO_LONG_KEY,MYF(0),length);
+ DBUG_RETURN(-1);
+ }
}
key_part_info->length=(uint16) length;
/* Use packed keys for long strings on the first column */
if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
- (length >= KEY_DEFAULT_PACK_LENGTH &&
- (sql_field->sql_type == FIELD_TYPE_STRING ||
- sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
- sql_field->pack_flag & FIELDFLAG_BLOB)))
+ (length >= KEY_DEFAULT_PACK_LENGTH &&
+ (sql_field->sql_type == FIELD_TYPE_STRING ||
+ sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
+ sql_field->pack_flag & FIELDFLAG_BLOB)))
{
- if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB))
- key_info->flags|= HA_BINARY_PACK_KEY;
- else
- key_info->flags|= HA_PACK_KEY;
+ if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB))
+ key_info->flags|= HA_BINARY_PACK_KEY;
+ else
+ key_info->flags|= HA_PACK_KEY;
}
key_length+=length;
key_part_info++;
@@ -977,25 +972,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* Create the key name based on the first column (if not given) */
if (column_nr == 0)
{
- if (key->type == Key::PRIMARY)
- {
- if (primary_key)
- {
- my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
- DBUG_RETURN(-1);
- }
- key_name=primary_key_name;
- primary_key=1;
- }
- else if (!(key_name = key->name))
- key_name=make_unique_key_name(sql_field->field_name,
- key_info_buffer,key_info);
- if (check_if_keyname_exists(key_name,key_info_buffer,key_info))
- {
- my_error(ER_DUP_KEYNAME,MYF(0),key_name);
- DBUG_RETURN(-1);
- }
- key_info->name=(char*) key_name;
+ if (key->type == Key::PRIMARY)
+ {
+ if (primary_key)
+ {
+ my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_name=primary_key_name;
+ primary_key=1;
+ }
+ else if (!(key_name = key->name))
+ key_name=make_unique_key_name(sql_field->field_name,
+ key_info_buffer,key_info);
+ if (check_if_keyname_exists(key_name,key_info_buffer,key_info))
+ {
+ my_error(ER_DUP_KEYNAME,MYF(0),key_name);
+ DBUG_RETURN(-1);
+ }
+ key_info->name=(char*) key_name;
}
}
if (!key_info->name || check_column_name(key_info->name))
@@ -1026,25 +1021,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
/* Sort keys in optimized order */
- qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
+ qsort((gptr) key_info_buffer, *key_count, sizeof(KEY),
+ (qsort_cmp) sort_keys);
DBUG_RETURN(0);
}
+
/*
Create a table
SYNOPSIS
mysql_create_table()
- thd Thread object
- db Database
- table_name Table name
- create_info Create information (like MAX_ROWS)
- fields List of fields to create
- keys List of keys to create
- tmp_table Set to 1 if this is an internal temporary table
- (From ALTER TABLE)
- no_log Don't log the query to binary log.
+ thd Thread object
+ db Database
+ table_name Table name
+ create_info Create information (like MAX_ROWS)
+ fields List of fields to create
+ keys List of keys to create
+ tmp_table Set to 1 if this is an internal temporary table
+ (From ALTER TABLE)
+ no_log Don't log the query to binary log.
DESCRIPTION
If one creates a temporary table, this is automaticly opened
@@ -1055,23 +1052,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
and must be zero for standard create of table.
RETURN VALUES
- 0 ok
- -1 error
+ 0 ok
+ -1 error
*/
int mysql_create_table(THD *thd,const char *db, const char *table_name,
- HA_CREATE_INFO *create_info,
- List<create_field> &fields,
- List<Key> &keys,bool tmp_table,bool no_log,
- uint select_field_count)
+ HA_CREATE_INFO *create_info,
+ List<create_field> &fields,
+ List<Key> &keys,bool tmp_table,bool no_log,
+ uint select_field_count)
{
- char path[FN_REFLEN];
- const char *alias;
- int error= -1;
- uint db_options, key_count;
- KEY *key_info_buffer;
- handler *file;
- enum db_type new_db_type;
+ char path[FN_REFLEN];
+ const char *alias;
+ int error= -1;
+ uint db_options, key_count;
+ KEY *key_info_buffer;
+ handler *file;
+ enum db_type new_db_type;
DBUG_ENTER("mysql_create_table");
/* Check for duplicate fields and check type of table to create */
@@ -1085,10 +1082,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
create_info->db_type= new_db_type;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_USING_OTHER_HANDLER,
- ER(ER_WARN_USING_OTHER_HANDLER),
- ha_get_storage_engine(new_db_type),
- table_name);
+ ER_WARN_USING_OTHER_HANDLER,
+ ER(ER_WARN_USING_OTHER_HANDLER),
+ ha_get_storage_engine(new_db_type),
+ table_name);
}
db_options=create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC)
@@ -1104,24 +1101,22 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (mysql_prepare_table(thd, create_info, fields,
- keys, tmp_table, db_options, file,
- key_info_buffer, key_count,
- select_field_count))
+ keys, tmp_table, db_options, file,
+ key_info_buffer, &key_count,
+ select_field_count))
DBUG_RETURN(-1);
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
- if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
- mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
- thd->tmp_table++, reg_ext)>= (int)sizeof(path))
- DBUG_RETURN(-1);
+ my_snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
+ mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
+ thd->tmp_table++, reg_ext);
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
}
else
- if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
- alias, reg_ext)>= (int)sizeof(path))
- DBUG_RETURN(-1);
+ my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
+ alias, reg_ext);
unpack_filename(path,path);
/* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
@@ -1129,7 +1124,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
- create_info->table_existed= 1; // Mark that table existed
+ create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0);
}
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
@@ -1144,24 +1139,24 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
- create_info->table_existed= 1; // Mark that table existed
- error= 0;
- }
+ create_info->table_existed= 1; // Mark that table existed
+ error= 0;
+ }
else
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
goto end;
}
}
thd->proc_info="creating table";
- create_info->table_existed= 0; // Mark that table is created
+ create_info->table_existed= 0; // Mark that table is created
if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
create_info->data_file_name= create_info->index_file_name= 0;
create_info->table_options=db_options;
if (rea_create_table(thd, path, create_info, fields, key_count,
- key_info_buffer))
+ key_info_buffer))
{
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
goto end;
@@ -1184,8 +1179,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- test(create_info->options &
- HA_LEX_CREATE_TMP_TABLE));
+ test(create_info->options &
+ HA_LEX_CREATE_TMP_TABLE));
mysql_bin_log.write(&qinfo);
}
}
@@ -1215,37 +1210,39 @@ static char *
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
{
char buff[MAX_FIELD_NAME],*buff_end;
- int remain;
if (!check_if_keyname_exists(field_name,start,end) &&
my_strcasecmp(system_charset_info,field_name,primary_key_name))
- return (char*) field_name; // Use fieldname
- buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4);
- /*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
+ return (char*) field_name; // Use fieldname
+ buff_end=strmake(buff,field_name, sizeof(buff)-4);
+
+ /*
+ Only 3 chars + '\0' left, so need to limit to 2 digit
+ This is ok as we can't have more than 100 keys anyway
+ */
for (uint i=2 ; i< 100; i++)
{
- remain= (int)sizeof(buff)- (buff_end- buff);
- if (snprintf(buff_end, remain, "_%d", i)>= remain)
- return NULL;
+ *buff_end= '_';
+ int10_to_str(i, buff_end+1, 10);
if (!check_if_keyname_exists(buff,start,end))
return sql_strdup(buff);
}
- /*ingo 2004-04-07 dedicated return is inevitable*/
- return NULL;
+ return (char*) "not_specified"; // Should never happen
}
+
/****************************************************************************
** Create table from a list of fields and items
****************************************************************************/
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
- const char *db, const char *name,
- List<create_field> *extra_fields,
- List<Key> *keys,
- List<Item> *items,
- MYSQL_LOCK **lock)
+ const char *db, const char *name,
+ List<create_field> *extra_fields,
+ List<Key> *keys,
+ List<Item> *items,
+ MYSQL_LOCK **lock)
{
- TABLE tmp_table; // Used during 'create_field()'
+ TABLE tmp_table; // Used during 'create_field()'
TABLE *table;
tmp_table.table_name=0;
uint select_field_count= items->elements;
@@ -1259,7 +1256,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
tmp_table.null_row=tmp_table.maybe_null=0;
tmp_table.blob_ptr_size=portable_sizeof_char_ptr;
tmp_table.db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
- create_info->db_type == DB_TYPE_HEAP);
+ create_info->db_type == DB_TYPE_HEAP);
while ((item=it++))
{
@@ -1269,18 +1266,18 @@ 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);
if (!field ||
- !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
- ((Item_field *)item)->field :
- (Field*) 0))))
+ !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
+ ((Item_field *)item)->field :
+ (Field*) 0))))
DBUG_RETURN(0);
extra_fields->push_back(cr_field);
}
/* create and lock table */
/* QQ: This should be done atomic ! */
if (mysql_create_table(thd,db,name,create_info,*extra_fields,
- *keys,0,1,select_field_count)) // no logging
+ *keys,0,1,select_field_count)) // no logging
DBUG_RETURN(0);
if (!(table=open_table(thd,db,name,name,(bool*) 0)))
{
@@ -1307,10 +1304,10 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
bool
mysql_rename_table(enum db_type base,
- const char *old_db,
- const char *old_name,
- const char *new_db,
- const char *new_name)
+ const char *old_db,
+ const char *old_name,
+ const char *new_db,
+ const char *new_name)
{
char from[FN_REFLEN], to[FN_REFLEN];
char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1];
@@ -1329,12 +1326,10 @@ mysql_rename_table(enum db_type base,
my_casedn_str(system_charset_info, tmp_to);
new_name= tmp_to;
}
- if (snprintf(from, sizeof(from), "%s/%s/%s",
- mysql_data_home, old_db, old_name)>= (int)sizeof(from))
- DBUG_RETURN(1);
- if (snprintf(to, sizeof(to), "%s/%s/%s",
- mysql_data_home, new_db, new_name)>= (int)sizeof(to))
- DBUG_RETURN(1);
+ my_snprintf(from, sizeof(from), "%s/%s/%s",
+ mysql_data_home, old_db, old_name);
+ my_snprintf(to, sizeof(to), "%s/%s/%s",
+ mysql_data_home, new_db, new_name);
fn_format(from,from,"","",4);
fn_format(to,to, "","",4);
@@ -1359,10 +1354,10 @@ mysql_rename_table(enum db_type base,
SYNOPSIS
wait_while_table_is_used()
- thd Thread handler
- table Table to remove from cache
- function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
- HA_EXTRA_FORCE_REOPEN if table is not be used
+ thd Thread handler
+ table Table to remove from cache
+ function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
+ HA_EXTRA_FORCE_REOPEN if table is not be used
NOTES
When returning, the table will be unusable for other threads until
the table is closed.
@@ -1373,7 +1368,7 @@ mysql_rename_table(enum db_type base,
*/
static void wait_while_table_is_used(THD *thd,TABLE *table,
- enum ha_extra_function function)
+ enum ha_extra_function function)
{
DBUG_PRINT("enter",("table: %s", table->real_name));
DBUG_ENTER("wait_while_table_is_used");
@@ -1381,11 +1376,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
VOID(table->file->extra(function));
/* Mark all tables that are in use as 'old' */
- mysql_lock_abort(thd, table); // end threads waiting on lock
+ mysql_lock_abort(thd, table); // end threads waiting on lock
/* Wait until all there are no other threads that has this table open */
while (remove_table_from_cache(thd,table->table_cache_key,
- table->real_name))
+ table->real_name))
{
dropping_tables++;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@@ -1399,8 +1394,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
SYNOPSIS
close_cached_table()
- thd Thread handler
- table Table to remove from cache
+ thd Thread handler
+ table Table to remove from cache
NOTES
Function ends by signaling threads waiting for the table to try to
@@ -1410,17 +1405,17 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
Lock on LOCK_open
Win32 clients must also have a WRITE LOCK on the table !
*/
-
+
static bool close_cached_table(THD *thd, TABLE *table)
{
DBUG_ENTER("close_cached_table");
-
+
wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
/* Close lock if this is not got with LOCK TABLES */
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
- thd->lock=0; // Start locked threads
+ thd->lock=0; // Start locked threads
}
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
@@ -1431,7 +1426,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
}
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
- const char* operator_name, const char* errmsg)
+ const char* operator_name, const char* errmsg)
{
Protocol *protocol= thd->protocol;
@@ -1448,15 +1443,15 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
static int prepare_for_restore(THD* thd, TABLE_LIST* table,
- HA_CHECK_OPT *check_opt)
+ HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("prepare_for_restore");
if (table->table) // do not overwrite existing tables on restore
{
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
- "table exists, will not overwrite on restore"
- ));
+ "table exists, will not overwrite on restore"
+ ));
}
else
{
@@ -1466,25 +1461,24 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
char* db = thd->db ? thd->db : table->db;
if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
- reg_ext))
+ reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
- if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
- mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path))
- DBUG_RETURN(-1);
+ my_snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
+ mysql_real_data_home, db, table_name);
if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1);
if (my_copy(src_path,
- fn_format(dst_path, dst_path,"", reg_ext, 4),
- MYF(MY_WME)))
+ fn_format(dst_path, dst_path,"", reg_ext, 4),
+ MYF(MY_WME)))
{
pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd, table);
pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
- "Failed copying .frm file"));
+ "Failed copying .frm file"));
}
if (mysql_truncate(thd, table, 1))
{
@@ -1492,7 +1486,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
unlock_table_name(thd, table);
pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
- "Failed generating table from .frm file"));
+ "Failed generating table from .frm file"));
}
}
@@ -1511,7 +1505,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
- HA_CHECK_OPT *check_opt)
+ HA_CHECK_OPT *check_opt)
{
int error= 0;
TABLE tmp_table, *table;
@@ -1520,13 +1514,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if (!(check_opt->sql_flags & TT_USEFRM))
DBUG_RETURN(0);
- if (!(table= table_list->table)) /* if open_ltable failed */
+ if (!(table= table_list->table)) /* if open_ltable failed */
{
char name[FN_REFLEN];
strxmov(name, mysql_data_home, "/", table_list->db, "/",
- table_list->real_name, NullS);
+ table_list->real_name, NullS);
if (openfrm(name, "", 0, 0, 0, &tmp_table))
- DBUG_RETURN(0); // Can't open frm file
+ DBUG_RETURN(0); // Can't open frm file
table= &tmp_table;
}
@@ -1549,18 +1543,14 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
like ISAM or MyISAM
*/
if (!ext[0] || !ext[1])
- goto end; // No data file
+ goto end; // No data file
- strxmov(from, table->path, ext[1], NullS); // Name of data file
+ strxmov(from, table->path, ext[1], NullS); // Name of data file
if (!my_stat(from, &stat_info, MYF(0)))
- goto end; // Can't use USE_FRM flag
+ goto end; // Can't use USE_FRM flag
- if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
- from, current_pid, thd->thread_id)>= (int)sizeof(tmp))
- {
- error= -1;
- goto end;
- }
+ my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
+ from, current_pid, thd->thread_id);
/* If we could open the table, close it */
if (table_list->table)
@@ -1580,7 +1570,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name(thd, table_list);
pthread_mutex_unlock(&LOCK_open);
error= send_check_errmsg(thd, table_list, "repair",
- "Failed renaming data file");
+ "Failed renaming data file");
goto end;
}
if (mysql_truncate(thd, table_list, 1))
@@ -1589,7 +1579,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name(thd, table_list);
pthread_mutex_unlock(&LOCK_open);
error= send_check_errmsg(thd, table_list, "repair",
- "Failed generating table from .frm file");
+ "Failed generating table from .frm file");
goto end;
}
if (my_rename(tmp, from, MYF(MY_WME)))
@@ -1598,7 +1588,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name(thd, table_list);
pthread_mutex_unlock(&LOCK_open);
error= send_check_errmsg(thd, table_list, "repair",
- "Failed restoring .MYD file");
+ "Failed restoring .MYD file");
goto end;
}
@@ -1615,21 +1605,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
end:
if (table == &tmp_table)
- closefrm(table); // Free allocated memory
+ closefrm(table); // Free allocated memory
DBUG_RETURN(error);
}
static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
- HA_CHECK_OPT* check_opt,
- const char *operator_name,
- thr_lock_type lock_type,
- bool open_for_modify,
- uint extra_open_options,
- int (*prepare_func)(THD *, TABLE_LIST *,
- HA_CHECK_OPT *),
- int (handler::*operator_func)
- (THD *, HA_CHECK_OPT *))
+ HA_CHECK_OPT* check_opt,
+ const char *operator_name,
+ thr_lock_type lock_type,
+ bool open_for_modify,
+ uint extra_open_options,
+ int (*prepare_func)(THD *, TABLE_LIST *,
+ HA_CHECK_OPT *),
+ int (handler::*operator_func)
+ (THD *, HA_CHECK_OPT *))
{
TABLE_LIST *table;
List<Item> field_list;
@@ -1666,9 +1656,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (prepare_func)
{
switch ((*prepare_func)(thd, table, check_opt)) {
- case 1: continue; // error, message written to net
- case -1: goto err; // error, message could be written to net
- default: ; // should be 0 otherwise
+ case 1: continue; // error, message written to net
+ case -1: goto err; // error, message could be written to net
+ default: ; // should be 0 otherwise
}
}
@@ -1680,11 +1670,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol->store(operator_name, system_charset_info);
protocol->store("error",5, system_charset_info);
if (!(err_msg=thd->net.last_error))
- err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
+ err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
protocol->store(err_msg, system_charset_info);
thd->net.last_error[0]=0;
if (protocol->write())
- goto err;
+ goto err;
continue;
}
table->table->pos_in_table_list= table;
@@ -1695,14 +1685,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol->store(table_name, system_charset_info);
protocol->store(operator_name, system_charset_info);
protocol->store("error", 5, system_charset_info);
- if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
- table_name)>= (int)sizeof(buff))
- goto err;
+ my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name);
protocol->store(buff, system_charset_info);
close_thread_tables(thd);
- table->table=0; // For query cache
+ table->table=0; // For query cache
if (protocol->write())
- goto err;
+ goto err;
continue;
}
@@ -1711,20 +1699,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
pthread_mutex_lock(&LOCK_open);
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
- "Waiting to get writelock");
+ "Waiting to get writelock");
mysql_lock_abort(thd,table->table);
while (remove_table_from_cache(thd, table->table->table_cache_key,
- table->table->real_name) &&
- ! thd->killed)
+ table->table->real_name) &&
+ ! thd->killed)
{
- dropping_tables++;
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- dropping_tables--;
+ dropping_tables++;
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ dropping_tables--;
}
thd->exit_cond(old_message);
pthread_mutex_unlock(&LOCK_open);
if (thd->killed)
- goto err;
+ goto err;
open_for_modify=0;
}
@@ -1739,11 +1727,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
switch (result_code) {
case HA_ADMIN_NOT_IMPLEMENTED:
{
- char buf[ERRMSGSIZE+20];
- uint length=my_snprintf(buf, ERRMSGSIZE,
- ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
- protocol->store("error", 5, system_charset_info);
- protocol->store(buf, length, system_charset_info);
+ char buf[ERRMSGSIZE+20];
+ uint length=my_snprintf(buf, ERRMSGSIZE,
+ ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
+ protocol->store("error", 5, system_charset_info);
+ protocol->store(buf, length, system_charset_info);
}
break;
@@ -1779,26 +1767,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol->store("Invalid argument",16, system_charset_info);
break;
- default: // Probably HA_ADMIN_INTERNAL_ERROR
+ default: // Probably HA_ADMIN_INTERNAL_ERROR
protocol->store("error", 5, system_charset_info);
protocol->store("Unknown - internal error during operation", 41
- , system_charset_info);
+ , system_charset_info);
fatal_error=1;
break;
}
if (fatal_error)
- table->table->version=0; // Force close of table
+ table->table->version=0; // Force close of table
else if (open_for_modify)
{
pthread_mutex_lock(&LOCK_open);
remove_table_from_cache(thd, table->table->table_cache_key,
- table->table->real_name);
+ table->table->real_name);
pthread_mutex_unlock(&LOCK_open);
/* May be something modified consequently we have to invalidate cache */
query_cache_invalidate3(thd, table->table, 0);
}
close_thread_tables(thd);
- table->table=0; // For query cache
+ table->table=0; // For query cache
if (protocol->write())
goto err;
}
@@ -1806,7 +1794,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
send_eof(thd);
DBUG_RETURN(0);
err:
- close_thread_tables(thd); // Shouldn't be needed
+ close_thread_tables(thd); // Shouldn't be needed
if (table)
table->table=0;
DBUG_RETURN(-1);
@@ -1817,8 +1805,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_backup_table");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
- "backup", TL_READ, 0, 0, 0,
- &handler::backup));
+ "backup", TL_READ, 0, 0, 0,
+ &handler::backup));
}
@@ -1826,9 +1814,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_restore_table");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
- "restore", TL_WRITE, 1, 0,
- &prepare_for_restore,
- &handler::restore));
+ "restore", TL_WRITE, 1, 0,
+ &prepare_for_restore,
+ &handler::restore));
}
@@ -1836,9 +1824,9 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("mysql_repair_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR,
- &prepare_for_repair,
- &handler::repair));
+ "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR,
+ &prepare_for_repair,
+ &handler::repair));
}
@@ -1846,8 +1834,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("mysql_optimize_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "optimize", TL_WRITE, 1,0,0,
- &handler::optimize));
+ "optimize", TL_WRITE, 1,0,0,
+ &handler::optimize));
}
@@ -1856,16 +1844,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
SYNOPSIS
mysql_assign_to_keycache()
- thd Thread object
- tables Table list (one table only)
+ thd Thread object
+ tables Table list (one table only)
RETURN VALUES
- 0 ok
- -1 error
+ 0 ok
+ -1 error
*/
int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
- LEX_STRING *key_cache_name)
+ LEX_STRING *key_cache_name)
{
HA_CHECK_OPT check_opt;
KEY_CACHE *key_cache;
@@ -1882,8 +1870,8 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
pthread_mutex_unlock(&LOCK_global_system_variables);
check_opt.key_cache= key_cache;
DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
- "assign_to_keycache", TL_READ_NO_INSERT, 0,
- 0, 0, &handler::assign_to_keycache));
+ "assign_to_keycache", TL_READ_NO_INSERT, 0,
+ 0, 0, &handler::assign_to_keycache));
}
@@ -1892,9 +1880,9 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
SYNOPSIS
reassign_keycache_tables()
- thd Thread object
- src_cache Reference to the key cache to clean up
- dest_cache New key cache
+ thd Thread object
+ src_cache Reference to the key cache to clean up
+ dest_cache New key cache
NOTES
This is called when one sets a key cache size to zero, in which
@@ -1909,20 +1897,20 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
to it for a while after this function returns.
RETURN VALUES
- 0 ok
+ 0 ok
*/
-int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
- KEY_CACHE *dst_cache)
+int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
+ KEY_CACHE *dst_cache)
{
DBUG_ENTER("reassign_keycache_tables");
DBUG_ASSERT(src_cache != dst_cache);
DBUG_ASSERT(src_cache->in_init);
- src_cache->param_buff_size= 0; // Free key cache
+ src_cache->param_buff_size= 0; // Free key cache
ha_resize_key_cache(src_cache);
ha_change_key_cache(src_cache, dst_cache);
- DBUG_RETURN(0);
+ DBUG_RETURN(0);
}
@@ -1931,20 +1919,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
SYNOPSIS
mysql_preload_keys()
- thd Thread object
- tables Table list (one table only)
+ thd Thread object
+ tables Table list (one table only)
RETURN VALUES
- 0 ok
- -1 error
+ 0 ok
+ -1 error
*/
int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
{
DBUG_ENTER("mysql_preload_keys");
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
- "preload_keys", TL_READ, 0, 0, 0,
- &handler::preload_keys));
+ "preload_keys", TL_READ, 0, 0, 0,
+ &handler::preload_keys));
}
@@ -1953,19 +1941,19 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
SYNOPSIS
mysql_create_like_table()
- thd Thread object
- table Table list (one table only)
+ thd Thread object
+ table Table list (one table only)
create_info Create info
table_ident Src table_ident
RETURN VALUES
- 0 ok
- -1 error
+ 0 ok
+ -1 error
*/
-int mysql_create_like_table(THD* thd, TABLE_LIST* table,
- HA_CREATE_INFO *create_info,
- Table_ident *table_ident)
+int mysql_create_like_table(THD* thd, TABLE_LIST* table,
+ HA_CREATE_INFO *create_info,
+ Table_ident *table_ident)
{
TABLE **tmp_table;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
@@ -1988,11 +1976,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
DBUG_RETURN(-1);
}
-
+
src_tables_list.db= table_ident->db.str ? table_ident->db.str : thd->db;
src_tables_list.real_name= table_ident->table.str;
src_tables_list.next= 0;
-
+
if (lock_and_wait_for_table_name(thd, &src_tables_list))
goto err;
@@ -2000,8 +1988,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
strxmov(src_path, (*tmp_table)->path, reg_ext, NullS);
else
{
- strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
- reg_ext, NullS);
+ strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
+ reg_ext, NullS);
if (access(src_path, F_OK))
{
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
@@ -2012,56 +2000,54 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
/*
Validate the destination table
- skip the destination table name checking as this is already
+ skip the destination table name checking as this is already
validated.
*/
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (find_temporary_table(thd, db, table_name))
goto table_exists;
- if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
- mysql_tmpdir, tmp_file_prefix, current_pid,
- thd->thread_id, thd->tmp_table++, reg_ext)>=
- (int)sizeof(dst_path))
- DBUG_RETURN(-1);
+ my_snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
+ mysql_tmpdir, tmp_file_prefix, current_pid,
+ thd->thread_id, thd->tmp_table++, reg_ext);
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
}
else
{
- strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
- reg_ext, NullS);
+ strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
+ reg_ext, NullS);
if (!access(dst_path, F_OK))
goto table_exists;
}
- /*
+ /*
Create a new table by copying from source table
- */
+ */
if (my_copy(src_path, dst_path, MYF(MY_WME|MY_DONT_OVERWRITE_FILE)))
goto err;
/*
- As mysql_truncate don't work on a new table at this stage of
- creation, instead create the table directly (for both normal
+ As mysql_truncate don't work on a new table at this stage of
+ creation, instead create the table directly (for both normal
and temporary tables).
*/
- *fn_ext(dst_path)= 0;
+ *fn_ext(dst_path)= 0;
err= ha_create_table(dst_path, create_info, 1);
-
+
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
{
- (void) rm_temporary_table(create_info->db_type,
- dst_path); /* purecov: inspected */
+ (void) rm_temporary_table(create_info->db_type,
+ dst_path); /* purecov: inspected */
goto err; /* purecov: inspected */
}
}
else if (err)
{
- (void) quick_rm_table(create_info->db_type, db,
- table_name); /* purecov: inspected */
- goto err; /* purecov: inspected */
+ (void) quick_rm_table(create_info->db_type, db,
+ table_name); /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
// Must be written before unlock
@@ -2070,22 +2056,21 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- test(create_info->options &
- HA_LEX_CREATE_TMP_TABLE));
+ test(create_info->options &
+ HA_LEX_CREATE_TMP_TABLE));
mysql_bin_log.write(&qinfo);
}
res= 0;
goto err;
-
+
table_exists:
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
- if (snprintf(warn_buff, sizeof(warn_buff),
- ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff))
- DBUG_RETURN(-1);
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TABLE_EXISTS_ERROR,warn_buff);
+ my_snprintf(warn_buff, sizeof(warn_buff),
+ ER(ER_TABLE_EXISTS_ERROR), table_name);
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TABLE_EXISTS_ERROR,warn_buff);
res= 0;
}
else
@@ -2109,8 +2094,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_analyze_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "analyze", lock_type, 1,0,0,
- &handler::analyze));
+ "analyze", lock_type, 1,0,0,
+ &handler::analyze));
}
@@ -2124,15 +2109,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_check_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "check", lock_type,
- 0, HA_OPEN_FOR_REPAIR, 0,
- &handler::check));
+ "check", lock_type,
+ 0, HA_OPEN_FOR_REPAIR, 0,
+ &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)
+ TABLE_LIST *table_list,
+ enum tablespace_op_type tablespace_op)
{
TABLE *table;
my_bool discard;
@@ -2150,8 +2135,8 @@ int mysql_discard_or_import_tablespace(THD *thd,
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 */
+ and ::external_lock() do not complain when we
+ lock the table */
mysql_ha_closeall(thd, table_list);
if (!(table=open_ltable(thd,table_list,TL_WRITE)))
@@ -2159,7 +2144,7 @@ int mysql_discard_or_import_tablespace(THD *thd,
thd->tablespace_op=FALSE;
DBUG_RETURN(-1);
}
-
+
error=table->file->discard_or_import_tablespace(discard);
thd->proc_info="end";
@@ -2194,6 +2179,8 @@ err:
DBUG_RETURN(error);
}
+
+#ifdef NOT_USED
/*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
the proper arguments. This isn't very fast but it should work for most
@@ -2201,38 +2188,38 @@ err:
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
*/
-int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
+int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
{
List<create_field> fields;
List<Alter_drop> drop;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
- int rc;
- uint idx;
- uint db_options;
- uint key_count;
- TABLE *table;
- Field **f_ptr;
- KEY *key_info_buffer;
- char path[FN_REFLEN];
+ int rc;
+ uint idx;
+ uint db_options;
+ uint key_count;
+ TABLE *table;
+ Field **f_ptr;
+ KEY *key_info_buffer;
+ char path[FN_REFLEN+1];
DBUG_ENTER("mysql_create_index");
/*
- Try to use online generation of index.
- This requires that all indexes can be created online.
- Otherwise, the old alter table procedure is executed.
+ Try to use online generation of index.
+ This requires that all indexes can be created online.
+ Otherwise, the old alter table procedure is executed.
- Open the table to have access to the correct table handler.
- */
+ Open the table to have access to the correct table handler.
+ */
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
/*
- The add_index method takes an array of KEY structs for the new indexes.
- Preparing a new table structure generates this array.
- It needs a list with all fields of the table, which does not need to
- be correct in every respect. The field names are important.
- */
+ The add_index method takes an array of KEY structs for the new indexes.
+ Preparing a new table structure generates this array.
+ It needs a list with all fields of the table, which does not need to
+ be correct in every respect. The field names are important.
+ */
for (f_ptr= table->field; *f_ptr; f_ptr++)
{
create_field *c_fld= new create_field(*f_ptr, *f_ptr);
@@ -2244,20 +2231,20 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info.default_table_charset= thd->variables.collation_database;
db_options= 0;
if (mysql_prepare_table(thd, &create_info, fields,
- keys, /*tmp_table*/ 0, db_options, table->file,
- key_info_buffer, key_count,
- /*select_field_count*/ 0))
+ keys, /*tmp_table*/ 0, db_options, table->file,
+ key_info_buffer, key_count,
+ /*select_field_count*/ 0))
DBUG_RETURN(-1);
/*
- Check if all keys can be generated with the add_index method.
- If anyone cannot, then take the old way.
- */
+ Check if all keys can be generated with the add_index method.
+ If anyone cannot, then take the old way.
+ */
for (idx=0; idx< key_count; idx++)
{
DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name));
if (!(table->file->index_ddl_flags(key_info_buffer+idx)&
- (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
+ (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
break ;
}
if ((idx < key_count)|| !key_count)
@@ -2269,68 +2256,68 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
/* Cleanup the fields list. We do not want to create existing fields. */
fields.delete_elements();
if (real_alter_table(thd, table_list->db, table_list->real_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_ADD_INDEX, DUP_ERROR))
- /*don't need to free((gptr) key_info_buffer);*/
+ &create_info, table_list, table,
+ fields, keys, drop, alter, 0, (ORDER*)0,
+ ALTER_ADD_INDEX, DUP_ERROR))
+ /* Don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(-1);
}
else
{
if (table->file->add_index(table, key_info_buffer, key_count)||
- (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
- table_list->db, (lower_case_table_names == 2)?
- table_list->alias: table_list->real_name, reg_ext)>=
- (int)sizeof(path))||
- ! unpack_filename(path, path)||
- mysql_create_frm(thd, path, &create_info,
- fields, key_count, key_info_buffer, table->file))
- /*don't need to free((gptr) key_info_buffer);*/
+ (my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
+ table_list->db, (lower_case_table_names == 2) ?
+ table_list->alias: table_list->real_name, reg_ext) >=
+ (int) sizeof(path)) ||
+ ! unpack_filename(path, path) ||
+ mysql_create_frm(thd, path, &create_info,
+ fields, key_count, key_info_buffer, table->file))
+ /* don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(-1);
}
-
- /*don't need to free((gptr) key_info_buffer);*/
+ /* don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(0);
}
-int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
+int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
+ List<Alter_drop> &drop)
{
List<create_field> fields;
- List<Key> keys;
+ List<Key> keys;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
- uint idx;
- uint db_options;
- uint key_count;
- uint *key_numbers;
- TABLE *table;
- Field **f_ptr;
- KEY *key_info;
- KEY *key_info_buffer;
- char path[FN_REFLEN];
+ uint idx;
+ uint db_options;
+ uint key_count;
+ uint *key_numbers;
+ TABLE *table;
+ Field **f_ptr;
+ KEY *key_info;
+ KEY *key_info_buffer;
+ char path[FN_REFLEN];
DBUG_ENTER("mysql_drop_index");
/*
- Try to use online generation of index.
- This requires that all indexes can be created online.
- Otherwise, the old alter table procedure is executed.
+ Try to use online generation of index.
+ This requires that all indexes can be created online.
+ Otherwise, the old alter table procedure is executed.
- Open the table to have access to the correct table handler.
- */
+ Open the table to have access to the correct table handler.
+ */
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
/*
- The drop_index method takes an array of key numbers.
- It cannot get more entries than keys in the table.
- */
+ The drop_index method takes an array of key numbers.
+ It cannot get more entries than keys in the table.
+ */
key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys);
key_count= 0;
/*
- Get the number of each key and check if it can be created online.
- */
+ Get the number of each key and check if it can be created online.
+ */
List_iterator<Alter_drop> drop_it(drop);
Alter_drop *drop_key;
while ((drop_key= drop_it++))
@@ -2340,7 +2327,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
for (idx=0; idx< table->keys; idx++, key_info++)
{
if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name))
- break;
+ break;
}
if (idx>= table->keys)
{
@@ -2349,12 +2336,12 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
DBUG_RETURN(-1);
}
/*
- Check if the key can be generated with the add_index method.
- If anyone cannot, then take the old way.
- */
+ Check if the key can be generated with the add_index method.
+ If anyone cannot, then take the old way.
+ */
DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name));
if (!(table->file->index_ddl_flags(table->key_info+idx)&
- (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
+ (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
break ;
key_numbers[key_count++]= idx;
}
@@ -2366,9 +2353,9 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
if ((drop_key)|| (drop.elements<= 0))
{
if (real_alter_table(thd, table_list->db, table_list->real_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_DROP_INDEX, DUP_ERROR))
+ &create_info, table_list, table,
+ fields, keys, drop, alter, 0, (ORDER*)0,
+ ALTER_DROP_INDEX, DUP_ERROR))
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN(-1);
}
@@ -2376,17 +2363,17 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
{
db_options= 0;
if (table->file->drop_index(table, key_numbers, key_count)||
- mysql_prepare_table(thd, &create_info, fields,
- keys, /*tmp_table*/ 0, db_options, table->file,
- key_info_buffer, key_count,
- /*select_field_count*/ 0)||
- (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
- table_list->db, (lower_case_table_names == 2)?
- table_list->alias: table_list->real_name, reg_ext)>=
- (int)sizeof(path))||
- ! unpack_filename(path, path)||
- mysql_create_frm(thd, path, &create_info,
- fields, key_count, key_info_buffer, table->file))
+ mysql_prepare_table(thd, &create_info, fields,
+ keys, /*tmp_table*/ 0, db_options, table->file,
+ key_info_buffer, key_count,
+ /*select_field_count*/ 0)||
+ (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
+ table_list->db, (lower_case_table_names == 2)?
+ table_list->alias: table_list->real_name, reg_ext)>=
+ (int)sizeof(path))||
+ ! unpack_filename(path, path)||
+ mysql_create_frm(thd, path, &create_info,
+ fields, key_count, key_info_buffer, table->file))
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN(-1);
}
@@ -2394,117 +2381,35 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN(0);
}
+#endif /* NOT_USED */
-int mysql_add_column(THD *thd, TABLE_LIST *table_list,
- List<create_field> &fields)
-{
- List<Alter_drop> drop;
- List<Key> keys;
- List<Alter_column> alter;
- HA_CREATE_INFO create_info;
- DBUG_ENTER("mysql_add_column");
- bzero((char*) &create_info,sizeof(create_info));
- create_info.db_type=DB_TYPE_DEFAULT;
- create_info.default_table_charset= thd->variables.collation_database;
- TABLE *table;
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
- DBUG_RETURN(-1);
-
- DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_ADD_COLUMN, DUP_ERROR));
-}
-int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
-{
- List<create_field> fields;
- List<Key> keys;
- List<Alter_column> alter;
- HA_CREATE_INFO create_info;
- DBUG_ENTER("mysql_drop_column");
- bzero((char*) &create_info,sizeof(create_info));
- create_info.db_type=DB_TYPE_DEFAULT;
- create_info.default_table_charset= thd->variables.collation_database;
- TABLE *table;
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
- DBUG_RETURN(-1);
-
- DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_DROP_COLUMN, DUP_ERROR));
-}
+/*
+ Alter table
+*/
int mysql_alter_table(THD *thd,char *new_db, char *new_name,
- HA_CREATE_INFO *create_info,
- TABLE_LIST *table_list,
- List<create_field> &fields,
- List<Key> &keys,List<Alter_drop> &drop_list,
- List<Alter_column> &alter_list,
- uint order_num, ORDER *order, int alter_flags,
- enum enum_duplicates handle_duplicates,
- enum enum_enable_or_disable keys_onoff,
- enum tablespace_op_type tablespace_op,
- bool simple_alter)
+ HA_CREATE_INFO *create_info,
+ TABLE_LIST *table_list,
+ List<create_field> &fields,
+ List<Key> &keys,List<Alter_drop> &drop_list,
+ List<Alter_column> &alter_list,
+ uint order_num, ORDER *order, uint alter_flags,
+ enum enum_duplicates handle_duplicates,
+ enum enum_enable_or_disable keys_onoff,
+ enum tablespace_op_type tablespace_op,
+ bool simple_alter)
{
- DBUG_ENTER("mysql_alter_table");
-
- mysql_ha_closeall(thd, table_list);
-
- /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
- if (tablespace_op != NO_TABLESPACE_OP)
- DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
- tablespace_op));
-
- if (alter_flags == ALTER_ADD_INDEX)
- DBUG_RETURN(mysql_create_index(thd, table_list, keys));
-
- if (alter_flags == ALTER_DROP_INDEX)
- DBUG_RETURN(mysql_drop_index(thd, table_list, drop_list));
-
- if (alter_flags == ALTER_ADD_COLUMN)
- DBUG_RETURN(mysql_add_column(thd, table_list, fields));
-
- if (alter_flags == ALTER_DROP_COLUMN)
- DBUG_RETURN(mysql_drop_column(thd, table_list, drop_list));
-
- TABLE *table;
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
- DBUG_RETURN(-1);
-
- DBUG_RETURN(real_alter_table(thd, new_db, new_name,
- create_info, table_list, table, fields,
- keys, drop_list, alter_list,
- order_num, order, alter_flags,
- handle_duplicates, keys_onoff,
- tablespace_op, simple_alter));
-}
-
-int real_alter_table(THD *thd,char *new_db, char *new_name,
- HA_CREATE_INFO *create_info,
- TABLE_LIST *table_list,
- TABLE *table,
- List<create_field> &fields,
- List<Key> &keys,List<Alter_drop> &drop_list,
- List<Alter_column> &alter_list,
- uint order_num, ORDER *order, int alter_flags,
- enum enum_duplicates handle_duplicates,
- enum enum_enable_or_disable keys_onoff,
- enum tablespace_op_type tablespace_op,
- bool simple_alter)
-{
- TABLE *new_table;
+ TABLE *table,*new_table;
int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN];
- bool use_timestamp=0;
ha_rows copied,deleted;
ulonglong next_insert_id;
uint db_create_options, used_fields;
enum db_type old_db_type,new_db_type;
- DBUG_ENTER("real_alter_table");
+ DBUG_ENTER("mysql_alter_table");
thd->proc_info="init";
table_name=table_list->real_name;
@@ -2512,11 +2417,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
db=table_list->db;
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
- {
new_db= db;
- }
used_fields=create_info->used_fields;
+ mysql_ha_closeall(thd, table_list);
+
+ /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
+ if (tablespace_op != NO_TABLESPACE_OP)
+ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
+ tablespace_op));
+ if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
+ DBUG_RETURN(-1);
+
/* Check that we are not trying to rename to an existing table */
if (new_name)
{
@@ -2526,17 +2438,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
if (lower_case_table_names != 2)
{
- my_casedn_str(system_charset_info, new_name_buff);
- new_alias= new_name; // Create lower case table name
+ my_casedn_str(system_charset_info, new_name_buff);
+ new_alias= new_name; // Create lower case table name
}
my_casedn_str(system_charset_info, new_name);
}
if (new_db == db &&
- !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
+ !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
{
/*
- Source and destination table names are equal: make later check
- easier.
+ Source and destination table names are equal: make later check
+ easier.
*/
new_alias= new_name= table_name;
}
@@ -2544,21 +2456,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
if (table->tmp_table)
{
- if (find_temporary_table(thd,new_db,new_name_buff))
- {
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
- DBUG_RETURN(-1);
- }
+ if (find_temporary_table(thd,new_db,new_name_buff))
+ {
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
+ DBUG_RETURN(-1);
+ }
}
else
{
- if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0),
- F_OK))
- {
- /* Table will be closed in do_command() */
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias);
- DBUG_RETURN(-1);
- }
+ if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0),
+ F_OK))
+ {
+ /* Table will be closed in do_command() */
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias);
+ DBUG_RETURN(-1);
+ }
}
}
}
@@ -2573,10 +2485,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
create_info->db_type= new_db_type;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_USING_OTHER_HANDLER,
- ER(ER_WARN_USING_OTHER_HANDLER),
- ha_get_storage_engine(new_db_type),
- new_name);
+ ER_WARN_USING_OTHER_HANDLER,
+ ER(ER_WARN_USING_OTHER_HANDLER),
+ ha_get_storage_engine(new_db_type),
+ new_name);
}
if (create_info->row_type == ROW_TYPE_NOT_USED)
create_info->row_type=table->row_type;
@@ -2593,15 +2505,15 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
error=0;
if (!access(new_name_buff,F_OK))
{
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
- error= -1;
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
+ error= -1;
}
else
{
- *fn_ext(new_name)=0;
- close_cached_table(thd, table);
- if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
- error= -1;
+ *fn_ext(new_name)=0;
+ close_cached_table(thd, table);
+ if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
+ error= -1;
}
VOID(pthread_mutex_unlock(&LOCK_open));
}
@@ -2610,7 +2522,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
switch (keys_onoff) {
case LEAVE_AS_IS:
- break;
+ break;
case ENABLE:
VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
@@ -2627,11 +2539,11 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
break;
}
}
- if (error==HA_ERR_WRONG_COMMAND)
+ if (error == HA_ERR_WRONG_COMMAND)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- table->table_name);
+ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
+ table->table_name);
error=0;
}
if (!error)
@@ -2639,18 +2551,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
- mysql_bin_log.write(&qinfo);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
+ mysql_bin_log.write(&qinfo);
}
send_ok(thd);
}
else
{
table->file->print_error(error, MYF(0));
- error=-1;
+ error= -1;
}
- table_list->table=0; // For query cache
+ table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0);
DBUG_RETURN(error);
}
@@ -2667,12 +2579,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
create_info->default_table_charset= table->table_charset;
- restore_record(table,default_values); // Empty record for DEFAULT
+ restore_record(table,default_values); // Empty record for DEFAULT
List_iterator<Alter_drop> drop_it(drop_list);
List_iterator<create_field> def_it(fields);
List_iterator<Alter_column> alter_it(alter_list);
- List<create_field> create_list; // Add new fields here
- List<Key> key_list; // Add new keys here
+ List<create_field> create_list; // Add new fields here
+ List<Key> key_list; // Add new keys here
create_field *def;
/*
@@ -2688,16 +2600,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while ((drop=drop_it++))
{
if (drop->type == Alter_drop::COLUMN &&
- !my_strcasecmp(system_charset_info,field->field_name, drop->name))
+ !my_strcasecmp(system_charset_info,field->field_name, drop->name))
{
- /* Reset auto_increment value if it was dropped */
- if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
- !(used_fields & HA_CREATE_USED_AUTO))
- {
- create_info->auto_increment_value=0;
- create_info->used_fields|=HA_CREATE_USED_AUTO;
- }
- break;
+ /* Reset auto_increment value if it was dropped */
+ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
+ !(used_fields & HA_CREATE_USED_AUTO))
+ {
+ create_info->auto_increment_value=0;
+ create_info->used_fields|=HA_CREATE_USED_AUTO;
+ }
+ break;
}
}
if (drop)
@@ -2710,47 +2622,43 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while ((def=def_it++))
{
if (def->change &&
- !my_strcasecmp(system_charset_info,field->field_name, def->change))
- break;
+ !my_strcasecmp(system_charset_info,field->field_name, def->change))
+ break;
}
if (def)
- { // Field is changed
+ { // Field is changed
def->field=field;
- if (def->sql_type == FIELD_TYPE_TIMESTAMP)
- use_timestamp=1;
if (!def->after)
{
- create_list.push_back(def);
- def_it.remove();
+ create_list.push_back(def);
+ def_it.remove();
}
}
else
- { // Use old field value
+ { // Use old field value
create_list.push_back(def=new create_field(field,field));
- if (def->sql_type == FIELD_TYPE_TIMESTAMP)
- use_timestamp=1;
- alter_it.rewind(); // Change default if ALTER
+ alter_it.rewind(); // Change default if ALTER
Alter_column *alter;
while ((alter=alter_it++))
{
- if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
- break;
+ if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
+ break;
}
if (alter)
{
- if (def->sql_type == FIELD_TYPE_BLOB)
- {
- my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change);
- DBUG_RETURN(-1);
- }
- def->def=alter->def; // Use new default
- alter_it.remove();
+ if (def->sql_type == FIELD_TYPE_BLOB)
+ {
+ my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change);
+ DBUG_RETURN(-1);
+ }
+ def->def=alter->def; // Use new default
+ alter_it.remove();
}
}
}
def_it.rewind();
List_iterator<create_field> find_it(create_list);
- while ((def=def_it++)) // Add new columns
+ while ((def=def_it++)) // Add new columns
{
if (def->change && ! def->field)
{
@@ -2765,17 +2673,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
create_field *find;
find_it.rewind();
- while ((find=find_it++)) // Add new columns
+ while ((find=find_it++)) // Add new columns
{
- if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
- break;
+ if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
+ break;
}
if (!find)
{
- my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name);
- DBUG_RETURN(-1);
+ my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name);
+ DBUG_RETURN(-1);
}
- find_it.after(def); // Put element after this
+ find_it.after(def); // Put element after this
}
}
if (alter_list.elements)
@@ -2807,8 +2715,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while ((drop=drop_it++))
{
if (drop->type == Alter_drop::KEY &&
- !my_strcasecmp(system_charset_info,key_name, drop->name))
- break;
+ !my_strcasecmp(system_charset_info,key_name, drop->name))
+ break;
}
if (drop)
{
@@ -2821,60 +2729,60 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
{
if (!key_part->field)
- continue; // Wrong field (from UNIREG)
+ continue; // Wrong field (from UNIREG)
const char *key_part_name=key_part->field->field_name;
create_field *cfield;
field_it.rewind();
while ((cfield=field_it++))
{
- if (cfield->change)
- {
- if (!my_strcasecmp(system_charset_info, key_part_name,
- cfield->change))
- break;
- }
- else if (!my_strcasecmp(system_charset_info,
- key_part_name, cfield->field_name))
- break;
+ if (cfield->change)
+ {
+ if (!my_strcasecmp(system_charset_info, key_part_name,
+ cfield->change))
+ break;
+ }
+ else if (!my_strcasecmp(system_charset_info,
+ key_part_name, cfield->field_name))
+ break;
}
if (!cfield)
- continue; // Field is removed
+ continue; // Field is removed
uint key_part_length=key_part->length;
- if (cfield->field) // Not new field
- { // Check if sub key
- if (cfield->field->type() != FIELD_TYPE_BLOB &&
- (cfield->field->pack_length() == key_part_length ||
- cfield->length <= key_part_length /
- key_part->field->charset()->mbmaxlen))
- key_part_length=0; // Use whole field
+ if (cfield->field) // Not new field
+ { // Check if sub key
+ if (cfield->field->type() != FIELD_TYPE_BLOB &&
+ (cfield->field->pack_length() == key_part_length ||
+ cfield->length <= key_part_length /
+ key_part->field->charset()->mbmaxlen))
+ key_part_length=0; // Use whole field
}
key_part_length /= key_part->field->charset()->mbmaxlen;
key_parts.push_back(new key_part_spec(cfield->field_name,
- key_part_length));
+ key_part_length));
}
if (key_parts.elements)
key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
- (key_info->flags & HA_NOSAME ?
- (!my_strcasecmp(system_charset_info,
- key_name, primary_key_name) ?
- Key::PRIMARY : Key::UNIQUE) :
- (key_info->flags & HA_FULLTEXT ?
- Key::FULLTEXT : Key::MULTIPLE)),
- key_name,
- key_info->algorithm,
- key_parts));
+ (key_info->flags & HA_NOSAME ?
+ (!my_strcasecmp(system_charset_info,
+ key_name, primary_key_name) ?
+ Key::PRIMARY : Key::UNIQUE) :
+ (key_info->flags & HA_FULLTEXT ?
+ Key::FULLTEXT : Key::MULTIPLE)),
+ key_name,
+ key_info->algorithm,
+ key_parts));
}
{
Key *key;
- while ((key=key_it++)) // Add new keys
+ while ((key=key_it++)) // Add new keys
{
if (key->type != Key::FOREIGN_KEY)
- key_list.push_back(key);
+ key_list.push_back(key);
if (key->name &&
- !my_strcasecmp(system_charset_info,key->name,primary_key_name))
+ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
{
- my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
- DBUG_RETURN(-1);
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
+ DBUG_RETURN(-1);
}
}
}
@@ -2891,9 +2799,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
- if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
- current_pid, thd->thread_id)>= (int)sizeof(tmp_name))
- goto err;
+ my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
+ current_pid, thd->thread_id);
create_info->db_type=new_db_type;
if (!create_info->comment)
create_info->comment=table->comment;
@@ -2909,7 +2816,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if (create_info->table_options &
(HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
- HA_OPTION_NO_DELAY_KEY_WRITE);
+ HA_OPTION_NO_DELAY_KEY_WRITE);
create_info->table_options|= db_create_options;
if (table->tmp_table)
@@ -2940,31 +2847,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
Remove old table and symlinks.
*/
- if (!strcmp(db, new_db)) // Ignore symlink if db changed
+ if (!strcmp(db, new_db)) // Ignore symlink if db changed
{
if (create_info->index_file_name)
{
/* Fix index_file_name to have 'tmp_name' as basename */
strmov(index_file, tmp_name);
create_info->index_file_name=fn_same(index_file,
- create_info->index_file_name,
- 1);
+ create_info->index_file_name,
+ 1);
}
if (create_info->data_file_name)
{
/* Fix data_file_name to have 'tmp_name' as basename */
strmov(data_file, tmp_name);
create_info->data_file_name=fn_same(data_file,
- create_info->data_file_name,
- 1);
+ create_info->data_file_name,
+ 1);
}
}
else
create_info->data_file_name=create_info->index_file_name=0;
if ((error=mysql_create_table(thd, new_db, tmp_name,
- create_info,
- create_list,key_list,1,1,0))) // no logging
+ create_info,
+ create_list,key_list,1,1,0))) // no logging
DBUG_RETURN(error);
if (table->tmp_table)
@@ -2972,9 +2879,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{
char path[FN_REFLEN];
- if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
- new_db, tmp_name)>= (int)sizeof(path))
- goto err;
+ my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
+ new_db, tmp_name);
fn_format(path,path,"","",4);
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
}
@@ -2984,24 +2890,24 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
-
- /*
- We don't want update TIMESTAMP fields during ALTER TABLE
+
+ /*
+ 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.
*/
new_table->timestamp_default_now= 0;
new_table->next_number_field=new_table->found_next_number_field;
- thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
+ thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
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
copied=deleted=0;
if (!new_table->is_view)
error=copy_data_between_tables(table,new_table,create_list,
- handle_duplicates,
- order_num, order, &copied, &deleted);
- thd->last_insert_id=next_insert_id; // Needed for correct log
+ handle_duplicates,
+ order_num, order, &copied, &deleted);
+ thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
if (table->tmp_table)
@@ -3010,8 +2916,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if (error)
{
/*
- The following function call will free the new_table pointer,
- in close_temporary_table(), so we can safely directly jump to err
+ The following function call will free the new_table pointer,
+ in close_temporary_table(), so we can safely directly jump to err
*/
close_temporary_table(thd,new_db,tmp_name);
goto err;
@@ -3025,7 +2931,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
/* Remove link to old table and rename the new one */
close_temporary_table(thd,table->table_cache_key,table_name);
if (rename_temporary_table(thd, new_table, new_db, new_alias))
- { // Fatal error
+ { // Fatal error
close_temporary_table(thd,new_db,tmp_name);
my_free((gptr) new_table,MYF(0));
goto err;
@@ -3040,7 +2946,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
goto end_temporary;
}
- intern_close_table(new_table); /* close temporary table */
+ intern_close_table(new_table); /* close temporary table */
my_free((gptr) new_table,MYF(0));
VOID(pthread_mutex_lock(&LOCK_open));
if (error)
@@ -3057,9 +2963,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/
thd->proc_info="rename result table";
- if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
- current_pid, thd->thread_id)>= (int)sizeof(old_name))
- goto err;
+ my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
+ current_pid, thd->thread_id);
if (new_name != table_name || new_db != db)
{
if (!access(new_name_buff,F_OK))
@@ -3080,18 +2985,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
Win32 and InnoDB can't drop a table that is in use, so we must
close the original table at before doing the rename
*/
- table_name=thd->strdup(table_name); // must be saved
+ table_name=thd->strdup(table_name); // must be saved
if (close_cached_table(thd, table))
- { // Aborted
+ { // Aborted
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
- table=0; // Marker that table is closed
+ table=0; // Marker that table is closed
}
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
else
- table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
+ table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
#endif
@@ -3102,8 +3007,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
}
else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
- new_alias))
- { // Try to get everything back
+ new_alias))
+ { // Try to get everything back
error=1;
VOID(quick_rm_table(new_db_type,new_db,new_alias));
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
@@ -3120,7 +3025,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
- if (thd->lock || new_name != table_name) // True if WIN32
+ if (thd->lock || new_name != table_name) // True if WIN32
{
/*
Not table locking or alter table with rename
@@ -3141,14 +3046,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old
- mysql_lock_abort(thd,table); // end threads waiting on lock
+ mysql_lock_abort(thd,table); // end threads waiting on lock
}
VOID(quick_rm_table(old_db_type,db,old_name));
if (close_data_tables(thd,db,table_name) ||
- reopen_tables(thd,1,0))
- { // This shouldn't happen
+ reopen_tables(thd,1,0))
+ { // This shouldn't happen
if (table)
- close_cached_table(thd,table); // Remove lock for table
+ close_cached_table(thd,table); // Remove lock for table
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
@@ -3182,9 +3087,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
*/
char path[FN_REFLEN];
- if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
- new_db, table_name)>= (int)sizeof(path))
- goto err;
+ my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
+ new_db, table_name);
fn_format(path,path,"","",4);
table=open_temporary_table(thd, path, new_db, tmp_name,0);
if (table)
@@ -3194,18 +3098,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
else
sql_print_error("Warning: Could not open BDB table %s.%s after rename\n",
- new_db,table_name);
+ new_db,table_name);
(void) berkeley_flush_logs();
}
#endif
- table_list->table=0; // For query cache
+ table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0);
end_temporary:
- if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
- (ulong) (copied + deleted), (ulong) deleted,
- (ulong) thd->cuted_fields)>= (int)sizeof(tmp_name))
- goto err;
+ my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
+ (ulong) (copied + deleted), (ulong) deleted,
+ (ulong) thd->cuted_fields);
send_ok(thd,copied+deleted,0L,tmp_name);
thd->some_tables_deleted=0;
DBUG_RETURN(0);
@@ -3217,11 +3120,11 @@ end_temporary:
static int
copy_data_between_tables(TABLE *from,TABLE *to,
- List<create_field> &create,
- enum enum_duplicates handle_duplicates,
- uint order_num, ORDER *order,
- ha_rows *copied,
- ha_rows *deleted)
+ List<create_field> &create,
+ enum enum_duplicates handle_duplicates,
+ uint order_num, ORDER *order,
+ ha_rows *copied,
+ ha_rows *deleted)
{
int error;
Copy_field *copy,*copy_end;
@@ -3238,7 +3141,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
DBUG_ENTER("copy_data_between_tables");
if (!(copy= new Copy_field[to->fields]))
- DBUG_RETURN(-1); /* purecov: inspected */
+ DBUG_RETURN(-1); /* purecov: inspected */
to->file->external_lock(thd,F_WRLCK);
from->file->info(HA_STATUS_VARIABLE);
@@ -3259,21 +3162,21 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (order)
{
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));
tables.table = from;
tables.alias = tables.real_name= from->real_name;
- tables.db = from->table_cache_key;
+ tables.db = from->table_cache_key;
error=1;
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
- setup_order(thd, thd->lex->select_lex.ref_pointer_array,
- &tables, fields, all_fields, order) ||
- !(sortorder=make_unireg_sortorder(order, &length)) ||
- (from->sort.found_records = filesort(thd, from, sortorder, length,
- (SQL_SELECT *) 0, HA_POS_ERROR,
- &examined_rows))
- == HA_POS_ERROR)
+ setup_order(thd, thd->lex->select_lex.ref_pointer_array,
+ &tables, fields, all_fields, order) ||
+ !(sortorder=make_unireg_sortorder(order, &length)) ||
+ (from->sort.found_records = filesort(thd, from, sortorder, length,
+ (SQL_SELECT *) 0, HA_POS_ERROR,
+ &examined_rows))
+ == HA_POS_ERROR)
goto err;
};
@@ -3310,12 +3213,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if ((error=to->file->write_row((byte*) to->record[0])))
{
if ((handle_duplicates != DUP_IGNORE &&
- handle_duplicates != DUP_REPLACE) ||
- (error != HA_ERR_FOUND_DUPP_KEY &&
- error != HA_ERR_FOUND_DUPP_UNIQUE))
+ handle_duplicates != DUP_REPLACE) ||
+ (error != HA_ERR_FOUND_DUPP_KEY &&
+ error != HA_ERR_FOUND_DUPP_UNIQUE))
{
- to->file->print_error(error,MYF(0));
- break;
+ to->file->print_error(error,MYF(0));
+ break;
}
delete_count++;
}
@@ -3324,7 +3227,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
end_read_record(&info);
free_io_cache(from);
- delete [] copy; // This is never 0
+ delete [] copy; // This is never 0
if (to->file->end_bulk_insert() && !error)
{
@@ -3375,7 +3278,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
strxmov(table_name, table->db ,".", table->real_name, NullS);
t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT);
- thd->clear_error(); // these errors shouldn't get client
+ thd->clear_error(); // these errors shouldn't get client
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
@@ -3391,54 +3294,54 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
t->pos_in_table_list= table;
if (t->file->table_flags() & HA_HAS_CHECKSUM &&
- !(check_opt->flags & T_EXTEND))
- protocol->store((ulonglong)t->file->checksum());
+ !(check_opt->flags & T_EXTEND))
+ protocol->store((ulonglong)t->file->checksum());
else if (!(t->file->table_flags() & HA_HAS_CHECKSUM) &&
- (check_opt->flags & T_QUICK))
- protocol->store_null();
+ (check_opt->flags & T_QUICK))
+ protocol->store_null();
else
{
- /* calculating table's checksum */
- ha_checksum crc= 0;
-
- /* InnoDB must be told explicitly to retrieve all columns, because
- this function does not set field->query_id in the columns to the
- current query id */
- t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
-
- if (t->file->rnd_init(1))
- protocol->store_null();
- else
- {
- while (!t->file->rnd_next(t->record[0]))
- {
- ha_checksum row_crc= 0;
- if (t->record[0] != (byte*) t->field[0]->ptr)
- row_crc= my_checksum(row_crc, t->record[0],
- ((byte*) t->field[0]->ptr) - t->record[0]);
-
- for (uint i= 0; i < t->fields; i++ )
- {
- Field *f= t->field[i];
- if (f->type() == FIELD_TYPE_BLOB)
- {
- String tmp;
- f->val_str(&tmp);
- row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length());
- }
- else
- row_crc= my_checksum(row_crc, (byte*) f->ptr,
- f->pack_length());
- }
-
- crc+= row_crc;
- }
- protocol->store((ulonglong)crc);
- }
+ /* calculating table's checksum */
+ ha_checksum crc= 0;
+
+ /* InnoDB must be told explicitly to retrieve all columns, because
+ this function does not set field->query_id in the columns to the
+ current query id */
+ t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
+
+ if (t->file->rnd_init(1))
+ protocol->store_null();
+ else
+ {
+ while (!t->file->rnd_next(t->record[0]))
+ {
+ ha_checksum row_crc= 0;
+ if (t->record[0] != (byte*) t->field[0]->ptr)
+ row_crc= my_checksum(row_crc, t->record[0],
+ ((byte*) t->field[0]->ptr) - t->record[0]);
+
+ for (uint i= 0; i < t->fields; i++ )
+ {
+ Field *f= t->field[i];
+ if (f->type() == FIELD_TYPE_BLOB)
+ {
+ String tmp;
+ f->val_str(&tmp);
+ row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length());
+ }
+ else
+ row_crc= my_checksum(row_crc, (byte*) f->ptr,
+ f->pack_length());
+ }
+
+ crc+= row_crc;
+ }
+ protocol->store((ulonglong)crc);
+ }
}
thd->clear_error();
close_thread_tables(thd);
- table->table=0; // For query cache
+ table->table=0; // For query cache
}
if (protocol->write())
goto err;
@@ -3448,7 +3351,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
DBUG_RETURN(0);
err:
- close_thread_tables(thd); // Shouldn't be needed
+ close_thread_tables(thd); // Shouldn't be needed
if (table)
table->table=0;
DBUG_RETURN(-1);
diff --git a/sql/table.cc b/sql/table.cc
index f137abf2ef7..1b7d30560ef 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -553,7 +553,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
if (field->type() == FIELD_TYPE_BLOB ||
- field->type() == FIELD_TYPE_GEOMETRY ||
field->real_type() == FIELD_TYPE_VAR_STRING)
{
if (field->type() == FIELD_TYPE_BLOB)
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 4af1c832b57..8d3e304b5da 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -46,12 +46,29 @@ static bool make_empty_rec(int file, enum db_type table_type,
List<create_field> &create_fields,
uint reclength,uint null_fields);
+/*
+ Create a frm (table definition) file
+
+ SYNOPSIS
+ mysql_create_frm()
+ thd Thread handler
+ file_name Name of file (including database and .frm)
+ create_info create info parameters
+ create_fields Fields to create
+ keys number of keys to create
+ key_info Keys to create
+ db_file Handler to use. May be zero, in which case we use
+ create_info->db_type
+ RETURN
+ 0 ok
+ 1 error
+*/
-int mysql_create_frm(THD *thd, my_string file_name,
- HA_CREATE_INFO *create_info,
- List<create_field> &create_fields,
- uint keys, KEY *key_info,
- handler *db_file)
+bool mysql_create_frm(THD *thd, my_string file_name,
+ HA_CREATE_INFO *create_info,
+ List<create_field> &create_fields,
+ uint keys, KEY *key_info,
+ handler *db_file)
{
uint reclength,info_length,screens,key_info_length,maxlength,null_fields;
File file;
@@ -166,9 +183,29 @@ err:
err2:
VOID(my_close(file,MYF(MY_WME)));
err3:
+ my_delete(file_name,MYF(0));
DBUG_RETURN(1);
} /* mysql_create_frm */
+
+/*
+ Create a frm (table definition) file and the tables
+
+ SYNOPSIS
+ mysql_create_frm()
+ thd Thread handler
+ file_name Name of file (including database and .frm)
+ create_info create info parameters
+ create_fields Fields to create
+ keys number of keys to create
+ key_info Keys to create
+ db_file Handler to use. May be zero, in which case we use
+ create_info->db_type
+ RETURN
+ 0 ok
+ 1 error
+*/
+
int rea_create_table(THD *thd, my_string file_name,
HA_CREATE_INFO *create_info,
List<create_field> &create_fields,
@@ -179,12 +216,8 @@ int rea_create_table(THD *thd, my_string file_name,
if (mysql_create_frm(thd, file_name, create_info,
create_fields, keys, key_info, NULL) ||
ha_create_table(file_name,create_info,0))
- goto err;
+ DBUG_RETURN(1);
DBUG_RETURN(0);
-
-err:
- my_delete(file_name,MYF(0));
- DBUG_RETURN(1);
} /* rea_create_table */