summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-04-09 15:56:59 +0200
committerSergei Golubchik <sergii@pisem.net>2013-04-09 15:56:59 +0200
commitb3e70c4ae713abeddd47b3987f898ed763fa4eca (patch)
tree3f02361cb965455e4be88bbbb227762cd1a128f8
parentcb5473cb2f0cea5eeace0fec17e0840fcba8f37a (diff)
downloadmariadb-git-b3e70c4ae713abeddd47b3987f898ed763fa4eca.tar.gz
split mysql_create_frm() in create_frm_image() and writefrm()
-rw-r--r--sql/discover.cc39
-rw-r--r--sql/discover.h3
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/table.cc11
-rw-r--r--sql/table.h2
-rw-r--r--sql/unireg.cc107
6 files changed, 81 insertions, 83 deletions
diff --git a/sql/discover.cc b/sql/discover.cc
index e2e84824f4d..a7681a3c2ba 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -100,7 +100,7 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
Write the content of a frm data pointer
to a frm file.
- @param name path to table-file "db/name"
+ @param path path to table-file "db/name"
@param frmdata frm data
@param len length of the frmdata
@@ -110,24 +110,35 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
2 Could not write file
*/
-int writefrm(const char *name, const uchar *frmdata, size_t len)
+int writefrm(const char *path, const char *db, const char *table,
+ bool need_sync, const uchar *frmdata, size_t len)
{
- File file;
- char index_file[FN_REFLEN];
+ char file_name[FN_REFLEN+1];
int error;
DBUG_ENTER("writefrm");
- DBUG_PRINT("enter",("name: '%s' len: %lu ",name, (ulong) len));
+ DBUG_PRINT("enter",("name: '%s' len: %lu ",path, (ulong) len));
- error= 0;
- if ((file= mysql_file_create(key_file_frm,
- fn_format(index_file, name, "", reg_ext,
- MY_UNPACK_FILENAME | MY_APPEND_EXT),
- CREATE_MODE, O_RDWR | O_TRUNC,
- MYF(MY_WME))) >= 0)
+ strxnmov(file_name, sizeof(file_name)-1, path, reg_ext, NullS);
+
+ File file= mysql_file_create(key_file_frm, file_name,
+ CREATE_MODE, O_RDWR | O_TRUNC, MYF(0));
+
+ if ((error= file < 0))
{
- if (mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP)))
- error= 2;
- (void) mysql_file_close(file, MYF(0));
+ if (my_errno == ENOENT)
+ my_error(ER_BAD_DB_ERROR, MYF(0), db);
+ else
+ my_error(ER_CANT_CREATE_TABLE, MYF(0), table, my_errno);
+ }
+ else
+ {
+ error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP));
+
+ if (!error && need_sync)
+ error= mysql_file_sync(file, MYF(MY_WME)) ||
+ my_sync_dir_by_file(file_name, MYF(MY_WME));
+
+ error|= mysql_file_close(file, MYF(MY_WME));
}
DBUG_RETURN(error);
} /* writefrm */
diff --git a/sql/discover.h b/sql/discover.h
index a5d98d270e6..28d35b73152 100644
--- a/sql/discover.h
+++ b/sql/discover.h
@@ -19,7 +19,8 @@
#include "my_global.h" /* uchar */
int readfrm(const char *name, uchar **data, size_t *length);
-int writefrm(const char* name, const uchar* data, size_t len);
+int writefrm(const char *path, const char *db, const char *table,
+ bool need_sync, const uchar *frmdata, size_t len);
int extension_based_table_discovery(MY_DIR *dirp, const char *ext,
handlerton::discovered_list *tl);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7d5f2d870ec..739a1141992 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1703,7 +1703,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#endif
/* Write shadow frm file */
lpt->create_info->table_options= lpt->db_options;
- if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db,
+ if ((mysql_create_frm(lpt->thd, shadow_path, lpt->db,
lpt->table_name, lpt->create_info,
lpt->alter_info->create_list, lpt->key_count,
lpt->key_info_buffer, lpt->table->file)) ||
diff --git a/sql/table.cc b/sql/table.cc
index a23eaa52c0b..b30ed15ba8e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -657,7 +657,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
}
mysql_file_close(file, MYF(MY_WME));
- share->init_from_binary_frm_image(thd, NULL, buf, stats.st_size);
+ share->init_from_binary_frm_image(thd, false, buf, stats.st_size);
error_given= true; // init_from_binary_frm_image has already called my_error()
my_free(buf);
@@ -696,8 +696,9 @@ err_not_open:
*/
-bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
- const uchar *frm_image, size_t frm_length)
+bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
+ const uchar *frm_image,
+ size_t frm_length)
{
TABLE_SHARE *share= this;
uint new_frm_ver, field_pack_length, new_field_pack_flag;
@@ -740,7 +741,9 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
old_root= *root_ptr;
*root_ptr= &share->mem_root;
- if (path && writefrm(path, frm_image, frm_length))
+ if (write && writefrm(share->normalized_path.str,
+ share->db.str, share->table_name.str, MY_SYNC,
+ frm_image, frm_length))
goto err;
if (frm_length < FRM_HEADER_SIZE + FRM_FORMINFO_SIZE)
diff --git a/sql/table.h b/sql/table.h
index 04a86aa1884..e419f5d1240 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -988,7 +988,7 @@ struct TABLE_SHARE
uint actual_n_key_parts(THD *thd);
- bool init_from_binary_frm_image(THD *thd, const char *path,
+ bool init_from_binary_frm_image(THD *thd, bool write,
const uchar *frm_image, size_t frm_length);
};
diff --git a/sql/unireg.cc b/sql/unireg.cc
index bffe3ab7a41..fdc4628bace 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -29,6 +29,7 @@
#include "sql_partition.h" // struct partition_info
#include "sql_class.h" // THD, Internal_error_handler
#include "create_options.h"
+#include "discover.h"
#include <m_ctype.h>
#include <assert.h>
@@ -43,6 +44,8 @@ static uint get_interval_id(uint *,List<Create_field> &, Create_field *);
static bool pack_fields(uchar *, List<Create_field> &, ulong);
static size_t packed_fields_length(List<Create_field> &);
static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, ulong);
+static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *,
+ List<Create_field> &, uint, KEY *, handler *);
/*
Create a frm (table definition) file
@@ -71,10 +74,28 @@ bool mysql_create_frm(THD *thd, const char *file_name,
uint keys, KEY *key_info,
handler *db_file)
{
+ DBUG_ENTER("mysql_create_frm");
+ LEX_CUSTRING frm= create_frm_image(thd, table, create_info,
+ create_fields, keys, key_info, db_file);
+ if (!frm.str)
+ DBUG_RETURN(1);
+
+ bool need_sync= opt_sync_frm &&
+ !(create_info->options & HA_LEX_CREATE_TMP_TABLE);
+ int error= writefrm(file_name, db, table, need_sync, frm.str, frm.length);
+
+ my_free(const_cast<uchar*>(frm.str));
+ DBUG_RETURN(error);
+}
+
+LEX_CUSTRING create_frm_image(THD *thd, const char *table,
+ HA_CREATE_INFO *create_info,
+ List<Create_field> &create_fields,
+ uint keys, KEY *key_info, handler *db_file)
+{
LEX_STRING str_db_type;
uint reclength, key_info_length, maxlength, tmp_len, i;
ulong key_buff_length;
- File file;
ulong filepos, data_offset;
uint options_len;
uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE];
@@ -82,12 +103,9 @@ bool mysql_create_frm(THD *thd, const char *file_name,
partition_info *part_info= thd->work_part_info;
#endif
int error;
- size_t frm_length;
uchar *frm_ptr, *pos;
- DBUG_ENTER("mysql_create_frm");
-
- DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
- DBUG_ASSERT(db_file != NULL);
+ LEX_CUSTRING frm= {0,0};
+ DBUG_ENTER("create_frm_image");
/* If fixed row records, we need one bit to check for deleted rows */
if (!(create_info->table_options & HA_OPTION_PACK_RECORD))
@@ -98,7 +116,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
data_offset, db_file);
if (error)
- DBUG_RETURN(1);
+ DBUG_RETURN(frm);
reclength=uint2korr(forminfo+266);
@@ -177,7 +195,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
{
my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0),
real_table_name, static_cast<ulong>(TABLE_COMMENT_MAXLEN));
- DBUG_RETURN(1);
+ DBUG_RETURN(frm);
}
char warn_buff[MYSQL_ERRMSG_SIZE];
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT),
@@ -207,25 +225,25 @@ bool mysql_create_frm(THD *thd, const char *file_name,
key_buff_length= uint4korr(fileinfo+47);
- frm_length= FRM_HEADER_SIZE; // fileinfo;
- frm_length+= 7; // "form entry"
+ frm.length= FRM_HEADER_SIZE; // fileinfo;
+ frm.length+= 7; // "form entry"
- int2store(fileinfo+6, frm_length);
- frm_length+= key_buff_length;
- frm_length+= reclength; // row with default values
- frm_length+= create_info->extra_size;
+ int2store(fileinfo+6, frm.length);
+ frm.length+= key_buff_length;
+ frm.length+= reclength; // row with default values
+ frm.length+= create_info->extra_size;
- filepos= frm_length;
- frm_length+= FRM_FORMINFO_SIZE; // forminfo
- frm_length+= packed_fields_length(create_fields);
+ filepos= frm.length;
+ frm.length+= FRM_FORMINFO_SIZE; // forminfo
+ frm.length+= packed_fields_length(create_fields);
- frm_ptr= (uchar*) my_malloc(frm_length, MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC));
+ frm_ptr= (uchar*) my_malloc(frm.length, MYF(MY_WME | MY_ZEROFILL |
+ MY_THREAD_SPECIFIC));
if (!frm_ptr)
- DBUG_RETURN(1);
+ DBUG_RETURN(frm);
pos = frm_ptr + uint2korr(fileinfo+6);
key_info_length= pack_keys(pos, keys, key_info, data_offset);
- //frm_length-= key_buff_length-key_info_length;
memcpy(frm_ptr + FRM_HEADER_SIZE, "//", 3);
int4store(frm_ptr + 67, filepos);
@@ -310,36 +328,6 @@ bool mysql_create_frm(THD *thd, const char *file_name,
if (pack_fields(frm_ptr + filepos + FRM_FORMINFO_SIZE, create_fields, data_offset))
goto err;
- //==========================================
- {
- int create_flags= O_RDWR | O_TRUNC;
- if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
- create_flags|= O_EXCL | O_NOFOLLOW;
-
- file= mysql_file_create(key_file_frm, file_name,
- CREATE_MODE, create_flags, MYF(0));
- }
- if (file < 0)
- {
- if (my_errno == ENOENT)
- my_error(ER_BAD_DB_ERROR,MYF(0),db);
- else
- my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
- goto err;
- }
-
- if (mysql_file_write(file, frm_ptr, frm_length, MYF_RW))
- goto err2;
- if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
- (mysql_file_sync(file, MYF(MY_WME)) ||
- my_sync_dir_by_file(file_name, MYF(MY_WME))))
- goto err2;
-
- if (mysql_file_close(file, MYF(MY_WME)))
- goto err1;
-
- my_free(frm_ptr);
-
{
/*
Restore all UCS2 intervals.
@@ -357,16 +345,13 @@ bool mysql_create_frm(THD *thd, const char *file_name,
}
}
- DBUG_RETURN(0);
+ frm.str= frm_ptr;
+ DBUG_RETURN(frm);
-err2:
- mysql_file_close(file, MYF(MY_WME));
-err1:
- mysql_file_delete(key_file_frm, file_name, MYF(0));
err:
my_free(frm_ptr);
- DBUG_RETURN(1);
-} /* mysql_create_frm */
+ DBUG_RETURN(frm);
+}
/*
@@ -397,15 +382,11 @@ int rea_create_table(THD *thd, const char *path,
{
DBUG_ENTER("rea_create_table");
- char frm_name[FN_REFLEN];
- strxmov(frm_name, path, reg_ext, NullS);
- if (mysql_create_frm(thd, frm_name, db, table_name, create_info,
+ if (mysql_create_frm(thd, path, db, table_name, create_info,
create_fields, keys, key_info, file))
DBUG_RETURN(1);
- // Make sure mysql_create_frm din't remove extension
- DBUG_ASSERT(*fn_rext(frm_name));
if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES;
if (!create_info->frm_only &&
@@ -417,6 +398,8 @@ int rea_create_table(THD *thd, const char *path,
err_handler:
(void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info);
+ char frm_name[FN_REFLEN];
+ strxmov(frm_name, path, reg_ext, NullS);
mysql_file_delete(key_file_frm, frm_name, MYF(0));
DBUG_RETURN(1);
} /* rea_create_table */