summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc132
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));