summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysql_com.h2
-rw-r--r--sql/discover.cc10
-rw-r--r--sql/discover.h2
-rw-r--r--sql/share/errmsg-utf8.txt6
-rw-r--r--sql/sql_table.cc8
-rw-r--r--sql/table.cc41
-rw-r--r--sql/table.h6
-rw-r--r--sql/unireg.cc55
-rw-r--r--sql/unireg.h6
-rw-r--r--storage/federatedx/ha_federatedx.cc7
10 files changed, 75 insertions, 68 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 5697fc952ce..9ba17b416c4 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -41,7 +41,7 @@
/*
Maximum length of comments
*/
-#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */
+#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 5.5: 60 characters */
#define TABLE_COMMENT_MAXLEN 2048
#define COLUMN_COMMENT_MAXLEN 1024
#define INDEX_COMMENT_MAXLEN 1024
diff --git a/sql/discover.cc b/sql/discover.cc
index 5add741fc0c..b5bccf7dcb0 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -111,17 +111,21 @@ int readfrm(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)
+ bool tmp_table, const uchar *frmdata, size_t len)
{
char file_name[FN_REFLEN+1];
int error;
+ int create_flags= O_RDWR | O_TRUNC;
DBUG_ENTER("writefrm");
DBUG_PRINT("enter",("name: '%s' len: %lu ",path, (ulong) len));
+ if (tmp_table)
+ create_flags|= O_EXCL | O_NOFOLLOW;
+
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));
+ CREATE_MODE, create_flags, MYF(0));
if ((error= file < 0))
{
@@ -134,7 +138,7 @@ int writefrm(const char *path, const char *db, const char *table,
{
error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP));
- if (!error && need_sync && opt_sync_frm)
+ if (!error && !tmp_table && opt_sync_frm)
error= mysql_file_sync(file, MYF(MY_WME)) ||
my_sync_dir_by_file(file_name, MYF(MY_WME));
diff --git a/sql/discover.h b/sql/discover.h
index aad8bb734ec..fbf94891c74 100644
--- a/sql/discover.h
+++ b/sql/discover.h
@@ -24,7 +24,7 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext,
#ifdef MYSQL_SERVER
int readfrm(const char *name, const uchar **data, size_t *length);
int writefrm(const char *path, const char *db, const char *table,
- bool need_sync, const uchar *frmdata, size_t len);
+ bool tmp_table, const uchar *frmdata, size_t len);
int ext_table_discovery_simple(MY_DIR *dirp,
handlerton::discovered_list *result);
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 036d4a0258c..6a7eafc5fc4 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6192,9 +6192,9 @@ ER_TOO_LONG_TABLE_COMMENT
por "Comentário para a tabela '%-.64s' é longo demais (max = %u)"
ger "Kommentar für Tabelle '%-.64s' ist zu lang (max = %u)"
ER_TOO_LONG_FIELD_COMMENT
- eng "Comment for field '%-.64s' is too long (max = %lu)"
- por "Comentário para o campo '%-.64s' é longo demais (max = %lu)"
- ger "Kommentar für Feld '%-.64s' ist zu lang (max = %lu)"
+ eng "Comment for field '%-.64s' is too long (max = %u)"
+ por "Comentário para o campo '%-.64s' é longo demais (max = %u)"
+ ger "Kommentar für Feld '%-.64s' ist zu lang (max = %u)"
ER_FUNC_INEXISTENT_NAME_COLLISION 42000
eng "FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual"
ger "FUNCTION %s existiert nicht. Erläuterungen im Abschnitt 'Function Name Parsing and Resolution' im Referenzhandbuch"
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8862fcc7d0e..eb02e9f2baf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1709,7 +1709,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
}
int error= writefrm(shadow_path, lpt->db, lpt->table_name,
- !lpt->create_info->tmp_table(), frm.str, frm.length);
+ lpt->create_info->tmp_table(), frm.str, frm.length);
my_free(const_cast<uchar*>(frm.str));
if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path,
@@ -1751,7 +1751,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
*/
build_table_filename(path, sizeof(path) - 1, lpt->db,
lpt->table_name, "", 0);
- strxmov(frm_name, path, reg_ext, NullS);
+ strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS);
/*
When we are changing to use new frm file we need to ensure that we
don't collide with another thread in process to open the frm file.
@@ -4467,7 +4467,7 @@ bool mysql_create_table_no_lock(THD *thd,
create_info, file))
{
char frm_name[FN_REFLEN];
- strxmov(frm_name, path, reg_ext, NullS);
+ strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS);
(void) mysql_file_delete(key_file_frm, frm_name, MYF(0));
goto err;
}
@@ -6661,7 +6661,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
char frm_name[FN_REFLEN+1];
- strxmov(frm_name, path, reg_ext, NullS);
+ strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS);
/*
C_ALTER_TABLE_FRM_ONLY can only be used if old frm exists.
discovering frm-less engines cannot enjoy this optimization.
diff --git a/sql/table.cc b/sql/table.cc
index ccb763847d6..faa087cbaa4 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -592,11 +592,10 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
{
bool error_given= false;
File file;
- MY_STAT stats;
uchar *buf;
uchar head[FRM_HEADER_SIZE];
char path[FN_REFLEN];
- size_t frmlen;
+ size_t frmlen, read_length;
DBUG_ENTER("open_table_def");
DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str,
share->table_name.str, share->normalized_path.str));
@@ -640,26 +639,26 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
goto err;
}
- if (my_fstat(file, &stats, MYF(0)))
- goto err;
-
- frmlen= min(FRM_MAX_SIZE, stats.st_size); // safety
+ frmlen= uint4korr(head+10);
+ set_if_smaller(frmlen, FRM_MAX_SIZE); // safety
if (!(buf= (uchar*)my_malloc(frmlen, MYF(MY_THREAD_SPECIFIC|MY_WME))))
goto err;
memcpy(buf, head, sizeof(head));
- if (mysql_file_read(file, buf + sizeof(head),
- frmlen - sizeof(head), MYF(MY_NABP)))
+ read_length= mysql_file_read(file, buf + sizeof(head),
+ frmlen - sizeof(head), MYF(MY_WME));
+ if (read_length == 0 || read_length == (size_t)-1)
{
- share->error = my_errno == HA_ERR_FILE_TOO_SHORT
- ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR;
+ share->error = OPEN_FRM_READ_ERROR;
my_free(buf);
goto err;
}
mysql_file_close(file, MYF(MY_WME));
+ frmlen= read_length + sizeof(head);
+
share->init_from_binary_frm_image(thd, false, buf, frmlen);
error_given= true; // init_from_binary_frm_image has already called my_error()
my_free(buf);
@@ -759,17 +758,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (*extra2 != '/') // old frm had '/' there
{
const uchar *e2end= extra2 + len;
- while (extra2 < e2end)
+ while (extra2 + 3 < e2end)
{
uchar type= *extra2++;
size_t length= *extra2++;
if (!length)
{
+ if (extra2 + 258 >= e2end)
+ goto err;
length= uint2korr(extra2);
extra2+=2;
if (length < 256)
goto err;
}
+ if (extra2 + length > e2end)
+ goto err;
switch (type) {
case EXTRA2_TABLEDEF_VERSION:
if (tabledef_version.str) // see init_from_sql_statement_string()
@@ -780,12 +783,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
else
{
- uchar *buf= (uchar*) alloc_root(&mem_root, length);
- if (!buf)
- goto err;
- memcpy(buf, extra2, length);
- tabledef_version.str= buf;
tabledef_version.length= length;
+ tabledef_version.str= (uchar*)memdup_root(&mem_root, extra2, length);
+ if (!tabledef_version.str)
+ goto err;
}
break;
case EXTRA2_ENGINE_TABLEOPTS:
@@ -797,12 +798,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
break;
default:
/* abort frm parsing if it's an unknown but important extra2 value */
- if (type >= 128)
+ if (type >= EXTRA2_ENGINE_IMPORTANT)
goto err;
}
extra2+= length;
}
- if (extra2 > e2end)
+ if (extra2 != e2end)
goto err;
}
@@ -2116,7 +2117,7 @@ ret:
bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len)
{
- return writefrm(normalized_path.str, db.str, table_name.str, 1, frm, len);
+ return writefrm(normalized_path.str, db.str, table_name.str, false, frm, len);
}
@@ -3242,7 +3243,7 @@ rename_file_ext(const char * from,const char * to,const char * ext)
char from_b[FN_REFLEN],to_b[FN_REFLEN];
(void) strxmov(from_b,from,ext,NullS);
(void) strxmov(to_b,to,ext,NullS);
- return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(0)));
+ return mysql_file_rename(key_file_frm, from_b, to_b, MYF(0));
}
diff --git a/sql/table.h b/sql/table.h
index 2d929bfc41b..fa5bd83371a 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2539,12 +2539,6 @@ static inline int set_zone(int nr,int min_zone,int max_zone)
return nr;
}
-/* Adjust number to next larger disk buffer */
-static inline ulong next_io_size(ulong pos)
-{
- return MY_ALIGN(pos, IO_SIZE);
-}
-
/* performance schema */
extern LEX_STRING PERFORMANCE_SCHEMA_DB_NAME;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index bb34c6e800b..0940b34308f 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -67,7 +67,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
uint keys, KEY *key_info, handler *db_file)
{
LEX_STRING str_db_type;
- uint reclength, key_info_length, maxlength, tmp_len, i;
+ uint reclength, key_info_length, tmp_len, i;
ulong key_buff_length;
ulong filepos, data_offset;
uint options_len;
@@ -173,7 +173,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
/*
If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes,
store the comment in an extra segment (up to TABLE_COMMENT_MAXLEN bytes).
- Pre 6.0, the limit was 60 characters, with no extra segment-handling.
+ Pre 5.5, the limit was 60 characters, with no extra segment-handling.
*/
if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN)
{
@@ -212,7 +212,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
frm.length+= extra2_size + 4; // mariadb extra2 frm segment
int2store(fileinfo+4, extra2_size);
- int2store(fileinfo+6, frm.length);
+ int2store(fileinfo+6, frm.length); // Position to key information
frm.length+= key_buff_length;
frm.length+= reclength; // row with default values
frm.length+= create_info->extra_size;
@@ -228,7 +228,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
/* write the extra2 segment */
pos = frm_ptr + 64;
- *pos++ = EXTRA2_TABLEDEF_VERSION;
+ compile_time_assert(EXTRA2_TABLEDEF_VERSION != '/');
+ *pos++ = EXTRA2_TABLEDEF_VERSION; // old servers write '/' here
*pos++ = create_info->tabledef_version.length;
memcpy(pos, create_info->tabledef_version.str,
create_info->tabledef_version.length);
@@ -241,7 +242,11 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
*pos++= options_len;
else
{
- DBUG_ASSERT(options_len <= 65535); // FIXME if necessary
+ /*
+ At the moment we support options_len up to 64K.
+ We can easily extend it in the future, if the need arises.
+ */
+ DBUG_ASSERT(options_len <= 65535);
int2store(pos + 1, options_len);
pos+= 3;
}
@@ -255,9 +260,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6));
key_info_length= pack_keys(pos, keys, key_info, data_offset);
- maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
- int2store(forminfo+2,maxlength);
- int4store(fileinfo+10,(ulong) (filepos+maxlength));
+ int2store(forminfo+2, frm.length - filepos);
+ int4store(fileinfo+10, frm.length);
fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
@@ -312,7 +316,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
pos+= key_info[i].parser_name->length + 1;
}
}
- if (forminfo[46] == (uchar)255)
+ if (forminfo[46] == (uchar)255) // New style MySQL 5.5 table comment
{
int2store(pos, create_info->comment.length);
pos+=2;
@@ -378,7 +382,7 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm,
{
// TODO don't write frm for temp tables
if (create_info->tmp_table() &&
- writefrm(path, db, table_name, 0, frm->str, frm->length))
+ writefrm(path, db, table_name, true, frm->str, frm->length))
goto err_handler;
if (thd->variables.keep_files_on_create)
@@ -393,7 +397,7 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm,
}
else
{
- if (writefrm(path, db, table_name, 1, frm->str, frm->length))
+ if (writefrm(path, db, table_name, false, frm->str, frm->length))
goto err_handler;
}
@@ -524,19 +528,18 @@ static bool pack_header(uchar *forminfo, List<Create_field> &create_fields,
COLUMN_COMMENT_MAXLEN);
if (tmp_len < field->comment.length)
{
- if ((current_thd->variables.sql_mode &
- (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
- {
- my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name,
- static_cast<ulong>(COLUMN_COMMENT_MAXLEN));
+ myf myf_warning= ME_JUST_WARNING;
+ ulonglong sql_mode= current_thd->variables.sql_mode;
+
+ if (sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
+ myf_warning= 0;
+
+ my_error(ER_TOO_LONG_FIELD_COMMENT, myf_warning, field->field_name,
+ COLUMN_COMMENT_MAXLEN);
+
+ if (!myf_warning)
DBUG_RETURN(1);
- }
- char warn_buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_FIELD_COMMENT),
- field->field_name,
- static_cast<ulong>(COLUMN_COMMENT_MAXLEN));
- push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TOO_LONG_FIELD_COMMENT, warn_buff);
+
field->comment.length= tmp_len;
}
if (field->vcol_info)
@@ -562,7 +565,7 @@ static bool pack_header(uchar *forminfo, List<Create_field> &create_fields,
expressions saved in the frm file for virtual columns.
*/
vcol_info_length+= field->vcol_info->expr_str.length+
- FRM_VCOL_HEADER_SIZE(field->interval!=NULL);
+ FRM_VCOL_HEADER_SIZE(field->interval);
}
totlength+= field->length;
@@ -890,10 +893,10 @@ static bool pack_fields(uchar *buff, List<Create_field> &create_fields,
*/
if (field->vcol_info && field->vcol_info->expr_str.length)
{
- *buff++= (uchar)(1 + test(field->interval_id));
+ *buff++= (uchar)(1 + test(field->interval));
*buff++= (uchar) field->sql_type;
*buff++= (uchar) field->stored_in_db;
- if (field->interval_id)
+ if (field->interval)
*buff++= (uchar) field->interval_id;
memcpy(buff, field->vcol_info->expr_str.str, field->vcol_info->expr_str.length);
buff+= field->vcol_info->expr_str.length;
diff --git a/sql/unireg.h b/sql/unireg.h
index 0ef69beb08a..5e232becbb2 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -175,11 +175,15 @@
binary value of the 'length' bytes.
Older MariaDB servers can ignore values of unknown types if
- the type code is less than 128. Otherwise older servers are required
+ the type code is less than 128 (EXTRA2_ENGINE_IMPORTANT).
+ Otherwise older (but newer than 10.0.1) servers are required
to report an error.
*/
enum extra2_frm_value_type {
EXTRA2_TABLEDEF_VERSION=0,
+
+#define EXTRA2_ENGINE_IMPORTANT 128
+
EXTRA2_ENGINE_TABLEOPTS=128,
};
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 81b57034e66..2f84cdf5c45 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -3622,9 +3622,10 @@ int ha_federatedx::discover_assisted(handlerton *hton, THD* thd,
goto err2;
query.copy(rdata[1], rlen[1], cs);
- query.append(STRING_WITH_LEN(" CONNECTION=\""), cs);
- query.append(table_s->connect_string.str, table_s->connect_string.length, cs);
- query.append('"');
+ query.append(STRING_WITH_LEN(" CONNECTION='"), cs);
+ query.append_for_single_quote(table_s->connect_string.str,
+ table_s->connect_string.length);
+ query.append('\'');
error= table_s->init_from_sql_statement_string(thd, true,
query.ptr(), query.length());