diff options
-rw-r--r-- | myisam/mi_checksum.c | 2 | ||||
-rw-r--r-- | mysql-test/r/innodb.result | 25 | ||||
-rw-r--r-- | mysql-test/r/myisam.result | 23 | ||||
-rw-r--r-- | mysql-test/r/show_check.result | 2 | ||||
-rw-r--r-- | mysql-test/t/innodb.test | 12 | ||||
-rw-r--r-- | mysql-test/t/myisam.test | 13 | ||||
-rw-r--r-- | mysys/checksum.c | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 66 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 14 |
11 files changed, 138 insertions, 28 deletions
diff --git a/myisam/mi_checksum.c b/myisam/mi_checksum.c index 982f77ee81f..cdbb634c5ff 100644 --- a/myisam/mi_checksum.c +++ b/myisam/mi_checksum.c @@ -50,7 +50,7 @@ ha_checksum mi_checksum(MI_INFO *info, const byte *buf) pos=buf; break; } - crc=my_checksum(crc, pos, length); + crc=my_checksum(crc, pos ? pos : "", length); } return crc; } diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 20cc50dcc61..e1a03b051ce 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1341,3 +1341,28 @@ ERROR HY000: Table storage engine for 't1' doesn't have this option select * from t1; c1 c2 stamp drop table t1; +create table t1 (a int, b varchar(200), c text not null) checksum=1 type=myisam; +create table t2 (a int, b varchar(200), c text not null) checksum=0 type=innodb; +create table t3 (a int, b varchar(200), c text not null) checksum=1 type=innodb; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +insert t3 select * from t1; +checksum table t1, t2, t3, t4 quick; +Table Checksum +test.t1 968604391 +test.t2 NULL +test.t3 NULL +test.t4 NULL +checksum table t1, t2, t3, t4; +Table Checksum +test.t1 968604391 +test.t2 968604391 +test.t3 968604391 +test.t4 NULL +checksum table t1, t2, t3, t4 extended; +Table Checksum +test.t1 968604391 +test.t2 968604391 +test.t3 968604391 +test.t4 NULL +drop table t1,t2,t3; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index fd9ff2c90cf..ece89ca282d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -394,6 +394,23 @@ id select_type table type possible_keys key key_len ref rows Extra drop table t1,t2; CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) TYPE=MyISAM; ERROR 42000: This version of MySQL doesn't yet support 'RTREE INDEX' -DROP TABLE IF EXISTS t1; -Warnings: -Note 1051 Unknown table 't1' +create table t1 (a int, b varchar(200), c text not null) checksum=1; +create table t2 (a int, b varchar(200), c text not null) checksum=0; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +checksum table t1, t2, t3 quick; +Table Checksum +test.t1 968604391 +test.t2 NULL +test.t3 NULL +checksum table t1, t2, t3; +Table Checksum +test.t1 968604391 +test.t2 968604391 +test.t3 NULL +checksum table t1, t2, t3 extended; +Table Checksum +test.t1 968604391 +test.t2 968604391 +test.t3 NULL +drop table t1,t2; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 201d1b541ae..682c48c9c55 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -43,7 +43,7 @@ wait_timeout 28800 show variables like "this_doesn't_exists%"; Variable_name Value show table status from test like "this_doesn't_exists%"; -Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Charset Create_options Comment +Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Charset Checksum Create_options Comment show databases; Database mysql diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index cd3a5693535..72a791b263c 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -920,3 +920,15 @@ replace delayed into t1 (c1, c2) values ( "text1","12"),( "text2","13"),( "text select * from t1; drop table t1; +create table t1 (a int, b varchar(200), c text not null) checksum=1 type=myisam; +create table t2 (a int, b varchar(200), c text not null) checksum=0 type=innodb; +create table t3 (a int, b varchar(200), c text not null) checksum=1 type=innodb; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +insert t3 select * from t1; +checksum table t1, t2, t3, t4 quick; +checksum table t1, t2, t3, t4; +checksum table t1, t2, t3, t4 extended; +#show table status; +drop table t1,t2,t3; + diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 80d46d1ef0c..2bcc5dd7514 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -360,4 +360,15 @@ drop table t1,t2; CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) TYPE=MyISAM; # INSERT INTO t1 VALUES (1,1),(1,1); # DELETE FROM rt WHERE a<1; -DROP TABLE IF EXISTS t1; +# DROP TABLE IF EXISTS t1; + +create table t1 (a int, b varchar(200), c text not null) checksum=1; +create table t2 (a int, b varchar(200), c text not null) checksum=0; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +checksum table t1, t2, t3 quick; +checksum table t1, t2, t3; +checksum table t1, t2, t3 extended; +#show table status; +drop table t1,t2; + diff --git a/mysys/checksum.c b/mysys/checksum.c index 2ae139b81c3..664e768ef4e 100644 --- a/mysys/checksum.c +++ b/mysys/checksum.c @@ -30,9 +30,11 @@ ha_checksum my_checksum(ha_checksum crc, const byte *pos, uint length) { - const byte *end=pos+length; +/* const byte *end=pos+length; for ( ; pos != end ; pos++) crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8)); return crc; +*/ + return (ha_checksum)crc32((uint)crc, (const uchar *)pos, length); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9834d169ac4..5913bee6d0a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -398,7 +398,8 @@ bool check_global_access(THD *thd, ulong want_access); int mysql_backup_table(THD* thd, TABLE_LIST* table_list); int mysql_restore_table(THD* thd, TABLE_LIST* table_list); -int mysql_checksum_table(THD* thd, TABLE_LIST* table_list); +int mysql_checksum_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); int mysql_check_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); int mysql_repair_table(THD* thd, TABLE_LIST* table_list, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0e344756b18..fb74ca7dd71 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2269,7 +2269,7 @@ mysql_execute_command(THD *thd) if (check_db_used(thd,tables) || check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) goto error; /* purecov: inspected */ - res = mysql_checksum_table(thd, tables); + res = mysql_checksum_table(thd, tables, &lex->check_opt); break; } case SQLCOM_REPAIR: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d63a15c13a8..48a99cfaad5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -350,10 +350,10 @@ static int sort_keys(KEY *a, KEY *b) fields List of fields to create keys List of keys to create tmp_table Set to 1 if this is an internal temporary table - (From ALTER TABLE) + (From ALTER TABLE) no_log Don't log the query to binary log. - DESCRIPTION + DESCRIPTION If one creates a temporary table, this is automaticly opened no_log is needed for the case of CREATE ... SELECT, @@ -672,11 +672,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, /* Make SPATIAL to be RTREE by default SPATIAL only on BLOB or at least BINARY, this - actually should be replaced by special GEOM type + actually should be replaced by special GEOM type in near future when new frm file is ready checking for proper key parts number: */ - + if (key_info->flags == HA_SPATIAL) { if (key_info->key_parts != 1) @@ -699,7 +699,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); } - + List_iterator<key_part_spec> cols(key->columns); for (uint column_nr=0 ; (column=cols++) ; column_nr++) { @@ -745,9 +745,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (!column->length ) { - /* + /* BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case - Lately we'll extend this code to support more dimensions + Lately we'll extend this code to support more dimensions */ column->length=4*sizeof(double); } @@ -797,7 +797,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { } else if (column->length > length || - ((f_is_packed(sql_field->pack_flag) || + ((f_is_packed(sql_field->pack_flag) || ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && (key_info->flags & HA_NOSAME))) && column->length != length)) @@ -2588,7 +2588,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, DBUG_RETURN(error > 0 ? -1 : 0); } -int mysql_checksum_table(THD* thd, TABLE_LIST* tables) +int mysql_checksum_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT *check_opt) { TABLE_LIST *table; List<Item> field_list; @@ -2608,9 +2608,10 @@ int mysql_checksum_table(THD* thd, TABLE_LIST* tables) char table_name[NAME_LEN*2+2]; char* db = (table->db) ? table->db : thd->db; bool fatal_error=0; + TABLE *t; strxmov(table_name,db ? db : "",".",table->real_name,NullS); - table->table = open_ltable(thd, table, TL_READ_NO_INSERT); + t=table->table = open_ltable(thd, table, TL_READ_NO_INSERT); #ifdef EMBEDDED_LIBRARY thd->net.last_errno= 0; // these errors shouldn't get client #endif @@ -2618,19 +2619,54 @@ int mysql_checksum_table(THD* thd, TABLE_LIST* tables) protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); - if (!table->table) + if (!t) { protocol->store_null(); thd->net.last_error[0]=0; } else { - table->table->pos_in_table_list= table; + t->pos_in_table_list= table; - if (table->table->file->table_flags() & HA_HAS_CHECKSUM) - protocol->store((ulonglong)table->table->file->checksum()); - else + if (t->file->table_flags() & HA_HAS_CHECKSUM && + !(check_opt->flags & T_EXTEND)) + protocol->store((ulonglong)t->file->checksum()); + else if (!(t->file->table_flags() & HA_HAS_CHECKSUM) && + check_opt->flags & T_QUICK) protocol->store_null(); + else + { + /* calculating table's checksum */ + ha_checksum crc=0; + if (t->file->rnd_init(1)) + protocol->store_null(); + else + { + while (!t->file->rnd_next(t->record[0])) + { + ha_checksum row_crc=0; + if (t->record[0] != t->field[0]->ptr) + row_crc=my_checksum(row_crc, t->record[0], + t->field[0]->ptr - t->record[0]); + + for (uint i=0; i < t->fields; i++ ) + { + Field *f=t->field[i]; + if (f->type() == FIELD_TYPE_BLOB) + { + String tmp; + f->val_str(&tmp,&tmp); + row_crc=my_checksum(row_crc, tmp.ptr(), tmp.length()); + } + else + row_crc=my_checksum(row_crc, f->ptr, f->pack_length()); + } + + crc+=row_crc; + } + protocol->store((ulonglong)crc); + } + } #ifdef EMBEDDED_LIBRARY thd->net.last_errno= 0; // these errors shouldn't get client #endif diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9be2b21debc..a63d70620fd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1080,7 +1080,7 @@ opt_select_from: | select_from select_lock_type; udf_func_type: - /* empty */ { $$ = UDFTYPE_FUNCTION; } + /* empty */ { $$ = UDFTYPE_FUNCTION; } | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }; udf_type: @@ -1547,7 +1547,7 @@ opt_ident: opt_component: /* empty */ { $$.str= 0; $$.length= 0; } | '.' ident { $$=$2; }; - + string_list: text_string { Lex->interval_list.push_back($1); } | string_list ',' text_string { Lex->interval_list.push_back($3); }; @@ -1760,10 +1760,16 @@ checksum: LEX *lex=Lex; lex->sql_command = SQLCOM_CHECKSUM; } - table_list - {} + table_list opt_checksum_type + {} ; +opt_checksum_type: + /* nothing */ { Lex->check_opt.flags= 0; } + | QUICK { Lex->check_opt.flags= T_QUICK; } + | EXTENDED_SYM { Lex->check_opt.flags= T_EXTEND; } + ; + repair: REPAIR opt_no_write_to_binlog table_or_tables { |