#include "mysql_priv.h"#include "sql_trigger.h"#include <m_ctype.h>#include "md5.h"Include dependency graph for table.cc:

Go to the source code of this file.
Functions | |
| void | open_table_error (TABLE_SHARE *share, int error, int db_errno, myf errortype, int errarg) |
| static int | open_binary_frm (THD *thd, TABLE_SHARE *share, uchar *head, File file) |
| static void | fix_type_pointers (const char ***array, TYPELIB *point_to_type, uint types, char **names) |
| static uint | find_field (Field **fields, uint start, uint length) |
| static byte * | get_field_name (Field **buff, uint *length, my_bool not_used __attribute__((unused))) |
| char * | fn_rext (char *name) |
| TABLE_SHARE * | alloc_table_share (TABLE_LIST *table_list, char *key, uint key_length) |
| void | init_tmp_table_share (TABLE_SHARE *share, const char *key, uint key_length, const char *table_name, const char *path) |
| void | free_table_share (TABLE_SHARE *share) |
| int | open_table_def (THD *thd, TABLE_SHARE *share, uint db_flags) |
| int | open_table_from_share (THD *thd, TABLE_SHARE *share, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, bool is_create_table) |
| int | closefrm (register TABLE *table, bool free_share) |
| void | free_blobs (register TABLE *table) |
| ulong | get_form_pos (File file, uchar *head, TYPELIB *save_names) |
| int | read_string (File file, gptr *to, uint length) |
| ulong | make_new_entry (File file, uchar *fileinfo, TYPELIB *formnames, const char *newname) |
| void | open_table_error (TABLE_SHARE *share, int error, int db_errno, int errarg) |
| TYPELIB * | typelib (MEM_ROOT *mem_root, List< String > &strings) |
| int | set_zone (register int nr, int min_zone, int max_zone) |
| ulong | next_io_size (register ulong pos) |
| void | append_unescaped (String *res, const char *pos, uint length) |
| File | create_frm (THD *thd, const char *name, const char *db, const char *table, uint reclength, uchar *fileinfo, HA_CREATE_INFO *create_info, uint keys) |
| void | update_create_info_from_table (HA_CREATE_INFO *create_info, TABLE *table) |
| int | rename_file_ext (const char *from, const char *to, const char *ext) |
| bool | get_field (MEM_ROOT *mem, Field *field, String *res) |
| char * | get_field (MEM_ROOT *mem, Field *field) |
| bool | check_db_name (char *name) |
| bool | check_table_name (const char *name, uint length) |
| bool | check_column_name (const char *name) |
| my_bool | table_check_intact (TABLE *table, uint table_f_count, TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time, int error_num) |
| Item * | create_view_field (THD *thd, TABLE_LIST *view, Item **field_ref, const char *name) |
| TABLE_SHARE* alloc_table_share | ( | TABLE_LIST * | table_list, | |
| char * | key, | |||
| uint | key_length | |||
| ) |
Definition at line 91 of file table.cc.
References build_table_filename(), bzero, st_table_list::db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, flush_version, FN_REFLEN, init_sql_alloc(), memcpy, multi_alloc_root(), MY_MUTEX_INIT_FAST, NULL, path, pthread_mutex_init, refresh_version, strmov(), TABLE_ALLOC_BLOCK_SIZE, and st_table_list::table_name.
Referenced by get_table_share().
00093 { 00094 MEM_ROOT mem_root; 00095 TABLE_SHARE *share; 00096 char *key_buff, *path_buff; 00097 char path[FN_REFLEN]; 00098 uint path_length; 00099 DBUG_ENTER("alloc_table_share"); 00100 DBUG_PRINT("enter", ("table: '%s'.'%s'", 00101 table_list->db, table_list->table_name)); 00102 00103 path_length= build_table_filename(path, sizeof(path) - 1, 00104 table_list->db, 00105 table_list->table_name, "", 0); 00106 init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 00107 if (multi_alloc_root(&mem_root, 00108 &share, sizeof(*share), 00109 &key_buff, key_length, 00110 &path_buff, path_length + 1, 00111 NULL)) 00112 { 00113 bzero((char*) share, sizeof(*share)); 00114 00115 share->set_table_cache_key(key_buff, key, key_length); 00116 00117 share->path.str= path_buff; 00118 share->path.length= path_length; 00119 strmov(share->path.str, path); 00120 share->normalized_path.str= share->path.str; 00121 share->normalized_path.length= path_length; 00122 00123 share->version= refresh_version; 00124 share->flush_version= flush_version; 00125 00126 #ifdef HAVE_ROW_BASED_REPLICATION 00127 /* 00128 This constant is used to mark that no table map version has been 00129 assigned. No arithmetic is done on the value: it will be 00130 overwritten with a value taken from MYSQL_BIN_LOG. 00131 */ 00132 share->table_map_version= ~(ulonglong)0; 00133 00134 /* 00135 Since alloc_table_share() can be called without any locking (for 00136 example, ha_create_table... functions), we do not assign a table 00137 map id here. Instead we assign a value that is not used 00138 elsewhere, and then assign a table map id inside open_table() 00139 under the protection of the LOCK_open mutex. 00140 */ 00141 share->table_map_id= ~0UL; 00142 share->cached_row_logging_check= -1; 00143 00144 #endif 00145 00146 memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root)); 00147 pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST); 00148 pthread_cond_init(&share->cond, NULL); 00149 } 00150 DBUG_RETURN(share); 00151 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2001 of file table.cc.
References String::append(), default_charset_info, my_ismbchar, MYSQL_VERSION_ID, use_mb, and USE_MB.
Referenced by create_string(), Event_timed::get_create_event(), Field_set::sql_type(), Field_enum::sql_type(), and store_create_info().
02002 { 02003 const char *end= pos+length; 02004 res->append('\''); 02005 02006 for (; pos != end ; pos++) 02007 { 02008 #if defined(USE_MB) && MYSQL_VERSION_ID < 40100 02009 uint mblen; 02010 if (use_mb(default_charset_info) && 02011 (mblen= my_ismbchar(default_charset_info, pos, end))) 02012 { 02013 res->append(pos, mblen); 02014 pos+= mblen; 02015 continue; 02016 } 02017 #endif 02018 02019 switch (*pos) { 02020 case 0: /* Must be escaped for 'mysql' */ 02021 res->append('\\'); 02022 res->append('0'); 02023 break; 02024 case '\n': /* Must be escaped for logs */ 02025 res->append('\\'); 02026 res->append('n'); 02027 break; 02028 case '\r': 02029 res->append('\\'); /* This gives better readability */ 02030 res->append('r'); 02031 break; 02032 case '\\': 02033 res->append('\\'); /* Because of the sql syntax */ 02034 res->append('\\'); 02035 break; 02036 case '\'': 02037 res->append('\''); /* Because of the sql syntax */ 02038 res->append('\''); 02039 break; 02040 default: 02041 res->append(*pos); 02042 break; 02043 } 02044 } 02045 res->append('\''); 02046 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_column_name | ( | const char * | name | ) |
Definition at line 2318 of file table.cc.
References charset_info_st::mbmaxlen, my_ismbchar, my_isspace, NAME_LEN, NAMES_SEP_CHAR, start(), system_charset_info, TRUE, and use_mb.
Referenced by mysql_prepare_table().
02319 { 02320 const char *start= name; 02321 bool last_char_is_space= TRUE; 02322 02323 while (*name) 02324 { 02325 #if defined(USE_MB) && defined(USE_MB_IDENT) 02326 last_char_is_space= my_isspace(system_charset_info, *name); 02327 if (use_mb(system_charset_info)) 02328 { 02329 int len=my_ismbchar(system_charset_info, name, 02330 name+system_charset_info->mbmaxlen); 02331 if (len) 02332 { 02333 name += len; 02334 continue; 02335 } 02336 } 02337 #else 02338 last_char_is_space= *name==' '; 02339 #endif 02340 if (*name == NAMES_SEP_CHAR) 02341 return 1; 02342 name++; 02343 } 02344 /* Error if empty or too long column name */ 02345 return last_char_is_space || (uint) (name - start) > NAME_LEN; 02346 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_db_name | ( | char * | name | ) |
Definition at line 2243 of file table.cc.
References any_db, files_charset_info, lower_case_table_names, charset_info_st::mbmaxlen, my_casedn_str, my_ismbchar, my_isspace, NAME_LEN, start(), system_charset_info, TRUE, and use_mb.
Referenced by dispatch_command(), mysql_change_db(), mysql_create_like_table(), mysql_execute_command(), mysql_table_dump(), and prepare_schema_table().
02244 { 02245 char *start=name; 02246 /* Used to catch empty names and names with end space */ 02247 bool last_char_is_space= TRUE; 02248 02249 if (lower_case_table_names && name != any_db) 02250 my_casedn_str(files_charset_info, name); 02251 02252 while (*name) 02253 { 02254 #if defined(USE_MB) && defined(USE_MB_IDENT) 02255 last_char_is_space= my_isspace(system_charset_info, *name); 02256 if (use_mb(system_charset_info)) 02257 { 02258 int len=my_ismbchar(system_charset_info, name, 02259 name+system_charset_info->mbmaxlen); 02260 if (len) 02261 { 02262 name += len; 02263 continue; 02264 } 02265 } 02266 #else 02267 last_char_is_space= *name==' '; 02268 #endif 02269 name++; 02270 } 02271 return last_char_is_space || (uint) (name - start) > NAME_LEN; 02272 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2282 of file table.cc.
References FALSE, my_ismbchar, my_isspace, NAME_LEN, system_charset_info, and use_mb.
Referenced by mysql_create_like_table().
02283 { 02284 const char *end= name+length; 02285 if (!length || length > NAME_LEN) 02286 return 1; 02287 #if defined(USE_MB) && defined(USE_MB_IDENT) 02288 bool last_char_is_space= FALSE; 02289 #else 02290 if (name[length-1]==' ') 02291 return 1; 02292 #endif 02293 02294 while (name != end) 02295 { 02296 #if defined(USE_MB) && defined(USE_MB_IDENT) 02297 last_char_is_space= my_isspace(system_charset_info, *name); 02298 if (use_mb(system_charset_info)) 02299 { 02300 int len=my_ismbchar(system_charset_info, name, end); 02301 if (len) 02302 { 02303 name += len; 02304 continue; 02305 } 02306 } 02307 #endif 02308 name++; 02309 } 02310 #if defined(USE_MB) && defined(USE_MB_IDENT) 02311 return last_char_is_space; 02312 #else 02313 return 0; 02314 #endif 02315 }
Here is the caller graph for this function:

Definition at line 1594 of file table.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, error, st_key::flags, free_items(), free_root(), free_table_share(), HA_USES_PARSER, MY_ALLOW_ZERO_PTR, my_free, MYF, NO_TMP_TABLE, st_key::parser, plugin_unlock(), RELEASE_NORMAL, and release_table_share().
Referenced by close_temporary(), ha_create_table(), ha_create_table_from_engine(), intern_close_table(), open_unireg_entry(), prepare_for_repair(), and reopen_table().
01595 { 01596 int error=0; 01597 uint idx; 01598 KEY *key_info; 01599 DBUG_ENTER("closefrm"); 01600 DBUG_PRINT("enter", ("table: 0x%lx", (long) table)); 01601 01602 if (table->db_stat) 01603 error=table->file->close(); 01604 key_info= table->key_info; 01605 for (idx= table->s->keys; idx; idx--, key_info++) 01606 { 01607 if (key_info->flags & HA_USES_PARSER) 01608 { 01609 plugin_unlock(key_info->parser); 01610 key_info->flags= 0; 01611 } 01612 } 01613 my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR)); 01614 table->alias= 0; 01615 if (table->field) 01616 { 01617 for (Field **ptr=table->field ; *ptr ; ptr++) 01618 delete *ptr; 01619 table->field= 0; 01620 } 01621 delete table->file; 01622 table->file= 0; /* For easier errorchecking */ 01623 #ifdef WITH_PARTITION_STORAGE_ENGINE 01624 if (table->part_info) 01625 { 01626 free_items(table->part_info->item_free_list); 01627 table->part_info->item_free_list= 0; 01628 table->part_info= 0; 01629 } 01630 #endif 01631 if (free_share) 01632 { 01633 if (table->s->tmp_table == NO_TMP_TABLE) 01634 release_table_share(table->s, RELEASE_NORMAL); 01635 else 01636 free_table_share(table->s); 01637 } 01638 free_root(&table->mem_root, MYF(0)); 01639 DBUG_RETURN(error); 01640 }
Here is the call graph for this function:

Here is the caller graph for this function:

| File create_frm | ( | THD * | thd, | |
| const char * | name, | |||
| const char * | db, | |||
| const char * | table, | |||
| uint | reclength, | |||
| uchar * | fileinfo, | |||
| HA_CREATE_INFO * | create_info, | |||
| uint | keys | |||
| ) |
Definition at line 2051 of file table.cc.
References st_ha_create_information::avg_row_length, bzero, CREATE_MODE, st_ha_create_information::db_type, st_ha_create_information::default_table_charset, ER_BAD_DB_ERROR, ER_CANT_CREATE_TABLE, st_ha_create_information::extra_size, mySTL::fill(), FRM_VER, ha_checktype(), ha_legacy_type(), HA_LEX_CREATE_TMP_TABLE, HA_OPTION_LONG_BLOB_PTR, int2store, int4store, IO_SIZE, st_ha_create_information::key_block_size, key_length, MAX_REF_PARTS, st_ha_create_information::max_rows, st_ha_create_information::min_rows, my_close(), my_create(), my_delete(), my_errno, my_error(), MY_NABP, MY_WME, my_write, MYF, MYSQL_VERSION_ID, NAME_LEN, next_io_size(), charset_info_st::number, O_NOFOLLOW, st_ha_create_information::options, st_ha_create_information::row_type, st_ha_create_information::table_options, test, UINT_MAX32, st_ha_create_information::varchar, and VOID.
Referenced by mysql_create_frm().
02054 { 02055 register File file; 02056 uint key_length; 02057 ulong length; 02058 char fill[IO_SIZE]; 02059 int create_flags= O_RDWR | O_TRUNC; 02060 02061 if (create_info->options & HA_LEX_CREATE_TMP_TABLE) 02062 create_flags|= O_EXCL | O_NOFOLLOW; 02063 02064 /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */ 02065 if (create_info->max_rows > UINT_MAX32) 02066 create_info->max_rows= UINT_MAX32; 02067 if (create_info->min_rows > UINT_MAX32) 02068 create_info->min_rows= UINT_MAX32; 02069 02070 if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0) 02071 { 02072 uint key_length, tmp_key_length; 02073 uint tmp; 02074 bzero((char*) fileinfo,64); 02075 /* header */ 02076 fileinfo[0]=(uchar) 254; 02077 fileinfo[1]= 1; 02078 fileinfo[2]= FRM_VER+3+ test(create_info->varchar); 02079 02080 fileinfo[3]= (uchar) ha_legacy_type( 02081 ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); 02082 fileinfo[4]=1; 02083 int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ 02084 key_length=keys*(7+NAME_LEN+MAX_REF_PARTS*9)+16; 02085 length= next_io_size((ulong) (IO_SIZE+key_length+reclength+ 02086 create_info->extra_size)); 02087 int4store(fileinfo+10,length); 02088 tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff; 02089 int2store(fileinfo+14,tmp_key_length); 02090 int2store(fileinfo+16,reclength); 02091 int4store(fileinfo+18,create_info->max_rows); 02092 int4store(fileinfo+22,create_info->min_rows); 02093 fileinfo[27]=2; // Use long pack-fields 02094 create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers 02095 int2store(fileinfo+30,create_info->table_options); 02096 fileinfo[32]=0; // No filename anymore 02097 fileinfo[33]=5; // Mark for 5.0 frm file 02098 int4store(fileinfo+34,create_info->avg_row_length); 02099 fileinfo[38]= (create_info->default_table_charset ? 02100 create_info->default_table_charset->number : 0); 02101 fileinfo[40]= (uchar) create_info->row_type; 02102 /* Next few bytes were for RAID support */ 02103 fileinfo[41]= 0; 02104 fileinfo[42]= 0; 02105 fileinfo[43]= 0; 02106 fileinfo[44]= 0; 02107 fileinfo[45]= 0; 02108 fileinfo[46]= 0; 02109 int4store(fileinfo+47, key_length); 02110 tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store 02111 int4store(fileinfo+51, tmp); 02112 int4store(fileinfo+55, create_info->extra_size); 02113 /* 02114 59-60 is reserved for extra_rec_buf_length, 02115 61 for default_part_db_type 02116 */ 02117 int2store(fileinfo+62, create_info->key_block_size); 02118 bzero(fill,IO_SIZE); 02119 for (; length > IO_SIZE ; length-= IO_SIZE) 02120 { 02121 if (my_write(file,(byte*) fill,IO_SIZE,MYF(MY_WME | MY_NABP))) 02122 { 02123 VOID(my_close(file,MYF(0))); 02124 VOID(my_delete(name,MYF(0))); 02125 return(-1); 02126 } 02127 } 02128 } 02129 else 02130 { 02131 if (my_errno == ENOENT) 02132 my_error(ER_BAD_DB_ERROR,MYF(0),db); 02133 else 02134 my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); 02135 } 02136 return (file); 02137 } /* create_frm */
Here is the call graph for this function:

Here is the caller graph for this function:

| Item* create_view_field | ( | THD * | thd, | |
| TABLE_LIST * | view, | |||
| Item ** | field_ref, | |||
| const char * | name | |||
| ) |
Definition at line 3462 of file table.cc.
References st_table_list::alias, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, Item::fix_fields(), Item::fixed, st_table_list::schema_table_reformed, TRUE, and st_table_list::view.
Referenced by Field_iterator_view::create_item(), and Natural_join_column::create_item().
03464 { 03465 bool save_wrapper= thd->lex->select_lex.no_wrap_view_item; 03466 Item *field= *field_ref; 03467 DBUG_ENTER("create_view_field"); 03468 03469 if (view->schema_table_reformed) 03470 { 03471 /* 03472 Translation table items are always Item_fields and already fixed 03473 ('mysql_schema_table' function). So we can return directly the 03474 field. This case happens only for 'show & where' commands. 03475 */ 03476 DBUG_ASSERT(field && field->fixed); 03477 DBUG_RETURN(field); 03478 } 03479 03480 DBUG_ASSERT(field); 03481 thd->lex->current_select->no_wrap_view_item= TRUE; 03482 if (!field->fixed) 03483 { 03484 if (field->fix_fields(thd, field_ref)) 03485 { 03486 thd->lex->current_select->no_wrap_view_item= save_wrapper; 03487 DBUG_RETURN(0); 03488 } 03489 field= *field_ref; 03490 } 03491 thd->lex->current_select->no_wrap_view_item= save_wrapper; 03492 if (save_wrapper) 03493 { 03494 DBUG_RETURN(field); 03495 } 03496 Item *item= new Item_direct_view_ref(&view->view->select_lex.context, 03497 field_ref, view->alias, 03498 name); 03499 DBUG_RETURN(item); 03500 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1944 of file table.cc.
References Field::pack_length().
01945 { 01946 Field **field; 01947 uint i, pos; 01948 01949 pos= 0; 01950 for (field= fields, i=1 ; *field ; i++,field++) 01951 { 01952 if ((*field)->offset() == start) 01953 { 01954 if ((*field)->key_length() == length) 01955 return (i); 01956 if (!pos || fields[pos-1]->pack_length() < 01957 (*field)->pack_length()) 01958 pos= i; 01959 } 01960 } 01961 return (pos); 01962 }
Here is the call graph for this function:

| static void fix_type_pointers | ( | const char *** | array, | |
| TYPELIB * | point_to_type, | |||
| uint | types, | |||
| char ** | names | |||
| ) | [static] |
Definition at line 1874 of file table.cc.
References st_typelib::count, st_typelib::name, NullS, strchr(), and st_typelib::type_names.
Referenced by get_form_pos().
01876 { 01877 char *type_name, *ptr; 01878 char chr; 01879 01880 ptr= *names; 01881 while (types--) 01882 { 01883 point_to_type->name=0; 01884 point_to_type->type_names= *array; 01885 01886 if ((chr= *ptr)) /* Test if empty type */ 01887 { 01888 while ((type_name=strchr(ptr+1,chr)) != NullS) 01889 { 01890 *((*array)++) = ptr+1; 01891 *type_name= '\0'; /* End string */ 01892 ptr=type_name; 01893 } 01894 ptr+=2; /* Skip end mark and last 0 */ 01895 } 01896 else 01897 ptr++; 01898 point_to_type->count= (uint) (*array - point_to_type->type_names); 01899 point_to_type++; 01900 *((*array)++)= NullS; /* End of type */ 01901 } 01902 *names=ptr; /* Update end */ 01903 return; 01904 } /* fix_type_pointers */
Here is the call graph for this function:

Here is the caller graph for this function:

| char* fn_rext | ( | char * | name | ) |
Definition at line 68 of file table.cc.
References reg_ext, strcmp(), strlen(), and strrchr().
Referenced by find_files(), mysql_create_frm(), mysql_rename_db(), and rea_create_table().
00069 { 00070 char *res= strrchr(name, '.'); 00071 if (res && !strcmp(res, reg_ext)) 00072 return res; 00073 return name + strlen(name); 00074 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void free_blobs | ( | register TABLE * | table | ) |
Definition at line 1645 of file table.cc.
References Field::free().
01646 { 01647 uint *ptr, *end; 01648 for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ; 01649 ptr != end ; 01650 ptr++) 01651 ((Field_blob*) table->field[*ptr])->free(); 01652 }
Here is the call graph for this function:

| void free_table_share | ( | TABLE_SHARE * | share | ) |
Definition at line 222 of file table.cc.
References st_table_share::cond, st_table_share::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, free_root(), hash_free(), st_table_share::mem_root, memcpy, st_table_share::mutex, MYF, st_table_share::name_hash, NO_TMP_TABLE, pthread_mutex_destroy, pthread_mutex_unlock, st_table_share::ref_count, LEX_STRING::str, st_table_share::table_name, st_table_share::tmp_table, and st_table_share::waiting_on_cond.
Referenced by close_temporary(), closefrm(), get_table_share(), ha_create_table(), ha_create_table_from_engine(), mysql_truncate(), open_temporary_table(), release_table_share(), and table_def_free_entry().
00223 { 00224 MEM_ROOT mem_root; 00225 DBUG_ENTER("free_table_share"); 00226 DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str)); 00227 DBUG_ASSERT(share->ref_count == 0); 00228 00229 /* 00230 If someone is waiting for this to be deleted, inform it about this. 00231 Don't do a delete until we know that no one is refering to this anymore. 00232 */ 00233 if (share->tmp_table == NO_TMP_TABLE) 00234 { 00235 /* share->mutex is locked in release_table_share() */ 00236 while (share->waiting_on_cond) 00237 { 00238 pthread_cond_broadcast(&share->cond); 00239 pthread_cond_wait(&share->cond, &share->mutex); 00240 } 00241 /* No thread refers to this anymore */ 00242 pthread_mutex_unlock(&share->mutex); 00243 pthread_mutex_destroy(&share->mutex); 00244 pthread_cond_destroy(&share->cond); 00245 } 00246 hash_free(&share->name_hash); 00247 00248 /* We must copy mem_root from share because share is allocated through it */ 00249 memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root)); 00250 free_root(&mem_root, MYF(0)); // Free's share 00251 DBUG_VOID_RETURN; 00252 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2212 of file table.cc.
References alloc_root(), String::length(), MAX_FIELD_WIDTH, mem, memcpy, my_charset_bin, NullS, String::ptr(), to, and Field::val_str().
02213 { 02214 char buff[MAX_FIELD_WIDTH], *to; 02215 String str(buff,sizeof(buff),&my_charset_bin); 02216 uint length; 02217 02218 field->val_str(&str); 02219 length= str.length(); 02220 if (!length || !(to= (char*) alloc_root(mem,length+1))) 02221 return NullS; 02222 memcpy(to,str.ptr(),(uint) length); 02223 to[length]=0; 02224 return to; 02225 }
Here is the call graph for this function:

Definition at line 2180 of file table.cc.
References charset, String::length(), MAX_FIELD_WIDTH, mem, my_charset_bin, String::ptr(), String::set(), strmake_root(), to, and Field::val_str().
Referenced by acl_load(), db_drop_events_from_table(), db_find_routine(), get_all_items_for_category(), GRANT_NAME::GRANT_NAME(), handle_grant_table(), Event_timed::load_from_row(), memorize_variant_topic(), plugin_load(), print_field_values(), search_categories(), and store_schema_proc().
02181 { 02182 char buff[MAX_FIELD_WIDTH], *to; 02183 String str(buff,sizeof(buff),&my_charset_bin); 02184 uint length; 02185 02186 field->val_str(&str); 02187 if (!(length= str.length())) 02188 { 02189 res->length(0); 02190 return 1; 02191 } 02192 if (!(to= strmake_root(mem, str.ptr(), length))) 02193 length= 0; // Safety fix 02194 res->set(to, length, ((Field_str*)field)->charset()); 02195 return 0; 02196 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1658 of file table.cc.
References buf, bzero, DBUG_ENTER, DBUG_RETURN, fix_type_pointers(), my_free, my_malloc(), MY_NABP, my_read, my_seek(), MY_SEEK_SET, MY_WME, MYF, st_typelib::type_names, uint2korr, uint4korr, VOID, and x_free.
Referenced by mysql_create_frm(), and open_binary_frm().
01659 { 01660 uint a_length,names,length; 01661 uchar *pos,*buf; 01662 ulong ret_value=0; 01663 DBUG_ENTER("get_form_pos"); 01664 01665 names=uint2korr(head+8); 01666 a_length=(names+2)*sizeof(my_string); /* Room for two extra */ 01667 01668 if (!save_names) 01669 a_length=0; 01670 else 01671 save_names->type_names=0; /* Clear if error */ 01672 01673 if (names) 01674 { 01675 length=uint2korr(head+4); 01676 VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0))); 01677 if (!(buf= (uchar*) my_malloc((uint) length+a_length+names*4, 01678 MYF(MY_WME))) || 01679 my_read(file,(byte*) buf+a_length,(uint) (length+names*4), 01680 MYF(MY_NABP))) 01681 { /* purecov: inspected */ 01682 x_free((gptr) buf); /* purecov: inspected */ 01683 DBUG_RETURN(0L); /* purecov: inspected */ 01684 } 01685 pos= buf+a_length+length; 01686 ret_value=uint4korr(pos); 01687 } 01688 if (! save_names) 01689 { 01690 if (names) 01691 my_free((gptr) buf,MYF(0)); 01692 } 01693 else if (!names) 01694 bzero((char*) save_names,sizeof(save_names)); 01695 else 01696 { 01697 char *str; 01698 str=(char *) (buf+a_length); 01699 fix_type_pointers((const char ***) &buf,save_names,1,&str); 01700 } 01701 DBUG_RETURN(ret_value); 01702 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void init_tmp_table_share | ( | TABLE_SHARE * | share, | |
| const char * | key, | |||
| uint | key_length, | |||
| const char * | table_name, | |||
| const char * | path | |||
| ) |
Definition at line 176 of file table.cc.
References bzero, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, FRM_VER_TRUE_VARCHAR, init_sql_alloc(), INTERNAL_TMP_TABLE, strlen(), and TABLE_ALLOC_BLOCK_SIZE.
Referenced by create_table_from_items(), create_tmp_table(), ha_create_table(), ha_create_table_from_engine(), and open_temporary_table().
00179 { 00180 DBUG_ENTER("init_tmp_table_share"); 00181 DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name)); 00182 00183 bzero((char*) share, sizeof(*share)); 00184 init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 00185 share->tmp_table= INTERNAL_TMP_TABLE; 00186 share->db.str= (char*) key; 00187 share->db.length= strlen(key); 00188 share->table_cache_key.str= (char*) key; 00189 share->table_cache_key.length= key_length; 00190 share->table_name.str= (char*) table_name; 00191 share->table_name.length= strlen(table_name); 00192 share->path.str= (char*) path; 00193 share->normalized_path.str= (char*) path; 00194 share->path.length= share->normalized_path.length= strlen(path); 00195 share->frm_version= FRM_VER_TRUE_VARCHAR; 00196 00197 #ifdef HAVE_ROW_BASED_REPLICATION 00198 /* 00199 Temporary tables are not replicated, but we set up these fields 00200 anyway to be able to catch errors. 00201 */ 00202 share->table_map_version= ~(ulonglong)0; 00203 share->table_map_id= ~0UL; 00204 share->cached_row_logging_check= -1; 00205 #endif 00206 00207 DBUG_VOID_RETURN; 00208 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1726 of file table.cc.
References bzero, DBUG_ENTER, DBUG_RETURN, int2store, int4store, IO_SIZE, my_chsize(), MY_NABP, my_read, my_seek(), MY_SEEK_END, MY_SEEK_SET, MY_WME, my_write, MYF, NullS, strlen(), strxmov(), st_typelib::type_names, uint2korr, uint4korr, and VOID.
Referenced by mysql_create_frm().
01728 { 01729 uint i,bufflength,maxlength,n_length,length,names; 01730 ulong endpos,newpos; 01731 char buff[IO_SIZE]; 01732 uchar *pos; 01733 DBUG_ENTER("make_new_entry"); 01734 01735 length=(uint) strlen(newname)+1; 01736 n_length=uint2korr(fileinfo+4); 01737 maxlength=uint2korr(fileinfo+6); 01738 names=uint2korr(fileinfo+8); 01739 newpos=uint4korr(fileinfo+10); 01740 01741 if (64+length+n_length+(names+1)*4 > maxlength) 01742 { /* Expand file */ 01743 newpos+=IO_SIZE; 01744 int4store(fileinfo+10,newpos); 01745 endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */ 01746 bufflength= (uint) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */ 01747 01748 while (endpos > maxlength) 01749 { 01750 VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0))); 01751 if (my_read(file,(byte*) buff,bufflength,MYF(MY_NABP+MY_WME))) 01752 DBUG_RETURN(0L); 01753 VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET, 01754 MYF(0))); 01755 if ((my_write(file,(byte*) buff,bufflength,MYF(MY_NABP+MY_WME)))) 01756 DBUG_RETURN(0); 01757 endpos-=bufflength; bufflength=IO_SIZE; 01758 } 01759 bzero(buff,IO_SIZE); /* Null new block */ 01760 VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0))); 01761 if (my_write(file,(byte*) buff,bufflength,MYF(MY_NABP+MY_WME))) 01762 DBUG_RETURN(0L); 01763 maxlength+=IO_SIZE; /* Fix old ref */ 01764 int2store(fileinfo+6,maxlength); 01765 for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ; 01766 pos+=4) 01767 { 01768 endpos=uint4korr(pos)+IO_SIZE; 01769 int4store(pos,endpos); 01770 } 01771 } 01772 01773 if (n_length == 1 ) 01774 { /* First name */ 01775 length++; 01776 VOID(strxmov(buff,"/",newname,"/",NullS)); 01777 } 01778 else 01779 VOID(strxmov(buff,newname,"/",NullS)); /* purecov: inspected */ 01780 VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0))); 01781 if (my_write(file,(byte*) buff,(uint) length+1,MYF(MY_NABP+MY_WME)) || 01782 (names && my_write(file,(byte*) (*formnames->type_names+n_length-1), 01783 names*4, MYF(MY_NABP+MY_WME))) || 01784 my_write(file,(byte*) fileinfo+10,(uint) 4,MYF(MY_NABP+MY_WME))) 01785 DBUG_RETURN(0L); /* purecov: inspected */ 01786 01787 int2store(fileinfo+8,names+1); 01788 int2store(fileinfo+4,n_length+length); 01789 VOID(my_chsize(file, newpos, 0, MYF(MY_WME)));/* Append file with '\0' */ 01790 DBUG_RETURN(newpos); 01791 } /* make_new_entry */
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1978 of file table.cc.
References IO_SIZE, offset, and reg2.
Referenced by create_frm(), and mysql_create_frm().
01979 { 01980 reg2 ulong offset; 01981 if ((offset= pos & (IO_SIZE-1))) 01982 return pos-offset+IO_SIZE; 01983 return pos; 01984 } /* next_io_size */
Here is the caller graph for this function:

| static int open_binary_frm | ( | THD * | thd, | |
| TABLE_SHARE * | share, | |||
| uchar * | head, | |||
| File | file | |||
| ) | [static] |
Definition at line 411 of file table.cc.
References alloc_root(), st_table_share::avg_row_length, st_table_share::blob_ptr_size, bzero, st_table_share::connect_string, st_table_share::crypted, st_table_share::db_create_options, st_table_share::db_low_byte_first, st_table_share::db_options_in_use, st_table_share::db_record_offset, st_table_share::db_type, DB_TYPE_ISAM, DBUG_ENTER, DBUG_PRINT, default_charset_info, ER_PLUGIN_IS_NOT_LOADED, err, error, FIELD_NR_MASK, st_key_part_info::fieldnr, FRM_VER, FRM_VER_TRUE_VARCHAR, st_table_share::frm_version, get_charset(), get_form_pos(), ha_checktype(), HA_KEY_ALG_UNDEF, ha_legacy_type(), HA_NOSAME, HA_OPTION_LONG_BLOB_PTR, ha_resolve_by_name(), HA_REVERSE_SORT, HA_USES_PARSER, Bitmap< 64 >::init(), st_table_share::key_info, st_key_part_info::key_part_flag, st_table_share::key_parts, st_key_part_info::key_type, keyinfo, st_table_share::keys, keys, st_table_share::keys_for_keyread, st_table_share::keys_in_use, LEX_STRING::length, st_key_part_info::length, st_table_share::max_rows, st_table_share::mem_root, memdup_root(), st_table_share::min_rows, my_error(), my_free, my_malloc(), MY_NABP, my_pread(), my_reinterpret_cast, my_seek(), MY_SEEK_SET, MY_WME, MYF, MYSQL_FTPARSER_PLUGIN, st_table_share::mysql_version, name, NULL, st_table_share::null_field_first, st_key_part_info::offset, st_table_share::path, plugin_lock(), portable_sizeof_char_ptr, pos(), read_string(), st_table_share::reclength, sql_print_warning(), st_key_part_info::store_length, LEX_STRING::str, strlen(), strmake_root(), strmov(), st_table_share::system, st_table_share::table_charset, test, uint2korr, uint4korr, use_mb, and VOID.
Referenced by open_table_def().
00413 { 00414 int error, errarg= 0; 00415 uint new_frm_ver, field_pack_length, new_field_pack_flag; 00416 uint interval_count, interval_parts, read_length, int_length; 00417 uint db_create_options, keys, key_parts, n_length; 00418 uint key_info_length, com_length, null_bit_pos; 00419 uint extra_rec_buf_length; 00420 uint i,j; 00421 bool use_hash; 00422 char *keynames, *record, *names, *comment_pos; 00423 uchar *disk_buff, *strpos, *null_flags, *null_pos; 00424 ulong pos, record_offset, *rec_per_key, rec_buff_length; 00425 handler *handler_file= 0; 00426 KEY *keyinfo; 00427 KEY_PART_INFO *key_part; 00428 SQL_CRYPT *crypted=0; 00429 Field **field_ptr, *reg_field; 00430 const char **interval_array; 00431 enum legacy_db_type legacy_db_type; 00432 my_bitmap_map *bitmaps; 00433 DBUG_ENTER("open_binary_frm"); 00434 00435 new_field_pack_flag= head[27]; 00436 new_frm_ver= (head[2] - FRM_VER); 00437 field_pack_length= new_frm_ver < 2 ? 11 : 17; 00438 disk_buff= 0; 00439 00440 error= 3; 00441 if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) 00442 goto err; /* purecov: inspected */ 00443 00444 share->frm_version= head[2]; 00445 /* 00446 Check if .frm file created by MySQL 5.0. In this case we want to 00447 display CHAR fields as CHAR and not as VARCHAR. 00448 We do it this way as we want to keep the old frm version to enable 00449 MySQL 4.1 to read these files. 00450 */ 00451 if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5) 00452 share->frm_version= FRM_VER_TRUE_VARCHAR; 00453 00454 #ifdef WITH_PARTITION_STORAGE_ENGINE 00455 if (*(head+61) && 00456 !(share->default_part_db_type= 00457 ha_checktype(thd, (enum legacy_db_type) (uint) *(head+61), 1, 0))) 00458 goto err; 00459 DBUG_PRINT("info", ("default_part_db_type = %u", head[61])); 00460 #endif 00461 legacy_db_type= (enum legacy_db_type) (uint) *(head+3); 00462 share->db_type= ha_checktype(thd, legacy_db_type, 0, 0); 00463 share->db_create_options= db_create_options= uint2korr(head+30); 00464 share->db_options_in_use= share->db_create_options; 00465 share->mysql_version= uint4korr(head+51); 00466 share->null_field_first= 0; 00467 if (!head[32]) // New frm file in 3.23 00468 { 00469 share->avg_row_length= uint4korr(head+34); 00470 share-> row_type= (row_type) head[40]; 00471 share->table_charset= get_charset((uint) head[38],MYF(0)); 00472 share->null_field_first= 1; 00473 } 00474 if (!share->table_charset) 00475 { 00476 /* unknown charset in head[38] or pre-3.23 frm */ 00477 if (use_mb(default_charset_info)) 00478 { 00479 /* Warn that we may be changing the size of character columns */ 00480 sql_print_warning("'%s' had no or invalid character set, " 00481 "and default character set is multi-byte, " 00482 "so character column sizes may have changed", 00483 share->path); 00484 } 00485 share->table_charset= default_charset_info; 00486 } 00487 share->db_record_offset= 1; 00488 if (db_create_options & HA_OPTION_LONG_BLOB_PTR) 00489 share->blob_ptr_size= portable_sizeof_char_ptr; 00490 /* Set temporarily a good value for db_low_byte_first */ 00491 share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM); 00492 error=4; 00493 share->max_rows= uint4korr(head+18); 00494 share->min_rows= uint4korr(head+22); 00495 00496 /* Read keyinformation */ 00497 key_info_length= (uint) uint2korr(head+28); 00498 VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); 00499 if (read_string(file,(gptr*) &disk_buff,key_info_length)) 00500 goto err; /* purecov: inspected */ 00501 if (disk_buff[0] & 0x80) 00502 { 00503 share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); 00504 share->key_parts= key_parts= uint2korr(disk_buff+2); 00505 } 00506 else 00507 { 00508 share->keys= keys= disk_buff[0]; 00509 share->key_parts= key_parts= disk_buff[1]; 00510 } 00511 share->keys_for_keyread.init(0); 00512 share->keys_in_use.init(keys); 00513 00514 n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); 00515 if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, 00516 n_length + uint2korr(disk_buff+4)))) 00517 goto err; /* purecov: inspected */ 00518 bzero((char*) keyinfo,n_length); 00519 share->key_info= keyinfo; 00520 key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); 00521 strpos=disk_buff+6; 00522 00523 if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, 00524 sizeof(ulong*)*key_parts))) 00525 goto err; 00526 00527 for (i=0 ; i < keys ; i++, keyinfo++) 00528 { 00529 keyinfo->table= 0; // Updated in open_frm 00530 if (new_frm_ver >= 3) 00531 { 00532 keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; 00533 keyinfo->key_length= (uint) uint2korr(strpos+2); 00534 keyinfo->key_parts= (uint) strpos[4]; 00535 keyinfo->algorithm= (enum ha_key_alg) strpos[5]; 00536 keyinfo->block_size= uint2korr(strpos+6); 00537 strpos+=8; 00538 } 00539 else 00540 { 00541 keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; 00542 keyinfo->key_length= (uint) uint2korr(strpos+1); 00543 keyinfo->key_parts= (uint) strpos[3]; 00544 keyinfo->algorithm= HA_KEY_ALG_UNDEF; 00545 strpos+=4; 00546 } 00547 00548 keyinfo->key_part= key_part; 00549 keyinfo->rec_per_key= rec_per_key; 00550 for (j=keyinfo->key_parts ; j-- ; key_part++) 00551 { 00552 *rec_per_key++=0; 00553 key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK); 00554 key_part->offset= (uint) uint2korr(strpos+2)-1; 00555 key_part->key_type= (uint) uint2korr(strpos+5); 00556 // key_part->field= (Field*) 0; // Will be fixed later 00557 if (new_frm_ver >= 1) 00558 { 00559 key_part->key_part_flag= *(strpos+4); 00560 key_part->length= (uint) uint2korr(strpos+7); 00561 strpos+=9; 00562 } 00563 else 00564 { 00565 key_part->length= *(strpos+4); 00566 key_part->key_part_flag=0; 00567 if (key_part->length > 128) 00568 { 00569 key_part->length&=127; /* purecov: inspected */ 00570 key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */ 00571 } 00572 strpos+=7; 00573 } 00574 key_part->store_length=key_part->length; 00575 } 00576 } 00577 keynames=(char*) key_part; 00578 strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; 00579 00580 share->reclength = uint2korr((head+16)); 00581 if (*(head+26) == 1) 00582 share->system= 1; /* one-record-database */ 00583 #ifdef HAVE_CRYPTED_FRM 00584 else if (*(head+26) == 2) 00585 { 00586 crypted= get_crypt_for_frm(); 00587 share->crypted= 1; 00588 } 00589 #endif 00590 00591 record_offset= (ulong) (uint2korr(head+6)+ 00592 ((uint2korr(head+14) == 0xffff ? 00593 uint4korr(head+47) : uint2korr(head+14)))); 00594 00595 if ((n_length= uint4korr(head+55))) 00596 { 00597 /* Read extra data segment */ 00598 char *buff, *next_chunk, *buff_end; 00599 DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); 00600 if (!(next_chunk= buff= my_malloc(n_length, MYF(MY_WME)))) 00601 goto err; 00602 if (my_pread(file, (byte*)buff, n_length, record_offset + share->reclength, 00603 MYF(MY_NABP))) 00604 { 00605 my_free(buff, MYF(0)); 00606 goto err; 00607 } 00608 share->connect_string.length= uint2korr(buff); 00609 if (! (share->connect_string.str= strmake_root(&share->mem_root, 00610 next_chunk + 2, share->connect_string.length))) 00611 { 00612 my_free(buff, MYF(0)); 00613 goto err; 00614 } 00615 next_chunk+= share->connect_string.length + 2; 00616 buff_end= buff + n_length; 00617 if (next_chunk + 2 < buff_end) 00618 { 00619 uint str_db_type_length= uint2korr(next_chunk); 00620 LEX_STRING name= { next_chunk + 2, str_db_type_length }; 00621 handlerton *tmp_db_type= ha_resolve_by_name(thd, &name); 00622 if (tmp_db_type != NULL) 00623 { 00624 share->db_type= tmp_db_type; 00625 DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", 00626 str_db_type_length, next_chunk + 2, 00627 ha_legacy_type(share->db_type))); 00628 } 00629 #ifdef WITH_PARTITION_STORAGE_ENGINE 00630 else 00631 { 00632 if (!strncmp(next_chunk + 2, "partition", str_db_type_length)) 00633 { 00634 /* Use partition handler */ 00635 share->db_type= &partition_hton; 00636 DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", 00637 str_db_type_length, next_chunk + 2, 00638 ha_legacy_type(share->db_type))); 00639 } 00640 } 00641 #endif 00642 next_chunk+= str_db_type_length + 2; 00643 } 00644 if (next_chunk + 5 < buff_end) 00645 { 00646 uint32 partition_info_len = uint4korr(next_chunk); 00647 #ifdef WITH_PARTITION_STORAGE_ENGINE 00648 if ((share->partition_info_len= partition_info_len)) 00649 { 00650 if (!(share->partition_info= 00651 (uchar*) memdup_root(&share->mem_root, next_chunk + 4, 00652 partition_info_len + 1))) 00653 { 00654 my_free(buff, MYF(0)); 00655 goto err; 00656 } 00657 } 00658 #else 00659 if (partition_info_len) 00660 { 00661 DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined")); 00662 my_free(buff, MYF(0)); 00663 goto err; 00664 } 00665 #endif 00666 next_chunk+= 5 + partition_info_len; 00667 } 00668 #if MYSQL_VERSION_ID < 50200 00669 if (share->mysql_version >= 50106 && share->mysql_version <= 50109) 00670 { 00671 /* 00672 Partition state array was here in version 5.1.6 to 5.1.9, this code 00673 makes it possible to load a 5.1.6 table in later versions. Can most 00674 likely be removed at some point in time. Will only be used for 00675 upgrades within 5.1 series of versions. Upgrade to 5.2 can only be 00676 done from newer 5.1 versions. 00677 */ 00678 next_chunk+= 4; 00679 } 00680 else if (share->mysql_version >= 50110) 00681 #endif 00682 { 00683 /* New auto_partitioned indicator introduced in 5.1.11 */ 00684 #ifdef WITH_PARTITION_STORAGE_ENGINE 00685 share->auto_partitioned= *next_chunk; 00686 #endif 00687 next_chunk++; 00688 } 00689 keyinfo= share->key_info; 00690 for (i= 0; i < keys; i++, keyinfo++) 00691 { 00692 if (keyinfo->flags & HA_USES_PARSER) 00693 { 00694 LEX_STRING parser_name; 00695 if (next_chunk >= buff_end) 00696 { 00697 DBUG_PRINT("error", 00698 ("fulltext key uses parser that is not defined in .frm")); 00699 my_free(buff, MYF(0)); 00700 goto err; 00701 } 00702 parser_name.str= next_chunk; 00703 parser_name.length= strlen(next_chunk); 00704 keyinfo->parser= plugin_lock(&parser_name, MYSQL_FTPARSER_PLUGIN); 00705 if (! keyinfo->parser) 00706 { 00707 my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str); 00708 my_free(buff, MYF(0)); 00709 goto err; 00710 } 00711 } 00712 } 00713 my_free(buff, MYF(0)); 00714 } 00715 share->key_block_size= uint2korr(head+62); 00716 00717 error=4; 00718 extra_rec_buf_length= uint2korr(head+59); 00719 rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); 00720 share->rec_buff_length= rec_buff_length; 00721 if (!(record= (char *) alloc_root(&share->mem_root, 00722 rec_buff_length))) 00723 goto err; /* purecov: inspected */ 00724 share->default_values= (byte *) record; 00725 if (my_pread(file,(byte*) record, (uint) share->reclength, 00726 record_offset, MYF(MY_NABP))) 00727 goto err; /* purecov: inspected */ 00728 00729 VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); 00730 if (my_read(file,(byte*) head,288,MYF(MY_NABP))) 00731 goto err; 00732 #ifdef HAVE_CRYPTED_FRM 00733 if (crypted) 00734 { 00735 crypted->decode((char*) head+256,288-256); 00736 if (sint2korr(head+284) != 0) // Should be 0 00737 goto err; // Wrong password 00738 } 00739 #endif 00740 00741 share->fields= uint2korr(head+258); 00742 pos= uint2korr(head+260); /* Length of all screens */ 00743 n_length= uint2korr(head+268); 00744 interval_count= uint2korr(head+270); 00745 interval_parts= uint2korr(head+272); 00746 int_length= uint2korr(head+274); 00747 share->null_fields= uint2korr(head+282); 00748 com_length= uint2korr(head+284); 00749 share->comment.length= (int) (head[46]); 00750 share->comment.str= strmake_root(&share->mem_root, (char*) head+47, 00751 share->comment.length); 00752 00753 DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length)); 00754 00755 if (!(field_ptr = (Field **) 00756 alloc_root(&share->mem_root, 00757 (uint) ((share->fields+1)*sizeof(Field*)+ 00758 interval_count*sizeof(TYPELIB)+ 00759 (share->fields+interval_parts+ 00760 keys+3)*sizeof(my_string)+ 00761 (n_length+int_length+com_length))))) 00762 goto err; /* purecov: inspected */ 00763 00764 share->field= field_ptr; 00765 read_length=(uint) (share->fields * field_pack_length + 00766 pos+ (uint) (n_length+int_length+com_length)); 00767 if (read_string(file,(gptr*) &disk_buff,read_length)) 00768 goto err; /* purecov: inspected */ 00769 #ifdef HAVE_CRYPTED_FRM 00770 if (crypted) 00771 { 00772 crypted->decode((char*) disk_buff,read_length); 00773 delete crypted; 00774 crypted=0; 00775 } 00776 #endif 00777 strpos= disk_buff+pos; 00778 00779 share->intervals= (TYPELIB*) (field_ptr+share->fields+1); 00780 interval_array= (const char **) (share->intervals+interval_count); 00781 names= (char*) (interval_array+share->fields+interval_parts+keys+3); 00782 if (!interval_count) 00783 share->intervals= 0; // For better debugging 00784 memcpy((char*) names, strpos+(share->fields*field_pack_length), 00785 (uint) (n_length+int_length)); 00786 comment_pos= names+(n_length+int_length); 00787 memcpy(comment_pos, disk_buff+read_length-com_length, com_length); 00788 00789 fix_type_pointers(&interval_array, &share->fieldnames, 1, &names); 00790 fix_type_pointers(&interval_array, share->intervals, interval_count, 00791 &names); 00792 00793 { 00794 /* Set ENUM and SET lengths */ 00795 TYPELIB *interval; 00796 for (interval= share->intervals; 00797 interval < share->intervals + interval_count; 00798 interval++) 00799 { 00800 uint count= (uint) (interval->count + 1) * sizeof(uint); 00801 if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root, 00802 count))) 00803 goto err; 00804 for (count= 0; count < interval->count; count++) 00805 interval->type_lengths[count]= strlen(interval->type_names[count]); 00806 interval->type_lengths[count]= 0; 00807 } 00808 } 00809 00810 if (keynames) 00811 fix_type_pointers(&interval_array, &share->keynames, 1, &keynames); 00812 00813 /* Allocate handler */ 00814 if (!(handler_file= get_new_handler(share, thd->mem_root, 00815 share->db_type))) 00816 goto err; 00817 00818 record= (char*) share->default_values-1; /* Fieldstart = 1 */ 00819 if (share->null_field_first) 00820 { 00821 null_flags= null_pos= (uchar*) record+1; 00822 null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1; 00823 /* 00824 null_bytes below is only correct under the condition that 00825 there are no bit fields. Correct values is set below after the 00826 table struct is initialized 00827 */ 00828 share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8; 00829 } 00830 #ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES 00831 else 00832 { 00833 share->null_bytes= (share->null_fields+7)/8; 00834 null_flags= null_pos= (uchar*) (record + 1 +share->reclength - 00835 share->null_bytes); 00836 null_bit_pos= 0; 00837 } 00838 #endif 00839 00840 use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH; 00841 if (use_hash) 00842 use_hash= !hash_init(&share->name_hash, 00843 system_charset_info, 00844 share->fields,0,0, 00845 (hash_get_key) get_field_name,0,0); 00846 00847 for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++) 00848 { 00849 uint pack_flag, interval_nr, unireg_type, recpos, field_length; 00850 enum_field_types field_type; 00851 CHARSET_INFO *charset=NULL; 00852 Field::geometry_type geom_type= Field::GEOM_GEOMETRY; 00853 LEX_STRING comment; 00854 00855 if (new_frm_ver >= 3) 00856 { 00857 /* new frm file in 4.1 */ 00858 field_length= uint2korr(strpos+3); 00859 recpos= uint3korr(strpos+5); 00860 pack_flag= uint2korr(strpos+8); 00861 unireg_type= (uint) strpos[10]; 00862 interval_nr= (uint) strpos[12]; 00863 uint comment_length=uint2korr(strpos+15); 00864 field_type=(enum_field_types) (uint) strpos[13]; 00865 00866 /* charset and geometry_type share the same byte in frm */ 00867 if (field_type == FIELD_TYPE_GEOMETRY) 00868 { 00869 #ifdef HAVE_SPATIAL 00870 geom_type= (Field::geometry_type) strpos[14]; 00871 charset= &my_charset_bin; 00872 #else 00873 error= 4; // unsupported field type 00874 goto err; 00875 #endif 00876 } 00877 else 00878 { 00879 if (!strpos[14]) 00880 charset= &my_charset_bin; 00881 else if (!(charset=get_charset((uint) strpos[14], MYF(0)))) 00882 { 00883 error= 5; // Unknown or unavailable charset 00884 errarg= (int) strpos[14]; 00885 goto err; 00886 } 00887 } 00888 if (!comment_length) 00889 { 00890 comment.str= (char*) ""; 00891 comment.length=0; 00892 } 00893 else 00894 { 00895 comment.str= (char*) comment_pos; 00896 comment.length= comment_length; 00897 comment_pos+= comment_length; 00898 } 00899 } 00900 else 00901 { 00902 field_length= (uint) strpos[3]; 00903 recpos= uint2korr(strpos+4), 00904 pack_flag= uint2korr(strpos+6); 00905 pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files 00906 unireg_type= (uint) strpos[8]; 00907 interval_nr= (uint) strpos[10]; 00908 00909 /* old frm file */ 00910 field_type= (enum_field_types) f_packtype(pack_flag); 00911 if (f_is_binary(pack_flag)) 00912 { 00913 /* 00914 Try to choose the best 4.1 type: 00915 - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 00916 try to find a binary collation for character set. 00917 - for other types (e.g. BLOB) just use my_charset_bin. 00918 */ 00919 if (!f_is_blob(pack_flag)) 00920 { 00921 // 3.23 or 4.0 string 00922 if (!(charset= get_charset_by_csname(share->table_charset->csname, 00923 MY_CS_BINSORT, MYF(0)))) 00924 charset= &my_charset_bin; 00925 } 00926 else 00927 charset= &my_charset_bin; 00928 } 00929 else 00930 charset= share->table_charset; 00931 bzero((char*) &comment, sizeof(comment)); 00932 } 00933 00934 if (interval_nr && charset->mbminlen > 1) 00935 { 00936 /* Unescape UCS2 intervals from HEX notation */ 00937 TYPELIB *interval= share->intervals + interval_nr - 1; 00938 unhex_type2(interval); 00939 } 00940 00941 #ifndef TO_BE_DELETED_ON_PRODUCTION 00942 if (field_type == FIELD_TYPE_NEWDECIMAL && !share->mysql_version) 00943 { 00944 /* 00945 Fix pack length of old decimal values from 5.0.3 -> 5.0.4 00946 The difference is that in the old version we stored precision 00947 in the .frm table while we now store the display_length 00948 */ 00949 uint decimals= f_decimals(pack_flag); 00950 field_length= my_decimal_precision_to_length(field_length, 00951 decimals, 00952 f_is_dec(pack_flag) == 0); 00953 sql_print_error("Found incompatible DECIMAL field '%s' in %s; " 00954 "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", 00955 share->fieldnames.type_names[i], share->table_name.str, 00956 share->table_name.str); 00957 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, 00958 ER_CRASHED_ON_USAGE, 00959 "Found incompatible DECIMAL field '%s' in %s; " 00960 "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", 00961 share->fieldnames.type_names[i], 00962 share->table_name.str, 00963 share->table_name.str); 00964 share->crashed= 1; // Marker for CHECK TABLE 00965 } 00966 #endif 00967 00968 *field_ptr= reg_field= 00969 make_field(share, record+recpos, 00970 (uint32) field_length, 00971 null_pos, null_bit_pos, 00972 pack_flag, 00973 field_type, 00974 charset, 00975 geom_type, 00976 (Field::utype) MTYP_TYPENR(unireg_type), 00977 (interval_nr ? 00978 share->intervals+interval_nr-1 : 00979 (TYPELIB*) 0), 00980 share->fieldnames.type_names[i]); 00981 if (!reg_field) // Not supported field type 00982 { 00983 error= 4; 00984 goto err; /* purecov: inspected */ 00985 } 00986 00987 reg_field->field_index= i; 00988 reg_field->comment=comment; 00989 if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) 00990 { 00991 if ((null_bit_pos+= field_length & 7) > 7) 00992 { 00993 null_pos++; 00994 null_bit_pos-= 8; 00995 } 00996 } 00997 if (!(reg_field->flags & NOT_NULL_FLAG)) 00998 { 00999 if (!(null_bit_pos= (null_bit_pos + 1) & 7)) 01000 null_pos++; 01001 } 01002 if (f_no_default(pack_flag)) 01003 reg_field->flags|= NO_DEFAULT_VALUE_FLAG; 01004 01005 if (reg_field->unireg_check == Field::NEXT_NUMBER) 01006 share->found_next_number_field= field_ptr; 01007 if (share->timestamp_field == reg_field) 01008 share->timestamp_field_offset= i; 01009 01010 if (use_hash) 01011 (void) my_hash_insert(&share->name_hash, 01012 (byte*) field_ptr); // never fail 01013 } 01014 *field_ptr=0; // End marker 01015 01016 /* Fix key->name and key_part->field */ 01017 if (key_parts) 01018 { 01019 uint primary_key=(uint) (find_type((char*) primary_key_name, 01020 &share->keynames, 3) - 1); 01021 uint ha_option= handler_file->ha_table_flags(); 01022 keyinfo= share->key_info; 01023 key_part= keyinfo->key_part; 01024 01025 for (uint key=0 ; key < share->keys ; key++,keyinfo++) 01026 { 01027 uint usable_parts= 0; 01028 keyinfo->name=(char*) share->keynames.type_names[key]; 01029 /* Fix fulltext keys for old .frm files */ 01030 if (share->key_info[key].flags & HA_FULLTEXT) 01031 share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; 01032 01033 if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) 01034 { 01035 /* 01036 If the UNIQUE key doesn't have NULL columns and is not a part key 01037 declare this as a primary key. 01038 */ 01039 primary_key=key; 01040 for (i=0 ; i < keyinfo->key_parts ;i++) 01041 { 01042 uint fieldnr= key_part[i].fieldnr; 01043 if (!fieldnr || 01044 share->field[fieldnr-1]->null_ptr || 01045 share->field[fieldnr-1]->key_length() != 01046 key_part[i].length) 01047 { 01048 primary_key=MAX_KEY; // Can't be used 01049 break; 01050 } 01051 } 01052 } 01053 01054 for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) 01055 { 01056 Field *field; 01057 if (new_field_pack_flag <= 1) 01058 key_part->fieldnr= (uint16) find_field(share->field, 01059 (uint) key_part->offset, 01060 (uint) key_part->length); 01061 if (!key_part->fieldnr) 01062 { 01063 error= 4; // Wrong file 01064 goto err; 01065 } 01066 field= key_part->field= share->field[key_part->fieldnr-1]; 01067 if (field->null_ptr) 01068 { 01069 key_part->null_offset=(uint) ((byte*) field->null_ptr - 01070 share->default_values); 01071 key_part->null_bit= field->null_bit; 01072 key_part->store_length+=HA_KEY_NULL_LENGTH; 01073 keyinfo->flags|=HA_NULL_PART_KEY; 01074 keyinfo->extra_length+= HA_KEY_NULL_LENGTH; 01075 keyinfo->key_length+= HA_KEY_NULL_LENGTH; 01076 } 01077 if (field->type() == FIELD_TYPE_BLOB || 01078 field->real_type() == MYSQL_TYPE_VARCHAR) 01079 { 01080 if (field->type() == FIELD_TYPE_BLOB) 01081 key_part->key_part_flag|= HA_BLOB_PART; 01082 else 01083 key_part->key_part_flag|= HA_VAR_LENGTH_PART; 01084 keyinfo->extra_length+=HA_KEY_BLOB_LENGTH; 01085 key_part->store_length+=HA_KEY_BLOB_LENGTH; 01086 keyinfo->key_length+= HA_KEY_BLOB_LENGTH; 01087 /* 01088 Mark that there may be many matching values for one key 01089 combination ('a', 'a ', 'a '...) 01090 */ 01091 if (!(field->flags & BINARY_FLAG)) 01092 keyinfo->flags|= HA_END_SPACE_KEY; 01093 } 01094 if (field->type() == MYSQL_TYPE_BIT) 01095 key_part->key_part_flag|= HA_BIT_PART; 01096 01097 if (i == 0 && key != primary_key) 01098 field->flags |= (((keyinfo->flags & HA_NOSAME) && 01099 (keyinfo->key_parts == 1)) ? 01100 UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); 01101 if (i == 0) 01102 field->key_start.set_bit(key); 01103 if (field->key_length() == key_part->length && 01104 !(field->flags & BLOB_FLAG)) 01105 { 01106 if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY) 01107 { 01108 share->keys_for_keyread.set_bit(key); 01109 field->part_of_key.set_bit(key); 01110 field->part_of_key_not_clustered.set_bit(key); 01111 } 01112 if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER) 01113 field->part_of_sortkey.set_bit(key); 01114 } 01115 if (!(key_part->key_part_flag & HA_REVERSE_SORT) && 01116 usable_parts == i) 01117 usable_parts++; // For FILESORT 01118 field->flags|= PART_KEY_FLAG; 01119 if (key == primary_key) 01120 { 01121 field->flags|= PRI_KEY_FLAG; 01122 /* 01123 If this field is part of the primary key and all keys contains 01124 the primary key, then we can use any key to find this column 01125 */ 01126 if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX) 01127 field->part_of_key= share->keys_in_use; 01128 } 01129 if (field->key_length() != key_part->length) 01130 { 01131 #ifndef TO_BE_DELETED_ON_PRODUCTION 01132 if (field->type() == FIELD_TYPE_NEWDECIMAL) 01133 { 01134 /* 01135 Fix a fatal error in decimal key handling that causes crashes 01136 on Innodb. We fix it by reducing the key length so that 01137 InnoDB never gets a too big key when searching. 01138 This allows the end user to do an ALTER TABLE to fix the 01139 error. 01140 */ 01141 keyinfo->key_length-= (key_part->length - field->key_length()); 01142 key_part->store_length-= (uint16)(key_part->length - 01143 field->key_length()); 01144 key_part->length= (uint16)field->key_length(); 01145 sql_print_error("Found wrong key definition in %s; " 01146 "Please do \"ALTER TABLE '%s' FORCE \" to fix it!", 01147 share->table_name.str, 01148 share->table_name.str); 01149 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, 01150 ER_CRASHED_ON_USAGE, 01151 "Found wrong key definition in %s; " 01152 "Please do \"ALTER TABLE '%s' FORCE\" to fix " 01153 "it!", 01154 share->table_name.str, 01155 share->table_name.str); 01156 share->crashed= 1; // Marker for CHECK TABLE 01157 goto to_be_deleted; 01158 } 01159 #endif 01160 key_part->key_part_flag|= HA_PART_KEY_SEG; 01161 } 01162 01163 to_be_deleted: 01164 01165 /* 01166 If the field can be NULL, don't optimize away the test 01167 key_part_column = expression from the WHERE clause 01168 as we need to test for NULL = NULL. 01169 */ 01170 if (field->real_maybe_null()) 01171 key_part->key_part_flag|= HA_PART_KEY_SEG; 01172 } 01173 keyinfo->usable_key_parts= usable_parts; // Filesort 01174 01175 set_if_bigger(share->max_key_length,keyinfo->key_length+ 01176 keyinfo->key_parts); 01177 share->total_key_length+= keyinfo->key_length; 01178 /* 01179 MERGE tables do not have unique indexes. But every key could be 01180 an unique index on the underlying MyISAM table. (Bug #10400) 01181 */ 01182 if ((keyinfo->flags & HA_NOSAME) || 01183 (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE)) 01184 set_if_bigger(share->max_unique_length,keyinfo->key_length); 01185 } 01186 if (primary_key < MAX_KEY && 01187 (share->keys_in_use.is_set(primary_key))) 01188 { 01189 share->primary_key= primary_key; 01190 /* 01191 If we are using an integer as the primary key then allow the user to 01192 refer to it as '_rowid' 01193 */ 01194 if (share->key_info[primary_key].key_parts == 1) 01195 { 01196 Field *field= share->key_info[primary_key].key_part[0].field; 01197 if (field && field->result_type() == INT_RESULT) 01198 { 01199 /* note that fieldnr here (and rowid_field_offset) starts from 1 */ 01200 share->rowid_field_offset= (share->key_info[primary_key].key_part[0]. 01201 fieldnr); 01202 } 01203 } 01204 } 01205 else 01206 share->primary_key = MAX_KEY; // we do not have a primary key 01207 } 01208 else 01209 share->primary_key= MAX_KEY; 01210 x_free((gptr) disk_buff); 01211 disk_buff=0; 01212 if (new_field_pack_flag <= 1) 01213 { 01214 /* Old file format with default as not null */ 01215 uint null_length= (share->null_fields+7)/8; 01216 bfill(share->default_values + (null_flags - (uchar*) record), 01217 null_length, 255); 01218 } 01219 01220 if (share->found_next_number_field) 01221 { 01222 /* 01223 We must have a table object for find_ref_key to calculate field offset 01224 */ 01225 TABLE tmp_table; 01226 tmp_table.record[0]= share->default_values; 01227 01228 reg_field= *share->found_next_number_field; 01229 reg_field->table= &tmp_table; 01230 if ((int) (share->next_number_index= (uint) 01231 find_ref_key(share->key_info, share->keys, reg_field, 01232 &share->next_number_key_offset)) < 0) 01233 { 01234 reg_field->unireg_check= Field::NONE; /* purecov: inspected */ 01235 share->found_next_number_field= 0; 01236 } 01237 else 01238 reg_field->flags |= AUTO_INCREMENT_FLAG; 01239 reg_field->table= 0; 01240 } 01241 01242 if (share->blob_fields) 01243 { 01244 Field **ptr; 01245 uint i, *save; 01246 01247 /* Store offsets to blob fields to find them fast */ 01248 if (!(share->blob_field= save= 01249 (uint*) alloc_root(&share->mem_root, 01250 (uint) (share->blob_fields* sizeof(uint))))) 01251 goto err; 01252 for (i=0, ptr= share->field ; *ptr ; ptr++, i++) 01253 { 01254 if ((*ptr)->flags & BLOB_FLAG) 01255 (*save++)= i; 01256 } 01257 } 01258 01259 /* 01260 the correct null_bytes can now be set, since bitfields have been taken 01261 into account 01262 */ 01263 share->null_bytes= (null_pos - (uchar*) null_flags + 01264 (null_bit_pos + 7) / 8); 01265 share->last_null_bit_pos= null_bit_pos; 01266 01267 share->db_low_byte_first= handler_file->low_byte_first(); 01268 share->column_bitmap_size= bitmap_buffer_size(share->fields); 01269 01270 if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root, 01271 share->column_bitmap_size))) 01272 goto err; 01273 bitmap_init(&share->all_set, bitmaps, share->fields, FALSE); 01274 bitmap_set_all(&share->all_set); 01275 01276 delete handler_file; 01277 #ifndef DBUG_OFF 01278 if (use_hash) 01279 (void) hash_check(&share->name_hash); 01280 #endif 01281 DBUG_RETURN (0); 01282 01283 err: 01284 share->error= error; 01285 share->open_errno= my_errno; 01286 share->errarg= errarg; 01287 x_free((gptr) disk_buff); 01288 delete crypted; 01289 delete handler_file; 01290 hash_free(&share->name_hash); 01291 01292 open_table_error(share, error, share->open_errno, errarg); 01293 DBUG_RETURN(error); 01294 } /* open_binary_frm */
Here is the call graph for this function:

Here is the caller graph for this function:

| int open_table_def | ( | THD * | thd, | |
| TABLE_SHARE * | share, | |||
| uint | db_flags | |||
| ) |
Definition at line 280 of file table.cc.
References st_table_share::db, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, err, st_table_share::error, error, FN_REFLEN, FRM_VER, st_table_share::is_view, LEX_STRING::length, st_table_share::log_table, st_table_share::mem_root, memcmp(), my_close(), my_errno, MY_NABP, my_open(), my_pthread_getspecific_ptr, my_read, my_strcasecmp, MY_WME, MYF, mysql_data_home, st_table_share::normalized_path, NULL, NullS, O_SHARE, open_binary_frm(), st_table_share::open_errno, open_table_error(), OPEN_VIEW, path, QUERY_LOG_GENERAL, QUERY_LOG_SLOW, reg_ext, reg_ext_length, LEX_STRING::str, strchr(), STRING_WITH_LEN, strmov(), strxmov(), strxnmov(), system_charset_info, st_table_share::system_table, st_table_share::table_name, and unpack_filename().
Referenced by get_table_share(), ha_create_table(), ha_create_table_from_engine(), and open_temporary_table().
00281 { 00282 int error, table_type; 00283 bool error_given; 00284 File file; 00285 uchar head[288], *disk_buff; 00286 char path[FN_REFLEN]; 00287 MEM_ROOT **root_ptr, *old_root; 00288 DBUG_ENTER("open_table_def"); 00289 DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, 00290 share->table_name.str, share->normalized_path.str)); 00291 00292 error= 1; 00293 error_given= 0; 00294 disk_buff= NULL; 00295 00296 strxmov(path, share->normalized_path.str, reg_ext, NullS); 00297 if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) 00298 { 00299 if (strchr(share->table_name.str, '@')) 00300 goto err_not_open; 00301 00302 /* Try unecoded 5.0 name */ 00303 uint length; 00304 strxnmov(path, sizeof(path)-1, 00305 mysql_data_home, "/", share->db.str, "/", 00306 share->table_name.str, reg_ext, NullS); 00307 length= unpack_filename(path, path) - reg_ext_length; 00308 /* 00309 The following is a safety test and should never fail 00310 as the old file name should never be longer than the new one. 00311 */ 00312 DBUG_ASSERT(length <= share->normalized_path.length); 00313 /* 00314 If the old and the new names have the same length, 00315 then table name does not have tricky characters, 00316 so no need to check the old file name. 00317 */ 00318 if (length == share->normalized_path.length || 00319 ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)) 00320 goto err_not_open; 00321 00322 /* Unencoded 5.0 table name found */ 00323 path[length]= '\0'; // Remove .frm extension 00324 strmov(share->normalized_path.str, path); 00325 share->normalized_path.length= length; 00326 } 00327 00328 error= 4; 00329 if (my_read(file,(byte*) head, 64, MYF(MY_NABP))) 00330 goto err; 00331 00332 if (head[0] == (uchar) 254 && head[1] == 1) 00333 { 00334 if (head[2] == FRM_VER || head[2] == FRM_VER+1 || 00335 (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) 00336 table_type= 1; 00337 else 00338 { 00339 error= 6; // Unkown .frm version 00340 goto err; 00341 } 00342 } 00343 else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0) 00344 { 00345 error= 5; 00346 if (memcmp(head+5,"VIEW",4) == 0) 00347 { 00348 share->is_view= 1; 00349 if (db_flags & OPEN_VIEW) 00350 error= 0; 00351 } 00352 goto err; 00353 } 00354 else 00355 goto err; 00356 00357 /* No handling of text based files yet */ 00358 if (table_type == 1) 00359 { 00360 root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); 00361 old_root= *root_ptr; 00362 *root_ptr= &share->mem_root; 00363 error= open_binary_frm(thd, share, head, file); 00364 *root_ptr= old_root; 00365 00366 if (share->db.length == 5 && 00367 !my_strcasecmp(system_charset_info, share->db.str, "mysql")) 00368 { 00369 /* 00370 We can't mark all tables in 'mysql' database as system since we don't 00371 allow to lock such tables for writing with any other tables (even with 00372 other system tables) and some privilege tables need this. 00373 */ 00374 if (!my_strcasecmp(system_charset_info, share->table_name.str, "proc")) 00375 share->system_table= 1; 00376 else 00377 { 00378 if (!my_strcasecmp(system_charset_info, share->table_name.str, 00379 "general_log")) 00380 share->log_table= QUERY_LOG_GENERAL; 00381 else 00382 if (!my_strcasecmp(system_charset_info, share->table_name.str, 00383 "slow_log")) 00384 share->log_table= QUERY_LOG_SLOW; 00385 } 00386 } 00387 error_given= 1; 00388 } 00389 00390 if (!error) 00391 thd->status_var.opened_shares++; 00392 00393 err: 00394 my_close(file, MYF(MY_WME)); 00395 00396 err_not_open: 00397 if (error && !error_given) 00398 { 00399 share->error= error; 00400 open_table_error(share, error, (share->open_errno= my_errno), 0); 00401 } 00402 00403 DBUG_RETURN(error); 00404 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void open_table_error | ( | TABLE_SHARE * | share, | |
| int | error, | |||
| int | db_errno, | |||
| int | errarg | |||
| ) |
Definition at line 1796 of file table.cc.
References handler::bas_ext(), current_thd, st_table_share::db, st_table_share::db_type, DBUG_ENTER, DBUG_VOID_RETURN, ER_CANT_OPEN_FILE, ER_FILE_NOT_FOUND, ER_FILE_USED, ER_NO_SUCH_TABLE, ER_NOT_FORM_FILE, ER_UNKNOWN_COLLATION, FN_REFLEN, get_charset_name(), get_new_handler(), ME_ERROR, ME_WAITTANG, my_error(), my_printf_error(), my_snprintf(), MYF, st_table_share::normalized_path, NULL, NullS, reg_ext, LEX_STRING::str, strxmov(), and st_table_share::table_name.
01797 { 01798 int err_no; 01799 char buff[FN_REFLEN]; 01800 myf errortype= ME_ERROR+ME_WAITTANG; 01801 DBUG_ENTER("open_table_error"); 01802 01803 switch (error) { 01804 case 7: 01805 case 1: 01806 if (db_errno == ENOENT) 01807 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str); 01808 else 01809 { 01810 strxmov(buff, share->normalized_path.str, reg_ext, NullS); 01811 my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND, 01812 errortype, buff, db_errno); 01813 } 01814 break; 01815 case 2: 01816 { 01817 handler *file= 0; 01818 const char *datext= ""; 01819 01820 if (share->db_type != NULL) 01821 { 01822 if ((file= get_new_handler(share, current_thd->mem_root, 01823 share->db_type))) 01824 { 01825 if (!(datext= *file->bas_ext())) 01826 datext= ""; 01827 } 01828 } 01829 err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ? 01830 ER_FILE_USED : ER_CANT_OPEN_FILE; 01831 strxmov(buff, share->normalized_path.str, datext, NullS); 01832 my_error(err_no,errortype, buff, db_errno); 01833 delete file; 01834 break; 01835 } 01836 case 5: 01837 { 01838 const char *csname= get_charset_name((uint) errarg); 01839 char tmp[10]; 01840 if (!csname || csname[0] =='?') 01841 { 01842 my_snprintf(tmp, sizeof(tmp), "#%d", errarg); 01843 csname= tmp; 01844 } 01845 my_printf_error(ER_UNKNOWN_COLLATION, 01846 "Unknown collation '%s' in table '%-.64s' definition", 01847 MYF(0), csname, share->table_name.str); 01848 break; 01849 } 01850 case 6: 01851 strxmov(buff, share->normalized_path.str, reg_ext, NullS); 01852 my_printf_error(ER_NOT_FORM_FILE, 01853 "Table '%-.64s' was created with a different version " 01854 "of MySQL and cannot be read", 01855 MYF(0), buff); 01856 break; 01857 default: /* Better wrong error than none */ 01858 case 4: 01859 strxmov(buff, share->normalized_path.str, reg_ext, NullS); 01860 my_error(ER_NOT_FORM_FILE, errortype, buff, 0); 01861 break; 01862 } 01863 DBUG_VOID_RETURN; 01864 } /* open_table_error */
Here is the call graph for this function:

| void open_table_error | ( | TABLE_SHARE * | share, | |
| int | error, | |||
| int | db_errno, | |||
| myf | errortype, | |||
| int | errarg | |||
| ) |
Referenced by get_table_share(), open_table_def(), and open_table_from_share().
Here is the caller graph for this function:

| int open_table_from_share | ( | THD * | thd, | |
| TABLE_SHARE * | share, | |||
| const char * | alias, | |||
| uint | db_stat, | |||
| uint | prgflag, | |||
| uint | ha_open_flags, | |||
| TABLE * | outparam, | |||
| bool | is_create_table | |||
| ) |
Definition at line 1322 of file table.cc.
References alloc_root(), bitmap_init(), BLOB_FLAG, bzero, Field::clone(), st_table_share::column_bitmap_size, st_table_share::crashed, st_table_share::db, st_table_share::db_type, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table_share::default_values, DELAYED_OPEN, err, error, EXTRA_RECORD, F_UNLCK, FALSE, st_table_share::field, Field::field_length, st_table_share::fields, fix_partition_func(), Field::flags, st_table_share::found_next_number_field, free_items(), free_root(), get_new_handler(), HA_ABORT_IF_LOCKED, HA_ERR_CRASHED_ON_USAGE, HA_ERR_NO_SUCH_TABLE, HA_ERR_TABLE_DEF_CHANGED, HA_GET_INFO, HA_OPEN_ABORT_IF_LOCKED, HA_OPEN_FOR_REPAIR, HA_OPEN_IGNORE_IF_LOCKED, HA_OPEN_KEYFILE, HA_OPEN_TEMPORARY, HA_OPEN_TMP_TABLE, HA_OPEN_WAIT_IF_LOCKED, HA_READ_ONLY, HA_WAIT_IF_LOCKED, init_sql_alloc(), st_table_share::key_info, Field::key_length(), st_key::key_part, st_table_share::key_parts, st_table_share::keys, st_table_share::mem_root, memcpy, MY_ALLOW_ZERO_PTR, my_errno, my_free, my_pthread_getspecific_ptr, my_reinterpret_cast, my_strdup(), MY_WME, MYF, mysql_unpack_partition(), Field::new_field(), st_table_share::normalized_path, NULL, st_table_share::null_bytes, st_table_share::null_field_first, open_table_error(), READ_ALL, st_table_share::rec_buff_length, st_table_share::reclength, records, SPECIAL_WAIT_IF_LOCKED, specialflag, LEX_STRING::str, TABLE_ALLOC_BLOCK_SIZE, st_table_share::table_name, st_table_share::timestamp_field, st_table_share::timestamp_field_offset, TL_UNLOCK, and TRUE.
Referenced by ha_create_table(), ha_create_table_from_engine(), open_temporary_table(), open_unireg_entry(), and prepare_for_repair().
01325 { 01326 int error; 01327 uint records, i, bitmap_size; 01328 bool error_reported= FALSE; 01329 byte *record, *bitmaps; 01330 Field **field_ptr; 01331 DBUG_ENTER("open_table_from_share"); 01332 DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str, 01333 share->table_name.str, outparam)); 01334 01335 error= 1; 01336 bzero((char*) outparam, sizeof(*outparam)); 01337 outparam->in_use= thd; 01338 outparam->s= share; 01339 outparam->db_stat= db_stat; 01340 outparam->write_row_record= NULL; 01341 01342 init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 01343 01344 if (!(outparam->alias= my_strdup(alias, MYF(MY_WME)))) 01345 goto err; 01346 outparam->quick_keys.init(); 01347 outparam->used_keys.init(); 01348 outparam->keys_in_use_for_query.init(); 01349 01350 /* Allocate handler */ 01351 if (!(outparam->file= get_new_handler(share, &outparam->mem_root, 01352 share->db_type))) 01353 goto err; 01354 01355 error= 4; 01356 outparam->reginfo.lock_type= TL_UNLOCK; 01357 outparam->current_lock= F_UNLCK; 01358 records=0; 01359 if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN)) 01360 records=1; 01361 if (prgflag & (READ_ALL+EXTRA_RECORD)) 01362 records++; 01363 01364 if (!(record= (byte*) alloc_root(&outparam->mem_root, 01365 share->rec_buff_length * records))) 01366 goto err; /* purecov: inspected */ 01367 01368 if (records == 0) 01369 { 01370 /* We are probably in hard repair, and the buffers should not be used */ 01371 outparam->record[0]= outparam->record[1]= share->default_values; 01372 } 01373 else 01374 { 01375 outparam->record[0]= record; 01376 if (records > 1) 01377 outparam->record[1]= record+ share->rec_buff_length; 01378 else 01379 outparam->record[1]= outparam->record[0]; // Safety 01380 } 01381 01382 #ifdef HAVE_purify 01383 /* 01384 We need this because when we read var-length rows, we are not updating 01385 bytes after end of varchar 01386 */ 01387 if (records > 1) 01388 { 01389 memcpy(outparam->record[0], share->default_values, share->rec_buff_length); 01390 if (records > 2) 01391 memcpy(outparam->record[1], share->default_values, 01392 share->rec_buff_length); 01393 } 01394 #endif 01395 01396 if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, 01397 (uint) ((share->fields+1)* 01398 sizeof(Field*))))) 01399 goto err; /* purecov: inspected */ 01400 01401 outparam->field= field_ptr; 01402 01403 record= (byte*) outparam->record[0]-1; /* Fieldstart = 1 */ 01404 if (share->null_field_first) 01405 outparam->null_flags= (uchar*) record+1; 01406 else 01407 outparam->null_flags= (uchar*) (record+ 1+ share->reclength - 01408 share->null_bytes); 01409 01410 /* Setup copy of fields from share, but use the right alias and record */ 01411 for (i=0 ; i < share->fields; i++, field_ptr++) 01412 { 01413 if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam))) 01414 goto err; 01415 } 01416 (*field_ptr)= 0; // End marker 01417 01418 if (share->found_next_number_field) 01419 outparam->found_next_number_field= 01420 outparam->field[(uint) (share->found_next_number_field - share->field)]; 01421 if (share->timestamp_field) 01422 outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset]; 01423 01424 01425 /* Fix key->name and key_part->field */ 01426 if (share->key_parts) 01427 { 01428 KEY *key_info, *key_info_end; 01429 KEY_PART_INFO *key_part; 01430 uint n_length; 01431 n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO); 01432 if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length))) 01433 goto err; 01434 outparam->key_info= key_info; 01435 key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys)); 01436 01437 memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys); 01438 memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) * 01439 share->key_parts)); 01440 01441 for (key_info_end= key_info + share->keys ; 01442 key_info < key_info_end ; 01443 key_info++) 01444 { 01445 KEY_PART_INFO *key_part_end; 01446 01447 key_info->table= outparam; 01448 key_info->key_part= key_part; 01449 01450 for (key_part_end= key_part+ key_info->key_parts ; 01451 key_part < key_part_end ; 01452 key_part++) 01453 { 01454 Field *field= key_part->field= outparam->field[key_part->fieldnr-1]; 01455 01456 if (field->key_length() != key_part->length && 01457 !(field->flags & BLOB_FLAG)) 01458 { 01459 /* 01460 We are using only a prefix of the column as a key: 01461 Create a new field for the key part that matches the index 01462 */ 01463 field= key_part->field=field->new_field(&outparam->mem_root, 01464 outparam, 0); 01465 field->field_length= key_part->length; 01466 } 01467 } 01468 } 01469 } 01470 01471 #ifdef WITH_PARTITION_STORAGE_ENGINE 01472 if (share->partition_info_len) 01473 { 01474 MEM_ROOT **root_ptr, *old_root; 01475 bool tmp; 01476 root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); 01477 old_root= *root_ptr; 01478 *root_ptr= &outparam->mem_root; 01479 01480 tmp= mysql_unpack_partition(thd, share->partition_info, 01481 share->partition_info_len, 01482 (uchar*)share->part_state, 01483 share->part_state_len, 01484 outparam, is_create_table, 01485 share->default_part_db_type); 01486 outparam->part_info->is_auto_partitioned= share->auto_partitioned; 01487 DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned)); 01488 if (!tmp) 01489 tmp= fix_partition_func(thd, outparam, is_create_table); 01490 *root_ptr= old_root; 01491 if (tmp) 01492 { 01493 if (is_create_table) 01494 { 01495 /* 01496 During CREATE/ALTER TABLE it is ok to receive errors here. 01497 It is not ok if it happens during the opening of an frm 01498 file as part of a normal query. 01499 */ 01500 error_reported= TRUE; 01501 } 01502 goto err; 01503 } 01504 } 01505 #endif 01506 01507 /* Allocate bitmaps */ 01508 01509 bitmap_size= share->column_bitmap_size; 01510 if (!(bitmaps= (byte*) alloc_root(&outparam->mem_root, bitmap_size*3))) 01511 goto err; 01512 bitmap_init(&outparam->def_read_set, 01513 (my_bitmap_map*) bitmaps, share->fields, FALSE); 01514 bitmap_init(&outparam->def_write_set, 01515 (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE); 01516 bitmap_init(&outparam->tmp_set, 01517 (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE); 01518 outparam->default_column_bitmaps(); 01519 01520 /* The table struct is now initialized; Open the table */ 01521 error= 2; 01522 if (db_stat) 01523 { 01524 int ha_err; 01525 if ((ha_err= (outparam->file-> 01526 ha_open(outparam, share->normalized_path.str, 01527 (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), 01528 (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : 01529 ((db_stat & HA_WAIT_IF_LOCKED) || 01530 (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? 01531 HA_OPEN_WAIT_IF_LOCKED : 01532 (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? 01533 HA_OPEN_ABORT_IF_LOCKED : 01534 HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) 01535 { 01536 /* Set a flag if the table is crashed and it can be auto. repaired */ 01537 share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) && 01538 outparam->file->auto_repair() && 01539 !(ha_open_flags & HA_OPEN_FOR_REPAIR)); 01540 01541 if (ha_err == HA_ERR_NO_SUCH_TABLE) 01542 { 01543 /* 01544 The table did not exists in storage engine, use same error message 01545 as if the .frm file didn't exist 01546 */ 01547 error= 1; 01548 my_errno= ENOENT; 01549 } 01550 else 01551 { 01552 outparam->file->print_error(ha_err, MYF(0)); 01553 error_reported= TRUE; 01554 if (ha_err == HA_ERR_TABLE_DEF_CHANGED) 01555 error= 7; 01556 } 01557 goto err; /* purecov: inspected */ 01558 } 01559 } 01560 01561 #if defined(HAVE_purify) && !defined(DBUG_OFF) 01562 bzero((char*) bitmaps, bitmap_size*3); 01563 #endif 01564 01565 thd->status_var.opened_tables++; 01566 01567 DBUG_RETURN (0); 01568 01569 err: 01570 if (! error_reported) 01571 open_table_error(share, error, my_errno, 0); 01572 delete outparam->file; 01573 #ifdef WITH_PARTITION_STORAGE_ENGINE 01574 if (outparam->part_info) 01575 free_items(outparam->part_info->item_free_list); 01576 #endif 01577 outparam->file= 0; // For easier error checking 01578 outparam->db_stat=0; 01579 free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root 01580 my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); 01581 DBUG_RETURN (error); 01582 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1707 of file table.cc.
References DBUG_ENTER, DBUG_RETURN, my_malloc(), MY_NABP, my_read, MY_WME, MYF, and x_free.
Referenced by examine_log(), mysql_create_frm(), open_binary_frm(), and readfrm().
01708 { 01709 DBUG_ENTER("read_string"); 01710 01711 x_free((gptr) *to); 01712 if (!(*to= (gptr) my_malloc(length+1,MYF(MY_WME))) || 01713 my_read(file,(byte*) *to,length,MYF(MY_NABP))) 01714 { 01715 x_free((gptr) *to); /* purecov: inspected */ 01716 *to= 0; /* purecov: inspected */ 01717 DBUG_RETURN(1); /* purecov: inspected */ 01718 } 01719 *((char*) *to+length)= '\0'; 01720 DBUG_RETURN (0); 01721 } /* read_string */
Here is the call graph for this function:

Here is the caller graph for this function:

| int rename_file_ext | ( | const char * | from, | |
| const char * | to, | |||
| const char * | ext | |||
| ) |
Definition at line 2157 of file table.cc.
References FN_REFLEN, my_rename(), MY_WME, MYF, NullS, strxmov(), and VOID.
Referenced by mysql_rename_table(), and handler::rename_table().
02158 { 02159 char from_b[FN_REFLEN],to_b[FN_REFLEN]; 02160 VOID(strxmov(from_b,from,ext,NullS)); 02161 VOID(strxmov(to_b,to,ext,NullS)); 02162 return (my_rename(from_b,to_b,MYF(MY_WME))); 02163 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int set_zone | ( | register int | nr, | |
| int | min_zone, | |||
| int | max_zone | |||
| ) |
Definition at line 1967 of file table.cc.
Referenced by Item_func_format::Item_func_format(), and my_yyoverflow().
01968 { 01969 if (nr<=min_zone) 01970 return (min_zone); 01971 if (nr>=max_zone) 01972 return (max_zone); 01973 return (nr); 01974 } /* set_zone */
Here is the caller graph for this function:

| my_bool table_check_intact | ( | TABLE * | table, | |
| uint | table_f_count, | |||
| TABLE_FIELD_W_TYPE * | table_def, | |||
| time_t * | last_create_time, | |||
| int | error_num | |||
| ) |
Definition at line 2372 of file table.cc.
References st_table::alias, buffer, Field::charset(), ha_statistics::create_time, st_table_field_w_type::cset, charset_info_st::csname, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER, ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, error, FALSE, st_table::field, Field::field_name, st_table_share::fields, st_table::file, Field::has_charset(), LEX_STRING::length, my_error(), MYF, st_table_share::mysql_version, MYSQL_VERSION_ID, st_table_field_w_type::name, st_table::s, sql_print_error(), Field::sql_type(), handler::stats, LEX_STRING::str, strcmp(), system_charset_info, TRUE, and st_table_field_w_type::type.
Referenced by Event_scheduler::check_system_tables(), and Events::open_event_table().
02375 { 02376 uint i; 02377 my_bool error= FALSE; 02378 my_bool fields_diff_count; 02379 DBUG_ENTER("table_check_intact"); 02380 DBUG_PRINT("info",("table=%s expected_count=%d",table->alias, table_f_count)); 02381 DBUG_PRINT("info",("last_create_time=%d", *last_create_time)); 02382 02383 if ((fields_diff_count= (table->s->fields != table_f_count)) || 02384 (*last_create_time != table->file->stats.create_time)) 02385 { 02386 DBUG_PRINT("info", ("I am suspecting, checking table")); 02387 if (fields_diff_count) 02388 { 02389 // previous MySQL version 02390 error= TRUE; 02391 if (MYSQL_VERSION_ID > table->s->mysql_version) 02392 { 02393 my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0), table->alias, 02394 table_f_count, table->s->fields, table->s->mysql_version, 02395 MYSQL_VERSION_ID); 02396 sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE), 02397 table->alias, table_f_count, table->s->fields, 02398 table->s->mysql_version, MYSQL_VERSION_ID); 02399 DBUG_RETURN(error); 02400 02401 } 02402 else if (MYSQL_VERSION_ID == table->s->mysql_version) 02403 { 02404 my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED,MYF(0), table->alias, 02405 table_f_count, table->s->fields); 02406 sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias, 02407 table_f_count, table->s->fields); 02408 } 02409 else 02410 { 02411 /* 02412 moving from newer mysql to older one -> let's say not an error but 02413 will check the definition afterwards. If a column was added at the 02414 end then we don't care much since it's not in the middle. 02415 */ 02416 error= FALSE; 02417 } 02418 } 02419 //definitely something has changed 02420 char buffer[255]; 02421 for (i=0 ; i < table_f_count; i++, table_def++) 02422 { 02423 String sql_type(buffer, sizeof(buffer), system_charset_info); 02424 sql_type.length(0); 02425 /* 02426 name changes are not fatal, we use sequence numbers => no prob for us 02427 but this can show tampered table or broken table. 02428 */ 02429 if (i < table->s->fields) 02430 { 02431 Field *field= table->field[i]; 02432 if (strncmp(field->field_name, table_def->name.str, 02433 table_def->name.length)) 02434 { 02435 sql_print_error("(%s) Expected field %s at position %d, found %s", 02436 table->alias, table_def->name.str, i, 02437 field->field_name); 02438 } 02439 02440 /* 02441 IF the type does not match than something is really wrong 02442 Check up to length - 1. Why? 02443 1. datetime -> datetim -> the same 02444 2. int(11) -> int(11 -> the same 02445 3. set('one','two') -> set('one','two' 02446 so for sets if the same prefix is there it's ok if more are 02447 added as part of the set. The same is valid for enum. So a new 02448 table running on a old server will be valid. 02449 */ 02450 field->sql_type(sql_type); 02451 if (strncmp(sql_type.c_ptr_safe(), table_def->type.str, 02452 table_def->type.length - 1)) 02453 { 02454 sql_print_error("(%s) Expected field %s at position %d to have type " 02455 "%s, found %s", table->alias, table_def->name.str, 02456 i, table_def->type.str, sql_type.c_ptr_safe()); 02457 error= TRUE; 02458 } 02459 else if (table_def->cset.str && !field->has_charset()) 02460 { 02461 sql_print_error("(%s) Expected field %s at position %d to have " 02462 "character set '%s' but found no such", table->alias, 02463 table_def->name.str, i, table_def->cset.str); 02464 error= TRUE; 02465 } 02466 else if (table_def->cset.str && 02467 strcmp(field->charset()->csname, table_def->cset.str)) 02468 { 02469 sql_print_error("(%s) Expected field %s at position %d to have " 02470 "character set '%s' but found '%s'", table->alias, 02471 table_def->name.str, i, table_def->cset.str, 02472 field->charset()->csname); 02473 error= TRUE; 02474 } 02475 } 02476 else 02477 { 02478 sql_print_error("(%s) Expected field %s at position %d to have type %s " 02479 " but no field found.", table->alias, 02480 table_def->name.str, i, table_def->type.str); 02481 error= TRUE; 02482 } 02483 } 02484 if (!error) 02485 *last_create_time= table->file->stats.create_time; 02486 else if (!fields_diff_count && error_num) 02487 my_error(error_num,MYF(0), table->alias, table_f_count, table->s->fields); 02488 } 02489 else 02490 { 02491 DBUG_PRINT("info", ("Table seems ok without thorough checking.")); 02492 *last_create_time= table->file->stats.create_time; 02493 } 02494 02495 DBUG_RETURN(error); 02496 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1907 of file table.cc.
References alloc_root(), st_typelib::count, base_list::elements, String::length(), st_typelib::name, String::ptr(), st_typelib::type_lengths, and st_typelib::type_names.
Referenced by check_duplicates_in_interval(), find_type(), find_type2(), Item_func_find_in_set::fix_length_and_dec(), get_access(), Item_type_holder::get_full_info(), get_type(), mysql_prepare_table(), and replace_user_table().
01908 { 01909 TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); 01910 if (!result) 01911 return 0; 01912 result->count=strings.elements; 01913 result->name=""; 01914 uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); 01915 if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) 01916 return 0; 01917 result->type_lengths= (uint*) (result->type_names + result->count + 1); 01918 List_iterator<String> it(strings); 01919 String *tmp; 01920 for (uint i=0; (tmp=it++) ; i++) 01921 { 01922 result->type_names[i]= tmp->ptr(); 01923 result->type_lengths[i]= tmp->length(); 01924 } 01925 result->type_names[result->count]= 0; // End marker 01926 result->type_lengths[result->count]= 0; 01927 return result; 01928 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void update_create_info_from_table | ( | HA_CREATE_INFO * | create_info, | |
| TABLE * | table | |||
| ) |
Definition at line 2140 of file table.cc.
References st_table_share::avg_row_length, st_ha_create_information::avg_row_length, st_table_share::db_create_options, DBUG_ENTER, DBUG_VOID_RETURN, st_ha_create_information::default_table_charset, st_table_share::max_rows, st_ha_create_information::max_rows, st_table_share::min_rows, st_ha_create_information::min_rows, st_table_share::row_type, st_ha_create_information::row_type, st_table::s, st_ha_create_information::table_charset, st_table_share::table_charset, and st_ha_create_information::table_options.
Referenced by ha_create_table(), and ha_create_table_from_engine().
02141 { 02142 TABLE_SHARE *share= table->s; 02143 DBUG_ENTER("update_create_info_from_table"); 02144 02145 create_info->max_rows= share->max_rows; 02146 create_info->min_rows= share->min_rows; 02147 create_info->table_options= share->db_create_options; 02148 create_info->avg_row_length= share->avg_row_length; 02149 create_info->row_type= share->row_type; 02150 create_info->default_table_charset= share->table_charset; 02151 create_info->table_charset= 0; 02152 02153 DBUG_VOID_RETURN; 02154 }
Here is the caller graph for this function:

1.4.7

