summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gluh@eagle.intranet.mysql.r18.ru>2006-06-29 18:39:34 +0500
committerunknown <gluh@eagle.intranet.mysql.r18.ru>2006-06-29 18:39:34 +0500
commit8703b22e167c706d5a8c77a1e24948b4db3fafb3 (patch)
treee1df56628e6e5f088a1482f6457da748a9c1c141
parenta7f9f7ae743efca9b1f405773416d19f9ebaf3c2 (diff)
downloadmariadb-git-8703b22e167c706d5a8c77a1e24948b4db3fafb3.tar.gz
Fix for bug#13934 Silent truncation of table comments
Table comment: issue a warning(error in traditional mode) if length of comment > 60 symbols Column comment: issue a warning(error in traditional mode) if length of comment > 255 symbols Table 'comment' is changed from char* to LEX_STRING mysql-test/r/strict.result: test case mysql-test/t/strict.test: test case sql/handler.h: Table 'comment' is changed from char* to LEX_STRING sql/sql_show.cc: Table 'comment' is changed from char* to LEX_STRING sql/sql_table.cc: Table 'comment' is changed from char* to LEX_STRING sql/sql_yacc.yy: Table 'comment' is changed from char* to LEX_STRING sql/table.cc: Table 'comment' is changed from char* to LEX_STRING sql/table.h: Table 'comment' is changed from char* to LEX_STRING sql/unireg.cc: Fix for bug#13934 Silent truncation of table comments Table comment: issue a warning(error in traditional mode) if length of comment > 60 symbols Column comment: issue a warning(error in traditional mode) if length of comment > 255 symbols
-rw-r--r--mysql-test/r/strict.result46
-rw-r--r--mysql-test/t/strict.test39
-rw-r--r--sql/handler.h3
-rw-r--r--sql/sql_show.cc13
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc4
-rw-r--r--sql/table.h2
-rw-r--r--sql/unireg.cc49
9 files changed, 150 insertions, 15 deletions
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 271cd7bf486..d0cf11d0511 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1298,3 +1298,49 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t2,t1;
set @@sql_mode= @org_mode;
+set @@sql_mode='traditional';
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*123456789*';
+ERROR HY000: Too long comment for table 't1'
+create table t1 (
+i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+ERROR HY000: Too long comment for field 'i'
+set @@sql_mode= @org_mode;
+create table t1
+(i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+Warnings:
+Warning 1105 Unknown error
+select column_name, column_comment from information_schema.columns where
+table_schema = 'test' and table_name = 't1';
+column_name column_comment
+i 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+drop table t1;
+set names utf8;
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*123456789*';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
+drop table t1;
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 5044a20ae9f..ce269b42ee9 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -1155,3 +1155,42 @@ create table t2 select date from t1;
show create table t2;
drop table t2,t1;
set @@sql_mode= @org_mode;
+
+#
+# Bug #13934 Silent truncation of table comments
+#
+set @@sql_mode='traditional';
+--error 1105
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*123456789*';
+--error 1105
+create table t1 (
+i int comment
+'123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+set @@sql_mode= @org_mode;
+create table t1
+(i int comment
+ '123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*
+ 123456789*123456789*123456789*123456789*');
+
+select column_name, column_comment from information_schema.columns where
+table_schema = 'test' and table_name = 't1';
+drop table t1;
+
+set names utf8;
+create table t1 (i int)
+comment '123456789*123456789*123456789*123456789*123456789*123456789*';
+show create table t1;
+drop table t1;
diff --git a/sql/handler.h b/sql/handler.h
index 31aac075a5e..6efb6e9e470 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -428,7 +428,8 @@ typedef struct st_ha_create_information
{
CHARSET_INFO *table_charset, *default_table_charset;
LEX_STRING connect_string;
- const char *comment,*password;
+ LEX_STRING comment;
+ const char *password;
const char *data_file_name, *index_file_name;
const char *alias;
ulonglong max_rows,min_rows;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 71a6b0acde9..34b5bdd142a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1080,10 +1080,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(ha_row_type[(uint) share->row_type]);
}
table->file->append_create_info(packet);
- if (share->comment && share->comment[0])
+ if (share->comment.length)
{
packet->append(STRING_WITH_LEN(" COMMENT="));
- append_unescaped(packet, share->comment, strlen(share->comment));
+ append_unescaped(packet, share->comment.str, share->comment.length);
}
if (share->connect_string.length)
{
@@ -2547,11 +2547,14 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
(uint) (ptr-option_buff)-1), cs);
{
char *comment;
- comment= show_table->file->update_table_comment(share->comment);
+ comment= show_table->file->update_table_comment(share->comment.str);
if (comment)
{
- table->field[20]->store(comment, strlen(comment), cs);
- if (comment != share->comment)
+ table->field[20]->store(comment,
+ (comment == share->comment.str ?
+ share->comment.length :
+ strlen(comment)), cs);
+ if (comment != share->comment.str)
my_free(comment, MYF(0));
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 91c71193df2..1d69c69b5cf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3598,8 +3598,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
create_info->db_type=new_db_type;
- if (!create_info->comment)
- create_info->comment= table->s->comment;
+ if (!create_info->comment.str)
+ {
+ create_info->comment.str= table->s->comment.str;
+ create_info->comment.length= table->s->comment.length;
+ }
table->file->update_create_info(create_info);
if ((create_info->table_options &
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 256b0b48c64..fc11157bdf7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2529,7 +2529,7 @@ create_table_option:
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
| AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; }
- | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
+ | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
| AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
| PACK_KEYS_SYM opt_equal ulong_num
{
diff --git a/sql/table.cc b/sql/table.cc
index 9ec9463c33c..1cace0d864d 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -410,7 +410,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
int_length= uint2korr(head+274);
share->null_fields= uint2korr(head+282);
com_length= uint2korr(head+284);
- share->comment= strdup_root(&outparam->mem_root, (char*) head+47);
+ share->comment.length= (int) (head[46]);
+ share->comment.str= strmake_root(&outparam->mem_root, (char*) head+47,
+ share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length));
diff --git a/sql/table.h b/sql/table.h
index ebb4481ef3a..d23d58e964f 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -124,7 +124,7 @@ typedef struct st_table_share
#endif
uint *blob_field; /* Index to blobs in Field arrray*/
byte *default_values; /* row with default values */
- char *comment; /* Comment about table */
+ LEX_STRING comment; /* Comment about table */
CHARSET_INFO *table_charset; /* Default charset of string fields */
/* A pair "database_name\0table_name\0", widely used as simply a db name */
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 0ab77462f61..3a139aea4c7 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -76,7 +76,7 @@ bool mysql_create_frm(THD *thd, my_string file_name,
handler *db_file)
{
LEX_STRING str_db_type;
- uint reclength,info_length,screens,key_info_length,maxlength;
+ uint reclength, info_length, screens, key_info_length, maxlength, tmp_len;
ulong key_buff_length;
File file;
ulong filepos, data_offset;
@@ -143,10 +143,30 @@ bool mysql_create_frm(THD *thd, my_string file_name,
fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
- strmake((char*) forminfo+47,create_info->comment ? create_info->comment : "",
- 60);
- forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment
+ tmp_len= system_charset_info->cset->charpos(system_charset_info,
+ create_info->comment.str,
+ create_info->comment.str +
+ create_info->comment.length, 60);
+ if (tmp_len < create_info->comment.length)
+ {
+ char buff[128];
+ (void) my_snprintf(buff, sizeof(buff), "Too long comment for table '%s'",
+ table);
+ if ((thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
+ {
+ my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ goto err;
+ }
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ create_info->comment.length= tmp_len;
+ }
+
+ strmake((char*) forminfo+47, create_info->comment.str ?
+ create_info->comment.str : "", create_info->comment.length);
+ forminfo[46]=(uchar) create_info->comment.length;
if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
my_pwrite(file,(byte*) keybuff,key_info_length,
(ulong) uint2korr(fileinfo+6),MYF_RW))
@@ -449,6 +469,27 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
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, 255);
+ if (tmp_len < field->comment.length)
+ {
+ char buff[128];
+ (void) my_snprintf(buff,sizeof(buff), "Too long comment for field '%s'",
+ field->field_name);
+ if ((current_thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
+ {
+ my_message(ER_UNKNOWN_ERROR, buff, MYF(0));
+ DBUG_RETURN(1);
+ }
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), buff);
+ field->comment.length= tmp_len;
+ }
+
totlength+= field->length;
com_length+= field->comment.length;
if (MTYP_TYPENR(field->unireg_check) == Field::NOEMPTY ||