summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-03-26 09:41:28 +0100
committerSergei Golubchik <sergii@pisem.net>2014-03-26 09:41:28 +0100
commit88ec8a08f30aa69a48225070ae272ea577f10a2f (patch)
tree78d78e938c608f3ac8e93933d52b4e2c81337205 /sql
parent11b498d6e0972d33dd35df9ef5211f3f969829f3 (diff)
downloadmariadb-git-88ec8a08f30aa69a48225070ae272ea577f10a2f.tar.gz
MDEV-5909 MySQL BUG#11748924 PARTITIONS: TOO-LONG COMMENT CAUSES NO WARNING
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_table.cc104
-rw-r--r--sql/sql_table.h4
-rw-r--r--sql/table.h3
-rw-r--r--sql/unireg.cc78
4 files changed, 99 insertions, 90 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 878e40cbb02..d30eb3169e3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4089,30 +4089,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE);
}
- uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
- key->key_create_info.comment.str,
- key->key_create_info.comment.str +
- key->key_create_info.comment.length,
- INDEX_COMMENT_MAXLEN);
-
- if (tmp_len < key->key_create_info.comment.length)
- {
- if (thd->is_strict_mode())
- {
- my_error(ER_TOO_LONG_INDEX_COMMENT, MYF(0),
- key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN));
- DBUG_RETURN(-1);
- }
- char warn_buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_INDEX_COMMENT),
- key_info->name, static_cast<ulong>(INDEX_COMMENT_MAXLEN));
- /* do not push duplicate warnings */
- if (!thd->get_stmt_da()->has_sql_condition(warn_buff, strlen(warn_buff)))
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_TOO_LONG_INDEX_COMMENT, warn_buff);
-
- key->key_create_info.comment.length= tmp_len;
- }
+ if (validate_comment_length(thd, &key->key_create_info.comment,
+ INDEX_COMMENT_MAXLEN, ER_TOO_LONG_INDEX_COMMENT,
+ key_info->name))
+ DBUG_RETURN(TRUE);
key_info->comment.length= key->key_create_info.comment.length;
if (key_info->comment.length > 0)
@@ -4195,6 +4175,43 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(FALSE);
}
+/**
+ check comment length of table, column, index and partition
+
+ If comment lenght is more than the standard length
+ truncate it and store the comment lenght upto the standard
+ comment length size
+
+ @param thd Thread handle
+ @param[in,out] comment Comment
+ @param max_len Maximum allowed comment length
+ @param err_code Error message
+ @param name Name of commented object
+
+ @return Operation status
+ @retval true Error found
+ @retval false On Success
+*/
+bool validate_comment_length(THD *thd, LEX_STRING *comment, size_t max_len,
+ uint err_code, const char *name)
+{
+ DBUG_ENTER("validate_comment_length");
+ uint tmp_len= my_charpos(system_charset_info, comment->str,
+ comment->str + comment->length, max_len);
+ if (tmp_len < comment->length)
+ {
+ if (thd->is_strict_mode())
+ {
+ my_error(err_code, MYF(0), name, static_cast<ulong>(max_len));
+ DBUG_RETURN(true);
+ }
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, err_code,
+ ER(err_code), name, static_cast<ulong>(max_len));
+ comment->length= tmp_len;
+ }
+ DBUG_RETURN(false);
+}
+
/*
Set table default charset, if not set
@@ -4403,6 +4420,45 @@ handler *mysql_create_frm_image(THD *thd,
char *part_syntax_buf;
uint syntax_len;
handlerton *engine_type;
+ List_iterator<partition_element> part_it(part_info->partitions);
+ partition_element *part_elem;
+
+ while ((part_elem= part_it++))
+ {
+ if (part_elem->part_comment)
+ {
+ LEX_STRING comment= {
+ part_elem->part_comment, strlen(part_elem->part_comment)
+ };
+ if (validate_comment_length(thd, &comment,
+ TABLE_PARTITION_COMMENT_MAXLEN,
+ ER_TOO_LONG_TABLE_PARTITION_COMMENT,
+ part_elem->partition_name))
+ DBUG_RETURN(NULL);
+ part_elem->part_comment[comment.length]= '\0';
+ }
+ if (part_elem->subpartitions.elements)
+ {
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ partition_element *subpart_elem;
+ while ((subpart_elem= sub_it++))
+ {
+ if (subpart_elem->part_comment)
+ {
+ LEX_STRING comment= {
+ subpart_elem->part_comment, strlen(subpart_elem->part_comment)
+ };
+ if (validate_comment_length(thd, &comment,
+ TABLE_PARTITION_COMMENT_MAXLEN,
+ ER_TOO_LONG_TABLE_PARTITION_COMMENT,
+ subpart_elem->partition_name))
+ DBUG_RETURN(NULL);
+ subpart_elem->part_comment[comment.length]= '\0';
+ }
+ }
+ }
+ }
+
if (create_info->tmp_table())
{
my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
diff --git a/sql/sql_table.h b/sql/sql_table.h
index c148ae63b4e..cd1c4293c39 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -267,10 +267,6 @@ bool sync_ddl_log();
void release_ddl_log();
void execute_ddl_log_recovery();
bool execute_ddl_log_entry(THD *thd, uint first_entry);
-bool validate_comment_length(THD *thd, const char *comment_str,
- size_t *comment_len, uint max_len,
- uint err_code, const char *comment_name);
-bool check_duplicate_warning(THD *thd, char *msg, ulong length);
template<typename T> class List;
void promote_first_timestamp_column(List<Create_field> *column_definitions);
diff --git a/sql/table.h b/sql/table.h
index 38a33886869..60a8578fc0b 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2539,6 +2539,9 @@ int rename_file_ext(const char * from,const char * to,const char * ext);
char *get_field(MEM_ROOT *mem, Field *field);
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
+bool validate_comment_length(THD *thd, LEX_STRING *comment, size_t max_len,
+ uint err_code, const char *name);
+
int closefrm(TABLE *table, bool free_share);
void free_blobs(TABLE *table);
void free_field_buffers_larger_than(TABLE *table, uint32 size);
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 4e4af221ddb..aeeba6f4f85 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -40,7 +40,7 @@
#define ALLOCA_THRESHOLD 2048
static uint pack_keys(uchar *,uint, KEY *, ulong);
-static bool pack_header(uchar *, List<Create_field> &, uint, ulong, handler *);
+static bool pack_header(THD *, uchar *, List<Create_field> &, uint, ulong, handler *);
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> &);
@@ -99,7 +99,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, tmp_len, i;
+ uint reclength, key_info_length, i;
ulong key_buff_length;
ulong filepos, data_offset;
uint options_len;
@@ -115,7 +115,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
create_info->null_bits++;
data_offset= (create_info->null_bits + 7) / 8;
- error= pack_header(forminfo, create_fields, create_info->table_options,
+ error= pack_header(thd, forminfo, create_fields, create_info->table_options,
data_offset, db_file);
if (error)
@@ -150,42 +150,9 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
keys, key_info);
DBUG_PRINT("info", ("Options length: %u", options_len));
- /*
- This gives us the byte-position of the character at
- (character-position, not byte-position) TABLE_COMMENT_MAXLEN.
- The trick here is that character-positions start at 0, so the last
- character in a maximum-allowed length string would be at char-pos
- MAXLEN-1; charpos MAXLEN will be the position of the terminator.
- Consequently, bytepos(charpos(MAXLEN)) should be equal to
- comment[length] (which should also be the terminator, or at least
- the first byte after the payload in the strict sense). If this is
- not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the
- string), the string is too long.
-
- For additional credit, realise that UTF-8 has 1-3 bytes before 6.0,
- and 1-4 bytes in 6.0 (6.0 also has UTF-32).
- */
- tmp_len= system_charset_info->cset->charpos(system_charset_info,
- create_info->comment.str,
- create_info->comment.str +
- create_info->comment.length,
- TABLE_COMMENT_MAXLEN);
-
- if (tmp_len < create_info->comment.length)
- {
- if (thd->is_strict_mode())
- {
- my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0),
- table, TABLE_COMMENT_MAXLEN);
- DBUG_RETURN(frm);
- }
- char warn_buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT),
- table, TABLE_COMMENT_MAXLEN);
- push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
- ER_TOO_LONG_TABLE_COMMENT, warn_buff);
- create_info->comment.length= tmp_len;
- }
+ if (validate_comment_length(thd, &create_info->comment, TABLE_COMMENT_MAXLEN,
+ ER_TOO_LONG_TABLE_COMMENT, table))
+ DBUG_RETURN(frm);
/*
If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes,
store the comment in an extra segment (up to TABLE_COMMENT_MAXLEN bytes).
@@ -496,7 +463,8 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
/* Make formheader */
-static bool pack_header(uchar *forminfo, List<Create_field> &create_fields,
+static bool pack_header(THD *thd, uchar *forminfo,
+ List<Create_field> &create_fields,
uint table_options, ulong data_offset, handler *file)
{
uint length,int_count,int_length,no_empty, int_parts;
@@ -521,32 +489,18 @@ static bool pack_header(uchar *forminfo, List<Create_field> &create_fields,
Create_field *field;
while ((field=it++))
{
- uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
- field->comment.str,
- field->comment.str +
- field->comment.length,
- COLUMN_COMMENT_MAXLEN);
- if (tmp_len < field->comment.length)
- {
- myf myf_warning= current_thd->is_strict_mode() ? 0 : ME_JUST_WARNING;
+ if (validate_comment_length(thd, &field->comment, COLUMN_COMMENT_MAXLEN,
+ ER_TOO_LONG_FIELD_COMMENT, field->field_name))
+ DBUG_RETURN(1);
- my_error(ER_TOO_LONG_FIELD_COMMENT, myf_warning, field->field_name,
- COLUMN_COMMENT_MAXLEN);
-
- if (!myf_warning)
- DBUG_RETURN(1);
-
- field->comment.length= tmp_len;
- }
if (field->vcol_info)
{
uint col_expr_maxlen= field->virtual_col_expr_maxlen();
- tmp_len=
- system_charset_info->cset->charpos(system_charset_info,
- field->vcol_info->expr_str.str,
- field->vcol_info->expr_str.str +
- field->vcol_info->expr_str.length,
- col_expr_maxlen);
+ uint tmp_len= my_charpos(system_charset_info,
+ field->vcol_info->expr_str.str,
+ field->vcol_info->expr_str.str +
+ field->vcol_info->expr_str.length,
+ col_expr_maxlen);
if (tmp_len < field->vcol_info->expr_str.length)
{