summaryrefslogtreecommitdiff
path: root/sql/unireg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/unireg.cc')
-rw-r--r--sql/unireg.cc364
1 files changed, 239 insertions, 125 deletions
diff --git a/sql/unireg.cc b/sql/unireg.cc
index f20d3e8cc6b..7b770ab733e 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -23,29 +23,58 @@
str is a (long) to record position where 0 is the first position.
*/
-#define USES_TYPES
#include "mysql_priv.h"
#include <m_ctype.h>
#include <assert.h>
#define FCOMP 17 /* Bytes for a packed field */
-static uchar * pack_screens(List<create_field> &create_fields,
+static uchar * pack_screens(List<Create_field> &create_fields,
uint *info_length, uint *screens, bool small_file);
static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info,
ulong data_offset);
-static bool pack_header(uchar *forminfo,enum db_type table_type,
- List<create_field> &create_fields,
+static bool pack_header(uchar *forminfo,enum legacy_db_type table_type,
+ List<Create_field> &create_fields,
uint info_length, uint screens, uint table_options,
ulong data_offset, handler *file);
-static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
- create_field *last_field);
-static bool pack_fields(File file, List<create_field> &create_fields,
+static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
+ Create_field *last_field);
+static bool pack_fields(File file, List<Create_field> &create_fields,
ulong data_offset);
-static bool make_empty_rec(THD *thd, int file, enum db_type table_type,
+static bool make_empty_rec(THD *thd, int file, enum legacy_db_type table_type,
uint table_options,
- List<create_field> &create_fields,
- uint reclength, ulong data_offset);
+ List<Create_field> &create_fields,
+ uint reclength, ulong data_offset,
+ handler *handler);
+
+/**
+ An interceptor to hijack ER_TOO_MANY_FIELDS error from
+ pack_screens and retry again without UNIREG screens.
+
+ XXX: what is a UNIREG screen?
+*/
+
+struct Pack_header_error_handler: public Internal_error_handler
+{
+ virtual bool handle_error(uint sql_errno,
+ const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+ bool is_handled;
+ Pack_header_error_handler() :is_handled(FALSE) {}
+};
+
+
+bool
+Pack_header_error_handler::
+handle_error(uint sql_errno,
+ const char * /* message */,
+ MYSQL_ERROR::enum_warning_level /* level */,
+ THD * /* thd */)
+{
+ is_handled= (sql_errno == ER_TOO_MANY_FIELDS);
+ return is_handled;
+}
/*
Create a frm (table definition) file
@@ -53,7 +82,7 @@ static bool make_empty_rec(THD *thd, int file, enum db_type table_type,
SYNOPSIS
mysql_create_frm()
thd Thread handler
- file_name Name of file (including database and .frm)
+ file_name Path for file (including database and .frm)
db Name of database
table Name of table
create_info create info parameters
@@ -61,21 +90,21 @@ static bool make_empty_rec(THD *thd, int file, enum db_type table_type,
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
+ create_info->db_type
RETURN
0 ok
1 error
*/
-bool mysql_create_frm(THD *thd, my_string file_name,
+bool mysql_create_frm(THD *thd, const char *file_name,
const char *db, const char *table,
HA_CREATE_INFO *create_info,
- List<create_field> &create_fields,
+ List<Create_field> &create_fields,
uint keys, KEY *key_info,
handler *db_file)
{
LEX_STRING str_db_type;
- uint reclength, info_length, screens, key_info_length, maxlength, tmp_len;
+ uint reclength, info_length, screens, key_info_length, maxlength, tmp_len, i;
ulong key_buff_length;
File file;
ulong filepos, data_offset;
@@ -83,50 +112,83 @@ bool mysql_create_frm(THD *thd, my_string file_name,
TYPELIB formnames;
uchar *screen_buff;
char buff[128];
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ partition_info *part_info= thd->work_part_info;
+#endif
+ Pack_header_error_handler pack_header_error_handler;
+ int error;
DBUG_ENTER("mysql_create_frm");
+ DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
formnames.type_names=0;
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0)))
DBUG_RETURN(1);
- if (db_file == NULL)
- db_file= get_new_handler((TABLE*) 0, thd->mem_root, create_info->db_type);
+ DBUG_ASSERT(db_file != NULL);
/* If fixed row records, we need one bit to check for deleted rows */
if (!(create_info->table_options & HA_OPTION_PACK_RECORD))
create_info->null_bits++;
data_offset= (create_info->null_bits + 7) / 8;
- if (pack_header(forminfo, create_info->db_type,create_fields,info_length,
- screens, create_info->table_options,
- data_offset, db_file))
+ thd->push_internal_handler(&pack_header_error_handler);
+
+ error= pack_header(forminfo, ha_legacy_type(create_info->db_type),
+ create_fields,info_length,
+ screens, create_info->table_options,
+ data_offset, db_file);
+
+ thd->pop_internal_handler();
+
+ if (error)
{
- my_free((gptr) screen_buff,MYF(0));
- if (thd->net.last_errno != ER_TOO_MANY_FIELDS)
+ my_free(screen_buff, MYF(0));
+ if (! pack_header_error_handler.is_handled)
DBUG_RETURN(1);
// Try again without UNIREG screens (to get more columns)
- thd->net.last_error[0]=0;
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
DBUG_RETURN(1);
- if (pack_header(forminfo, create_info->db_type, create_fields,info_length,
+ if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
+ create_fields,info_length,
screens, create_info->table_options, data_offset, db_file))
{
- my_free((gptr) screen_buff,MYF(0));
+ my_free(screen_buff, MYF(0));
DBUG_RETURN(1);
}
}
reclength=uint2korr(forminfo+266);
/* Calculate extra data segment length */
- str_db_type.str= (char *) ha_get_storage_engine(create_info->db_type);
+ str_db_type.str= (char *) ha_resolve_storage_engine_name(create_info->db_type);
str_db_type.length= strlen(str_db_type.str);
+ /* str_db_type */
create_info->extra_size= (2 + str_db_type.length +
2 + create_info->connect_string.length);
+ /*
+ Partition:
+ Length of partition info = 4 byte
+ Potential NULL byte at end of partition info string = 1 byte
+ Indicator if auto-partitioned table = 1 byte
+ => Total 6 byte
+ */
+ create_info->extra_size+= 6;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (part_info)
+ {
+ create_info->extra_size+= part_info->part_info_len;
+ }
+#endif
+
+ for (i= 0; i < keys; i++)
+ {
+ if (key_info[i].parser_name)
+ create_info->extra_size+= key_info[i].parser_name->length + 1;
+ }
if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
create_info, keys)) < 0)
{
- my_free((gptr) screen_buff,MYF(0));
+ my_free(screen_buff, MYF(0));
DBUG_RETURN(1);
}
@@ -183,32 +245,70 @@ bool mysql_create_frm(THD *thd, my_string file_name,
strmake((char*) forminfo+47, create_info->comment.str ?
create_info->comment.str : "", create_info->comment.length);
forminfo[46]=(uchar) create_info->comment.length;
- if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
- my_pwrite(file,(byte*) keybuff,key_info_length,
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (part_info)
+ {
+ fileinfo[61]= (uchar) ha_legacy_type(part_info->default_engine_type);
+ DBUG_PRINT("info", ("part_db_type = %d", fileinfo[61]));
+ }
+#endif
+ int2store(fileinfo+59,db_file->extra_rec_buf_length());
+
+ if (my_pwrite(file, fileinfo, 64, 0L, MYF_RW) ||
+ my_pwrite(file, keybuff, key_info_length,
(ulong) uint2korr(fileinfo+6),MYF_RW))
goto err;
VOID(my_seek(file,
(ulong) uint2korr(fileinfo+6)+ (ulong) key_buff_length,
MY_SEEK_SET,MYF(0)));
- if (make_empty_rec(thd,file,create_info->db_type,create_info->table_options,
- create_fields,reclength, data_offset))
+ if (make_empty_rec(thd,file,ha_legacy_type(create_info->db_type),
+ create_info->table_options,
+ create_fields,reclength, data_offset, db_file))
goto err;
int2store(buff, create_info->connect_string.length);
- if (my_write(file, (const byte*)buff, 2, MYF(MY_NABP)) ||
- my_write(file, (const byte*)create_info->connect_string.str,
+ if (my_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) ||
+ my_write(file, (const uchar*)create_info->connect_string.str,
create_info->connect_string.length, MYF(MY_NABP)))
goto err;
int2store(buff, str_db_type.length);
- if (my_write(file, (const byte*)buff, 2, MYF(MY_NABP)) ||
- my_write(file, (const byte*)str_db_type.str,
+ if (my_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) ||
+ my_write(file, (const uchar*)str_db_type.str,
str_db_type.length, MYF(MY_NABP)))
goto err;
-
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (part_info)
+ {
+ char auto_partitioned= part_info->is_auto_partitioned ? 1 : 0;
+ int4store(buff, part_info->part_info_len);
+ if (my_write(file, (const uchar*)buff, 4, MYF_RW) ||
+ my_write(file, (const uchar*)part_info->part_info_string,
+ part_info->part_info_len + 1, MYF_RW) ||
+ my_write(file, (const uchar*)&auto_partitioned, 1, MYF_RW))
+ goto err;
+ }
+ else
+#endif
+ {
+ bzero((uchar*) buff, 6);
+ if (my_write(file, (uchar*) buff, 6, MYF_RW))
+ goto err;
+ }
+ for (i= 0; i < keys; i++)
+ {
+ if (key_info[i].parser_name)
+ {
+ if (my_write(file, (const uchar*)key_info[i].parser_name->str,
+ key_info[i].parser_name->length + 1, MYF(MY_NABP)))
+ goto err;
+ }
+ }
+
VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
- if (my_write(file,(byte*) forminfo,288,MYF_RW) ||
- my_write(file,(byte*) screen_buff,info_length,MYF_RW) ||
+ if (my_write(file, forminfo, 288, MYF_RW) ||
+ my_write(file, screen_buff, info_length, MYF_RW) ||
pack_fields(file, create_fields, data_offset))
goto err;
@@ -221,7 +321,7 @@ bool mysql_create_frm(THD *thd, my_string file_name,
goto err;
uint read_length=uint2korr(forminfo)-256;
VOID(my_seek(file,filepos+256,MY_SEEK_SET,MYF(0)));
- if (read_string(file,(gptr*) &disk_buff,read_length))
+ if (read_string(file,(uchar**) &disk_buff,read_length))
goto err;
crypted->encode(disk_buff,read_length);
delete crypted;
@@ -234,12 +334,14 @@ bool mysql_create_frm(THD *thd, my_string file_name,
}
#endif
- my_free((gptr) screen_buff,MYF(0));
- my_free((gptr) keybuff, MYF(0));
+ my_free(screen_buff,MYF(0));
+ my_free(keybuff, MYF(0));
if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
- my_sync(file, MYF(MY_WME)))
- goto err2;
+ (my_sync(file, MYF(MY_WME)) ||
+ my_sync_dir_by_file(file_name, MYF(MY_WME))))
+ goto err2;
+
if (my_close(file,MYF(MY_WME)))
goto err3;
@@ -248,8 +350,8 @@ bool mysql_create_frm(THD *thd, my_string file_name,
Restore all UCS2 intervals.
HEX representation of them is not needed anymore.
*/
- List_iterator<create_field> it(create_fields);
- create_field *field;
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
while ((field=it++))
{
if (field->save_interval)
@@ -262,8 +364,8 @@ bool mysql_create_frm(THD *thd, my_string file_name,
DBUG_RETURN(0);
err:
- my_free((gptr) screen_buff,MYF(0));
- my_free((gptr) keybuff, MYF(0));
+ my_free(screen_buff, MYF(0));
+ my_free(keybuff, MYF(0));
err2:
VOID(my_close(file,MYF(MY_WME)));
err3:
@@ -278,54 +380,65 @@ err3:
SYNOPSIS
rea_create_table()
thd Thread handler
- file_name Name of file (including database and .frm)
- db Name of database
- table Name of table
+ path Name of file (including database, without .frm)
+ db Data base name
+ table_name Table name
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
+ file Handler to use
+
RETURN
0 ok
1 error
*/
-int rea_create_table(THD *thd, my_string file_name,
- const char *db, const char *table,
- HA_CREATE_INFO *create_info,
- List<create_field> &create_fields,
- uint keys, KEY *key_info)
+int rea_create_table(THD *thd, const char *path,
+ const char *db, const char *table_name,
+ HA_CREATE_INFO *create_info,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info, handler *file)
{
DBUG_ENTER("rea_create_table");
- if (mysql_create_frm(thd, file_name, db, table, create_info,
- create_fields, keys, key_info, NULL))
+ char frm_name[FN_REFLEN];
+ strxmov(frm_name, path, reg_ext, NullS);
+ if (mysql_create_frm(thd, frm_name, db, table_name, create_info,
+ create_fields, keys, key_info, file))
+
DBUG_RETURN(1);
+
+ // Make sure mysql_create_frm din't remove extension
+ DBUG_ASSERT(*fn_rext(frm_name));
if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES;
- if (!create_info->frm_only && ha_create_table(file_name,create_info,0))
- {
- my_delete(file_name,MYF(0));
- DBUG_RETURN(1);
- }
+ if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
+ goto err_handler;
+ if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
+ create_info,0))
+ goto err_handler;
DBUG_RETURN(0);
+
+err_handler:
+ VOID(file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info));
+ my_delete(frm_name, MYF(0));
+ DBUG_RETURN(1);
} /* rea_create_table */
/* Pack screens to a screen for save in a form-file */
-static uchar * pack_screens(List<create_field> &create_fields,
- uint *info_length, uint *screens,
- bool small_file)
+static uchar *pack_screens(List<Create_field> &create_fields,
+ uint *info_length, uint *screens,
+ bool small_file)
{
reg1 uint i;
uint row,start_row,end_row,fields_on_screen;
uint length,cols;
uchar *info,*pos,*start_screen;
uint fields=create_fields.elements;
- List_iterator<create_field> it(create_fields);
+ List_iterator<Create_field> it(create_fields);
DBUG_ENTER("pack_screens");
start_row=4; end_row=22; cols=80; fields_on_screen=end_row+1-start_row;
@@ -333,7 +446,7 @@ static uchar * pack_screens(List<create_field> &create_fields,
*screens=(fields-1)/fields_on_screen+1;
length= (*screens) * (SC_INFO_LENGTH+ (cols>> 1)+4);
- create_field *field;
+ Create_field *field;
while ((field=it++))
length+=(uint) strlen(field->field_name)+1+TE_INFO_LENGTH+cols/2;
@@ -346,7 +459,7 @@ static uchar * pack_screens(List<create_field> &create_fields,
it.rewind();
for (i=0 ; i < fields ; i++)
{
- create_field *cfield=it++;
+ Create_field *cfield=it++;
if (row++ == end_row)
{
if (i)
@@ -362,7 +475,7 @@ static uchar * pack_screens(List<create_field> &create_fields,
pos[0]= (uchar) start_row-2; /* Header string */
pos[1]= (uchar) (cols >> 2);
pos[2]= (uchar) (cols >> 1) +1;
- strfill((my_string) pos+3,(uint) (cols >> 1),' ');
+ strfill((char *) pos+3,(uint) (cols >> 1),' ');
pos+=(cols >> 1)+4;
}
length=(uint) strlen(cfield->field_name);
@@ -409,7 +522,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
int2store(pos+2,key->key_length);
pos[4]= (uchar) key->key_parts;
pos[5]= (uchar) key->algorithm;
- pos[6]=pos[7]=0; // For the future
+ int2store(pos+6, key->block_size);
pos+=8;
key_parts+=key->key_parts;
DBUG_PRINT("loop", ("flags: %lu key_parts: %d at 0x%lx",
@@ -465,8 +578,8 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
/* Make formheader */
-static bool pack_header(uchar *forminfo, enum db_type table_type,
- List<create_field> &create_fields,
+static bool pack_header(uchar *forminfo, enum legacy_db_type table_type,
+ List<Create_field> &create_fields,
uint info_length, uint screens, uint table_options,
ulong data_offset, handler *file)
{
@@ -489,8 +602,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
/* Check fields */
- List_iterator<create_field> it(create_fields);
- create_field *field;
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
while ((field=it++))
{
uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
@@ -527,7 +640,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE
as auto-update field.
*/
- if (field->sql_type == FIELD_TYPE_TIMESTAMP &&
+ if (field->sql_type == MYSQL_TYPE_TIMESTAMP &&
MTYP_TYPENR(field->unireg_check) != Field::NONE &&
!time_stamp_pos)
time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1;
@@ -571,7 +684,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
length= field->save_interval->type_lengths[pos];
hex_length= length * 2;
field->interval->type_lengths[pos]= hex_length;
- field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1);
+ field->interval->type_names[pos]= dst= (char*) sql_alloc(hex_length +
+ 1);
octet2hex(dst, src, length);
}
}
@@ -631,11 +745,11 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
/* get each unique interval each own id */
-static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
- create_field *last_field)
+static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
+ Create_field *last_field)
{
- List_iterator<create_field> it(create_fields);
- create_field *field;
+ List_iterator<Create_field> it(create_fields);
+ Create_field *field;
TYPELIB *interval=last_field->interval;
while ((field=it++) != last_field)
@@ -659,18 +773,18 @@ static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
/* Save fields, fieldnames and intervals */
-static bool pack_fields(File file, List<create_field> &create_fields,
+static bool pack_fields(File file, List<Create_field> &create_fields,
ulong data_offset)
{
reg2 uint i;
uint int_count, comment_length=0;
uchar buff[MAX_FIELD_WIDTH];
- create_field *field;
+ Create_field *field;
DBUG_ENTER("pack_fields");
/* Write field info */
- List_iterator<create_field> it(create_fields);
+ List_iterator<Create_field> it(create_fields);
int_count=0;
while ((field=it++))
@@ -687,7 +801,7 @@ static bool pack_fields(File file, List<create_field> &create_fields,
int2store(buff+10,field->unireg_check);
buff[12]= (uchar) field->interval_id;
buff[13]= (uchar) field->sql_type;
- if (field->sql_type == FIELD_TYPE_GEOMETRY)
+ if (field->sql_type == MYSQL_TYPE_GEOMETRY)
{
buff[14]= (uchar) field->geom_type;
#ifndef HAVE_SPATIAL
@@ -701,13 +815,13 @@ static bool pack_fields(File file, List<create_field> &create_fields,
int2store(buff+15, field->comment.length);
comment_length+= field->comment.length;
set_if_bigger(int_count,field->interval_id);
- if (my_write(file,(byte*) buff,FCOMP,MYF_RW))
+ if (my_write(file, buff, FCOMP, MYF_RW))
DBUG_RETURN(1);
}
/* Write fieldnames */
buff[0]=(uchar) NAMES_SEP_CHAR;
- if (my_write(file,(byte*) buff,1,MYF_RW))
+ if (my_write(file, buff, 1, MYF_RW))
DBUG_RETURN(1);
i=0;
it.rewind();
@@ -717,7 +831,7 @@ static bool pack_fields(File file, List<create_field> &create_fields,
*pos++=NAMES_SEP_CHAR;
if (i == create_fields.elements-1)
*pos++=0;
- if (my_write(file,(byte*) buff,(uint) (pos-(char*) buff),MYF_RW))
+ if (my_write(file, buff, (size_t) (pos-(char*) buff),MYF_RW))
DBUG_RETURN(1);
i++;
}
@@ -777,7 +891,7 @@ static bool pack_fields(File file, List<create_field> &create_fields,
tmp.append('\0'); // End of intervall
}
}
- if (my_write(file,(byte*) tmp.ptr(),tmp.length(),MYF_RW))
+ if (my_write(file,(uchar*) tmp.ptr(),tmp.length(),MYF_RW))
DBUG_RETURN(1);
}
if (comment_length)
@@ -787,7 +901,7 @@ static bool pack_fields(File file, List<create_field> &create_fields,
while ((field=it++))
{
if (field->comment.length)
- if (my_write(file, (byte*) field->comment.str, field->comment.length,
+ if (my_write(file, (uchar*) field->comment.str, field->comment.length,
MYF_RW))
DBUG_RETURN(1);
}
@@ -798,31 +912,30 @@ static bool pack_fields(File file, List<create_field> &create_fields,
/* save an empty record on start of formfile */
-static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
+static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type,
uint table_options,
- List<create_field> &create_fields,
+ List<Create_field> &create_fields,
uint reclength,
- ulong data_offset)
+ ulong data_offset,
+ handler *handler)
{
- int error;
+ int error= 0;
Field::utype type;
uint null_count;
uchar *buff,*null_pos;
TABLE table;
- create_field *field;
- handler *handler;
+ TABLE_SHARE share;
+ Create_field *field;
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
DBUG_ENTER("make_empty_rec");
/* We need a table to generate columns for default values */
- bzero((char*) &table,sizeof(table));
- table.s= &table.share_not_to_be_used;
- handler= get_new_handler((TABLE*) 0, thd->mem_root, table_type);
+ bzero((char*) &table, sizeof(table));
+ bzero((char*) &share, sizeof(share));
+ table.s= &share;
- if (!handler ||
- !(buff=(uchar*) my_malloc((uint) reclength,MYF(MY_WME | MY_ZEROFILL))))
+ if (!(buff=(uchar*) my_malloc((size_t) reclength,MYF(MY_WME | MY_ZEROFILL))))
{
- delete handler;
DBUG_RETURN(1);
}
@@ -838,46 +951,47 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
}
null_pos= buff;
- List_iterator<create_field> it(create_fields);
+ List_iterator<Create_field> it(create_fields);
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
while ((field=it++))
{
/*
regfield don't have to be deleted as it's allocated with sql_alloc()
*/
- Field *regfield=make_field((char*) buff+field->offset + data_offset,
- field->length,
- null_pos + null_count / 8,
- null_count & 7,
- field->pack_flag,
- field->sql_type,
- field->charset,
- field->geom_type,
- field->unireg_check,
- field->save_interval ? field->save_interval :
- field->interval,
- field->field_name,
- &table);
+ Field *regfield= make_field(&share,
+ buff+field->offset + data_offset,
+ field->length,
+ null_pos + null_count / 8,
+ null_count & 7,
+ field->pack_flag,
+ field->sql_type,
+ field->charset,
+ field->geom_type,
+ field->unireg_check,
+ field->save_interval ? field->save_interval :
+ field->interval,
+ field->field_name);
if (!regfield)
{
error= 1;
goto err; // End of memory
}
+ /* save_in_field() will access regfield->table->in_use */
+ regfield->init(&table);
+
if (!(field->flags & NOT_NULL_FLAG))
{
*regfield->null_ptr|= regfield->null_bit;
null_count++;
}
- if (field->sql_type == FIELD_TYPE_BIT && !f_bit_as_char(field->pack_flag))
+ if (field->sql_type == MYSQL_TYPE_BIT && !f_bit_as_char(field->pack_flag))
null_count+= field->length & 7;
type= (Field::utype) MTYP_TYPENR(field->unireg_check);
- if (field->def &&
- (regfield->real_type() != FIELD_TYPE_YEAR ||
- field->def->val_int() != 0))
+ if (field->def)
{
int res= field->def->save_in_field(regfield, 1);
/* If not ok or warning of level 'note' */
@@ -885,10 +999,11 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
{
my_error(ER_INVALID_DEFAULT, MYF(0), regfield->field_name);
error= 1;
+ delete regfield; //To avoid memory leak
goto err;
}
}
- else if (regfield->real_type() == FIELD_TYPE_ENUM &&
+ else if (regfield->real_type() == MYSQL_TYPE_ENUM &&
(field->flags & NOT_NULL_FLAG))
{
regfield->set_notnull();
@@ -910,11 +1025,10 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
if (null_count & 7)
*(null_pos + null_count / 8)|= ~(((uchar) 1 << (null_count & 7)) - 1);
- error=(int) my_write(file,(byte*) buff, (uint) reclength,MYF_RW);
+ error= my_write(file, buff, (size_t) reclength,MYF_RW) != 0;
err:
- my_free((gptr) buff,MYF(MY_FAE));
- delete handler;
+ my_free(buff, MYF(MY_FAE));
thd->count_cuted_fields= old_count_cuted_fields;
DBUG_RETURN(error);
} /* make_empty_rec */