Commit 79922d94 authored by serg@serg.mylan's avatar serg@serg.mylan

table checksum background:

   my_checksum() mysys function
   NISAM checksum code moved from mysys to isam/ - it's obsolete
   MyISAM checksum code moved to mysys
   table's checksum accessible from sql layer
   SHOW TABLE STATUS shows checksum (WL#646)
code cleanup
parent 6ac0c55c
......@@ -507,6 +507,8 @@ typedef struct st_keycache
ulonglong size;
} KEY_CACHE;
typedef uint32 ha_checksum;
#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
......@@ -749,7 +751,7 @@ extern void print_defaults(const char *conf_file, const char **groups);
extern my_bool my_compress(byte *, ulong *, ulong *);
extern my_bool my_uncompress(byte *, ulong *, ulong *);
extern byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
extern ulong checksum(const byte *mem, uint count);
extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count);
extern uint my_bit_log2(ulong value);
uint my_count_bits(ulonglong v);
extern void my_sleep(ulong m_seconds);
......
......@@ -53,8 +53,6 @@ extern "C" {
#define mi_portable_sizeof_char_ptr 8
typedef uint32 ha_checksum;
/* Param to/from mi_info */
typedef struct st_mi_isaminfo /* Struct from h_info */
......
......@@ -1328,7 +1328,7 @@ int extend;
print_error("Found wrong record at %lu",(ulong) start_recpos);
got_error=1;
}
crc^=checksum(record,info->s->base.reclength);
crc^=_nisam_checksum(record,info->s->base.reclength);
link_used+=info->s->pack.ref_length;
used+=block_info.rec_len+info->s->pack.ref_length;
}
......
......@@ -358,6 +358,7 @@ extern int _nisam_read_pack_record(N_INFO *info,ulong filepos,byte *buf);
extern int _nisam_read_rnd_pack_record(N_INFO*, byte *,ulong, int);
extern int _nisam_pack_rec_unpack(N_INFO *info,byte *to,byte *from,
uint reclength);
extern ulong _nisam_checksum(const byte *mem, uint count);
typedef struct st_sortinfo {
uint key_length;
......
......@@ -453,3 +453,22 @@ static void setup_key_functions(register N_KEYDEF *keyinfo)
}
return;
}
/*
Calculate a long checksum for a memoryblock. Used to verify pack_isam
SYNOPSIS
checksum()
mem Pointer to memory block
count Count of bytes
*/
ulong _nisam_checksum(const byte *mem, uint count)
{
ulong crc;
for (crc= 0; count-- ; mem++)
crc= ((crc << 1) + *((uchar*) mem)) +
test(crc & ((ulong) 1L << (8*sizeof(ulong)-1)));
return crc;
}
......@@ -738,7 +738,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
{
if (! error)
{
crc^=checksum(record,reclength);
crc^=_nisam_checksum(record,reclength);
for (pos=record,count=huff_counts ;
count < end_count ;
count++,
......
......@@ -28,30 +28,29 @@ ha_checksum mi_checksum(MI_INFO *info, const byte *buf)
{
const byte *pos;
const byte *end;
ulong length;
switch (rec->type) {
case FIELD_BLOB:
{
ulong length=_mi_calc_blob_length(rec->length-
length=_mi_calc_blob_length(rec->length-
mi_portable_sizeof_char_ptr,
buf);
memcpy((char*) &pos, buf+rec->length- mi_portable_sizeof_char_ptr,
sizeof(char*));
end=pos+length;
break;
}
case FIELD_VARCHAR:
{
uint length;
length=uint2korr(buf);
pos=buf+2; end=pos+length;
pos=buf+2;
break;
}
default:
pos=buf; end=buf+rec->length;
length=rec->length;
pos=buf;
break;
}
for ( ; pos != end ; pos++)
crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8));
crc=my_checksum(crc, pos, length);
}
return crc;
}
......@@ -59,9 +58,5 @@ ha_checksum mi_checksum(MI_INFO *info, const byte *buf)
ha_checksum mi_static_checksum(MI_INFO *info, const byte *pos)
{
ha_checksum crc;
const byte *end=pos+info->s->base.reclength;
for (crc=0; pos != end; pos++)
crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8));
return crc;
return my_checksum(0, pos, info->s->base.reclength);
}
......@@ -19,19 +19,20 @@
#include "my_sys.h"
/*
Calculate a long checksum for a memoryblock. Used to verify pack_isam
Calculate a long checksum for a memoryblock.
SYNOPSIS
checksum()
mem Pointer to memory block
count Count of bytes
my_checksum()
crc start value for crc
pos pointer to memory block
length length of the block
*/
ulong checksum(const byte *mem, uint count)
ha_checksum my_checksum(ha_checksum crc, const byte *pos, uint length)
{
ulong crc;
for (crc= 0; count-- ; mem++)
crc= ((crc << 1) + *((uchar*) mem)) +
test(crc & ((ulong) 1L << (8*sizeof(ulong)-1)));
const byte *end=pos+length;
for ( ; pos != end ; pos++)
crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8));
return crc;
}
......@@ -236,6 +236,8 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
if (!table->db_record_offset)
int_table_flags|=HA_REC_NOT_IN_SEQ;
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
int_table_flags|=HA_HAS_CHECKSUM;
return (0);
}
......@@ -1398,3 +1400,9 @@ int ha_myisam::ft_read(byte * buf)
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
uint ha_myisam::checksum() const
{
return (uint)file->s->state.checksum;
}
......@@ -64,6 +64,7 @@ class ha_myisam: public handler
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MI_MAX_KEY_LENGTH; }
uint checksum() const;
int open(const char *name, int mode, uint test_if_locked);
int close(void);
......
......@@ -48,32 +48,33 @@
#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */
#define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
#define HA_HAS_GEOMETRY 16
#define HA_NO_INDEX 32 /* No index needed for next/prev */
#define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */
#define HA_NULL_KEY 128 /* One can have keys with NULL */
#define HA_DUPP_POS 256 /* ha_position() gives dupp row */
#define HA_NO_BLOBS 512 /* Doesn't support blobs */
#define HA_BLOB_KEY (HA_NO_BLOBS*2) /* key on blob */
#define HA_AUTO_PART_KEY (HA_BLOB_KEY*2)
#define HA_REQUIRE_PRIMARY_KEY (HA_AUTO_PART_KEY*2)
#define HA_NOT_EXACT_COUNT (HA_REQUIRE_PRIMARY_KEY*2)
#define HA_NO_WRITE_DELAYED (HA_NOT_EXACT_COUNT*2)
#define HA_PRIMARY_KEY_IN_READ_INDEX (HA_NO_WRITE_DELAYED*2)
#define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2)
#define HA_NOT_READ_AFTER_KEY (HA_DROP_BEFORE_CREATE*2)
#define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2)
#define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2)
#define HA_NO_PREFIX_CHAR_KEYS (HA_NO_TEMP_TABLES*2)
#define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2)
#define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2)
#define HA_NO_AUTO_INCREMENT (HA_CAN_SQL_HANDLER*2)
#define HA_HAS_GEOMETRY (1 << 4)
#define HA_NO_INDEX (1 << 5) /* No index needed for next/prev */
#define HA_KEY_READ_WRONG_STR (1 << 6) /* keyread returns converted strings */
#define HA_NULL_KEY (1 << 7) /* One can have keys with NULL */
#define HA_DUPP_POS (1 << 8) /* ha_position() gives dupp row */
#define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
#define HA_BLOB_KEY (1 << 10) /* key on blob */
#define HA_AUTO_PART_KEY (1 << 11)
#define HA_REQUIRE_PRIMARY_KEY (1 << 12)
#define HA_NOT_EXACT_COUNT (1 << 13)
#define HA_NO_WRITE_DELAYED (1 << 14)
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
#define HA_DROP_BEFORE_CREATE (1 << 16)
#define HA_NOT_READ_AFTER_KEY (1 << 17)
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
#define HA_NO_TEMP_TABLES (1 << 19)
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
#define HA_CAN_FULLTEXT (1 << 21)
#define HA_CAN_SQL_HANDLER (1 << 22)
#define HA_NO_AUTO_INCREMENT (1 << 23)
#define HA_HAS_CHECKSUM (1 << 24)
/*
Next record gives next record according last record read (even
if database is updated after read). Not used at this point.
*/
#define HA_LASTKEY_ORDER (HA_NO_AUTO_INCREMENT*2)
#define HA_LASTKEY_ORDER (1 << 25)
/* bits in index_flags(index_number) for what you can do with index */
......@@ -304,8 +305,8 @@ class handler :public Sql_alloc
virtual bool check_and_repair(THD *thd) {return 1;}
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
/*
restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
......@@ -340,6 +341,7 @@ class handler :public Sql_alloc
virtual uint max_key_part_length() { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
virtual bool low_byte_first() const { return 1; }
virtual uint checksum() const { return 0; }
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
......@@ -354,12 +356,11 @@ class handler :public Sql_alloc
/* Type of table for caching query */
virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
/*
Is query with this cable cachable (have sense only for ASKTRANSACT
Is query with this table cachable (have sense only for ASKTRANSACT
tables)
*/
static bool caching_allowed(THD* thd, char* table_key,
uint key_length, uint8 cahe_type);
};
/* Some extern variables used with handlers */
......
......@@ -447,15 +447,21 @@ typedef struct st_lex
SELECT_LEX *all_selects_list;
uchar *ptr,*tok_start,*tok_end,*end_of_query;
char *length,*dec,*change,*name;
char *help_arg;
char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */
time_t purge_time; /* For PURGE MASTER LOGS BEFORE */
char* x509_subject,*x509_issuer,*ssl_cipher;
char* found_colon; /* For multi queries - next query */
enum SSL_type ssl_type; /* defined in violite.h */
String *wild;
sql_exchange *exchange;
select_result *result;
Item *default_value, *comment;
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
CHARSET_INFO *charset;
SQL_LIST *gorder_list;
List<key_part_spec> col_list;
List<key_part_spec> ref_list;
......@@ -473,11 +479,6 @@ typedef struct st_lex
SQL_LIST proc_list, auxilliary_table_list;
TYPELIB *interval;
create_field *last_field;
Item *default_value, *comment;
uint uint_geom_type;
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info;
......@@ -486,6 +487,7 @@ typedef struct st_lex
ulong thread_id,type;
enum_sql_command sql_command;
thr_lock_type lock_option;
enum SSL_type ssl_type; /* defined in violite.h */
enum my_lex_states next_state;
enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
......@@ -493,17 +495,15 @@ typedef struct st_lex
enum ha_rkey_function ha_rkey_mode;
enum enum_enable_or_disable alter_keys_onoff;
enum enum_var_type option_type;
uint uint_geom_type;
uint grant, grant_tot_col, which_columns;
uint fk_delete_opt, fk_update_opt, fk_match_option;
uint param_count;
uint slave_thd_opt;
bool drop_primary, drop_if_exists, drop_temporary, local_file;
bool in_comment, ignore_space, verbose, simple_alter, no_write_to_binlog;
bool derived_tables, describe;
bool safe_to_cache_query;
uint slave_thd_opt;
CHARSET_INFO *charset;
char *help_arg;
SQL_LIST *gorder_list;
st_lex() {}
inline void uncacheable()
{
......
......@@ -2349,7 +2349,7 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
Constant tables are ignored.
To avoid bad matches, we don't make ref_table_rows less than 100.
*/
keyuse->ref_table_rows= ~(table_map) 0; // If no ref
keyuse->ref_table_rows= ~(ha_rows) 0; // If no ref
if (keyuse->used_tables &
(map= (keyuse->used_tables & ~join->const_table_map &
~OUTER_REF_TABLE_BIT)))
......
......@@ -503,6 +503,8 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Charset",32));
item->maybe_null=1;
field_list.push_back(item=new Item_int("Checksum",(longlong) 1,21));
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Create_options",255));
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Comment",80));
......@@ -588,6 +590,10 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
}
str= (table->table_charset ? table->table_charset->name : "default");
protocol->store(str, system_charset_info);
if (file->table_flags() & HA_HAS_CHECKSUM)
protocol->store((ulonglong)file->checksum());
else
protocol->store_null(); // Checksum
{
char option_buff[350],*ptr;
ptr=option_buff;
......
......@@ -730,12 +730,14 @@ verb_clause:
| describe
| do
| drop
| flush
| grant
| handler
| help
| insert
| flush
| kill
| load
| lock
| kill
| optimize
| preload
| purge
......@@ -748,15 +750,14 @@ verb_clause:
| rollback
| select
| set
| show
| slave
| start
| show
| truncate
| handler
| unlock
| update
| use
| help;
;
/* help */
......@@ -3327,7 +3328,7 @@ do: DO_SYM
*/
drop:
DROP opt_temporary TABLE_SYM if_exists table_list opt_restrict
DROP opt_temporary table_or_tables if_exists table_list opt_restrict
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DROP_TABLE;
......@@ -5228,3 +5229,4 @@ subselect_end:
LEX *lex=Lex;
lex->current_select = lex->current_select->return_after_parsing();
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment