diff options
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 132 |
1 files changed, 120 insertions, 12 deletions
diff --git a/sql/table.cc b/sql/table.cc index 8068a839052..b4548f4d90b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -70,7 +70,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, int j,error, errarg= 0; uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; - uint key_info_length, com_length; + uint key_info_length, com_length, part_info_len=0, extra_rec_buf_length; ulong pos, record_offset; char index_file[FN_REFLEN], *names, *keynames, *comment_pos; uchar head[288],*disk_buff,new_field_pack_flag; @@ -87,6 +87,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, SQL_CRYPT *crypted=0; MEM_ROOT **root_ptr, *old_root; TABLE_SHARE *share; + enum db_type default_part_db_type; DBUG_ENTER("openfrm"); DBUG_PRINT("enter",("name: '%s' form: 0x%lx",name,outparam)); @@ -163,6 +164,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5) share->frm_version= FRM_VER_TRUE_VARCHAR; + default_part_db_type= ha_checktype(thd,(enum db_type) (uint) *(head+61),0,0); share->db_type= ha_checktype(thd,(enum db_type) (uint) *(head+3),0,0); share->db_create_options= db_create_options=uint2korr(head+30); share->db_options_in_use= share->db_create_options; @@ -308,9 +310,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, { /* Read extra data segment */ char *buff, *next_chunk, *buff_end; + DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); if (!(next_chunk= buff= my_malloc(n_length, MYF(MY_WME)))) goto err; - buff_end= buff + n_length; if (my_pread(file, (byte*)buff, n_length, record_offset + share->reclength, MYF(MY_NABP))) { @@ -321,26 +323,89 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (! (share->connect_string.str= strmake_root(&outparam->mem_root, next_chunk + 2, share->connect_string.length))) { + DBUG_PRINT("EDS", ("strmake_root failed for connect_string")); my_free(buff, MYF(0)); goto err; } next_chunk+= share->connect_string.length + 2; + buff_end= buff + n_length; if (next_chunk + 2 < buff_end) { uint str_db_type_length= uint2korr(next_chunk); - share->db_type= ha_resolve_by_name(next_chunk + 2, str_db_type_length); - DBUG_PRINT("enter", ("Setting dbtype to: %d - %d - '%.*s'\n", - share->db_type, - str_db_type_length, str_db_type_length, - next_chunk + 2)); + enum db_type tmp_db_type= ha_resolve_by_name(next_chunk + 2, + str_db_type_length); + if (tmp_db_type != DB_TYPE_UNKNOWN) + { + share->db_type= tmp_db_type; + DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", + str_db_type_length, next_chunk + 2, + share->db_type)); + } +#ifdef WITH_PARTITION_STORAGE_ENGINE + else + { + if (!strncmp(next_chunk + 2, "partition", str_db_type_length)) + { + /* Use partition handler */ + share->db_type= DB_TYPE_PARTITION_DB; + DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", + str_db_type_length, next_chunk + 2, + share->db_type)); + } + } +#endif next_chunk+= str_db_type_length + 2; } + if (next_chunk + 4 < buff_end) + { + part_info_len= uint4korr(next_chunk); + if (part_info_len > 0) + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (mysql_unpack_partition(thd, (uchar *)(next_chunk + 4), + part_info_len, outparam, + default_part_db_type)) + { + DBUG_PRINT("info", ("mysql_unpack_partition failed")); + my_free(buff, MYF(0)); + goto err; + } +#else + DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined")); + my_free(buff, MYF(0)); + goto err; +#endif + } + next_chunk+= part_info_len + 5; + } + keyinfo= outparam->key_info; + for (i= 0; i < keys; i++, keyinfo++) + { + if (keyinfo->flags & HA_USES_PARSER) + { + LEX_STRING parser_name; + if (next_chunk >= buff_end) + { + DBUG_PRINT("EDS", + ("fulltext key uses parser that is not defined in .frm")); + my_free(buff, MYF(0)); + goto err; + } + parser_name.str= next_chunk; + parser_name.length= strlen(next_chunk); + keyinfo->parser= plugin_lock(&parser_name, MYSQL_FTPARSER_PLUGIN); + if (! keyinfo->parser) + { + DBUG_PRINT("EDS", ("parser plugin is not loaded")); + my_free(buff, MYF(0)); + my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str); + error_reported= 1; + goto err; + } + } + } my_free(buff, MYF(0)); } - /* Allocate handler */ - if (!(outparam->file= get_new_handler(outparam, &outparam->mem_root, - share->db_type))) - goto err; error=4; outparam->reginfo.lock_type= TL_UNLOCK; @@ -352,8 +417,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (prgflag & (READ_ALL+EXTRA_RECORD)) records++; /* QQ: TODO, remove the +1 from below */ + extra_rec_buf_length= uint2korr(head+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + - outparam->file->extra_rec_buf_length()); + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; if (!(record= (char *) alloc_root(&outparam->mem_root, rec_buff_length * records))) @@ -471,9 +537,15 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (keynames) fix_type_pointers(&int_array, &share->keynames, 1, &keynames); + VOID(my_close(file,MYF(MY_WME))); file= -1; + /* Allocate handler */ + if (!(outparam->file= get_new_handler(outparam, &outparam->mem_root, + share->db_type))) + goto err; + record= (char*) outparam->record[0]-1; /* Fieldstart = 1 */ if (null_field_first) { @@ -635,6 +707,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, goto err; /* purecov: inspected */ } + reg_field->fieldnr= i+1; //Set field number reg_field->field_index= i; reg_field->comment=comment; if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) @@ -896,6 +969,16 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } } + if (outparam->file->ha_allocate_read_write_set(share->fields)) + goto err; + + /* Fix the partition functions and ensure they are not constant functions*/ + if (part_info_len > 0) +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (fix_partition_func(thd,name,outparam)) +#endif + goto err; + /* the correct null_bytes can now be set, since bitfields have been taken into account @@ -961,6 +1044,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (! error_reported) frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG, errarg); delete outparam->file; +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (outparam->s->part_info) + { + free_items(outparam->s->part_info->item_free_list); + outparam->s->part_info->item_free_list= 0; + } +#endif outparam->file=0; // For easier errorchecking outparam->db_stat=0; hash_free(&share->name_hash); @@ -975,9 +1065,20 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, int closefrm(register TABLE *table) { int error=0; + uint idx; + KEY *key_info; DBUG_ENTER("closefrm"); if (table->db_stat) error=table->file->close(); + key_info= table->key_info; + for (idx= table->s->keys; idx; idx--, key_info++) + { + if (key_info->flags & HA_USES_PARSER) + { + plugin_unlock(key_info->parser); + key_info->flags= 0; + } + } my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR)); table->alias= 0; if (table->field) @@ -987,6 +1088,13 @@ int closefrm(register TABLE *table) table->field= 0; } delete table->file; +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (table->s->part_info) + { + free_items(table->s->part_info->item_free_list); + table->s->part_info->item_free_list= 0; + } +#endif table->file= 0; /* For easier errorchecking */ hash_free(&table->s->name_hash); free_root(&table->mem_root, MYF(0)); |