diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-09-18 13:07:31 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-09-18 13:07:31 +0200 |
commit | 4ec2e9d7eda78d409d1b017ef4d8928fe9055438 (patch) | |
tree | 6c3a74a740d3c1c5f3a7d1f8154d8a791b435b3f /sql/datadict.cc | |
parent | 1a2a9d74fe1256554eceb09bbc6752a6376df87d (diff) | |
parent | 197bdbae4db78ba65f3668803bebd3c4a4509ae5 (diff) | |
download | mariadb-git-4ec2e9d7eda78d409d1b017ef4d8928fe9055438.tar.gz |
5.5 merge and fixes for compiler/test errors
Diffstat (limited to 'sql/datadict.cc')
-rw-r--r-- | sql/datadict.cc | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/sql/datadict.cc b/sql/datadict.cc index 4bc74af7bdb..deeedcd512d 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -18,6 +18,22 @@ #include "sql_class.h" #include "sql_table.h" +static int read_string(File file, uchar**to, size_t length) +{ + DBUG_ENTER("read_string"); + + my_free(*to); + if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) || + mysql_file_read(file, *to, length, MYF(MY_NABP))) + { + my_free(*to); + *to= 0; + DBUG_RETURN(1); + } + *((char*) *to+length)= '\0'; // C-style safety + DBUG_RETURN (0); +} + /** Check type of .frm if we are not going to parse it. @@ -36,6 +52,7 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) File file; uchar header[10]; //"TYPE=VIEW\n" it is 10 characters size_t error; + frm_type_enum type= FRMTYPE_ERROR; DBUG_ENTER("dd_frm_type"); *dbt= DB_TYPE_UNKNOWN; @@ -43,12 +60,16 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0) DBUG_RETURN(FRMTYPE_ERROR); error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)); - mysql_file_close(file, MYF(MY_WME)); if (error) - DBUG_RETURN(FRMTYPE_ERROR); + goto err; if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header))) - DBUG_RETURN(FRMTYPE_VIEW); + { + type= FRMTYPE_VIEW; + goto err; + } + + type= FRMTYPE_TABLE; /* This is just a check for DB_TYPE. We'll return default unknown type @@ -56,17 +77,57 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) on return value from this function (default FRMTYPE_TABLE) */ if (!is_binary_frm_header(header)) - DBUG_RETURN(FRMTYPE_TABLE); + goto err; - /* - XXX this is a bug. - if header[3] is > DB_TYPE_FIRST_DYNAMIC, then the complete - storage engine name must be read from the frm - */ *dbt= (enum legacy_db_type) (uint) *(header + 3); + if (*dbt >= DB_TYPE_FIRST_DYNAMIC) /* read the true engine name */ + { + MY_STAT state; + uchar *frm_image= 0; + uint n_length; + + if (mysql_file_fstat(file, &state, MYF(MY_WME))) + goto err; + + if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME))) + goto err; + + if (read_string(file, &frm_image, state.st_size)) + goto err; + + if ((n_length= uint4korr(frm_image+55))) + { + uint record_offset= uint2korr(frm_image+6)+ + ((uint2korr(frm_image+14) == 0xffff ? + uint4korr(frm_image+47) : uint2korr(frm_image+14))); + uint reclength= uint2korr(frm_image+16); + + uchar *next_chunk= frm_image + record_offset + reclength; + uchar *buff_end= next_chunk + n_length; + uint connect_string_length= uint2korr(next_chunk); + next_chunk+= connect_string_length + 2; + if (next_chunk + 2 < buff_end) + { + uint str_db_type_length= uint2korr(next_chunk); + LEX_STRING name; + name.str= (char*) next_chunk + 2; + name.length= str_db_type_length; + plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name); + if (tmp_plugin) + *dbt= plugin_data(tmp_plugin, handlerton *)->db_type; + else + *dbt= DB_TYPE_UNKNOWN; + } + } + + my_free(frm_image); + } + /* Probably a table. */ - DBUG_RETURN(FRMTYPE_TABLE); +err: + mysql_file_close(file, MYF(MY_WME)); + DBUG_RETURN(type); } |