The world's most popular open source database
#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 *&nbs |

