summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--myisam/mi_checksum.c2
-rw-r--r--mysql-test/r/innodb.result25
-rw-r--r--mysql-test/r/myisam.result23
-rw-r--r--mysql-test/r/show_check.result2
-rw-r--r--mysql-test/t/innodb.test12
-rw-r--r--mysql-test/t/myisam.test13
-rw-r--r--mysys/checksum.c4
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_table.cc66
-rw-r--r--sql/sql_yacc.yy14
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
{