diff options
-rw-r--r-- | Docs/manual.texi | 3 | ||||
-rw-r--r-- | include/my_base.h | 8 | ||||
-rw-r--r-- | libmysql/net.c | 52 | ||||
-rw-r--r-- | mysql-test/r/func_misc.result | 4 | ||||
-rw-r--r-- | sql/field.cc | 4 | ||||
-rw-r--r-- | sql/field.h | 4 | ||||
-rw-r--r-- | sql/filesort.cc | 2 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 17 | ||||
-rw-r--r-- | sql/ha_heap.h | 22 | ||||
-rw-r--r-- | sql/ha_innodb.h | 16 | ||||
-rw-r--r-- | sql/ha_isam.cc | 2 | ||||
-rw-r--r-- | sql/ha_isam.h | 10 | ||||
-rw-r--r-- | sql/ha_isammrg.h | 3 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 2 | ||||
-rw-r--r-- | sql/ha_myisam.h | 12 | ||||
-rw-r--r-- | sql/ha_myisammrg.h | 14 | ||||
-rw-r--r-- | sql/handler.cc | 4 | ||||
-rw-r--r-- | sql/handler.h | 76 | ||||
-rw-r--r-- | sql/log.cc | 1 | ||||
-rw-r--r-- | sql/net_serv.cc | 7 | ||||
-rw-r--r-- | sql/opt_range.cc | 11 | ||||
-rw-r--r-- | sql/opt_sum.cc | 22 | ||||
-rw-r--r-- | sql/records.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_handler.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 12 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 22 | ||||
-rw-r--r-- | sql/structs.h | 1 | ||||
-rw-r--r-- | sql/table.cc | 26 | ||||
-rw-r--r-- | sql/unireg.cc | 11 |
32 files changed, 222 insertions, 158 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index f1d730f5e04..ca3ffdff719 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -6184,6 +6184,9 @@ and are configured with the following compilers and options: @item SunOS 5.6 i86pc with @code{gcc} 2.8.1 @code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex} +@item Solaris 2.8 sparc with @code{gcc 2.95.3} +@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex "--with-server-suffix=" --enable-thread-safe-client --enable-local-infile --enable-assembler --disable-shared} + @item Linux 2.0.33 i386 with @code{pgcc} 2.90.29 (@code{egcs} 1.0.3a) @code{CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentium -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --with-extra-charsets=complex} diff --git a/include/my_base.h b/include/my_base.h index 68f33147145..ae8fc2204d5 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -67,9 +67,11 @@ enum ha_rkey_function { /* Key algorithm types */ enum ha_key_alg { - HA_KEY_ALG_BTREE=0, /* B-tree, default one */ - HA_KEY_ALG_RTREE=1, /* R-tree, for spatial searches */ - HA_KEY_ALG_HASH=2 /* HASH keys (HEAP tables) */ + HA_KEY_ALG_UNDEF= 0, /* Not specified (old file) */ + HA_KEY_ALG_BTREE= 1, /* B-tree, default one */ + HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */ + HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */ + HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */ }; /* The following is parameter to ha_extra() */ diff --git a/libmysql/net.c b/libmysql/net.c index 666c572ccee..0d6e548a873 100644 --- a/libmysql/net.c +++ b/libmysql/net.c @@ -54,32 +54,32 @@ ulong max_allowed_packet=65536; extern ulong net_read_timeout,net_write_timeout; extern uint test_flags; +#define USE_QUERY_CACHE +extern void query_cache_insert(NET *net, const char *packet, ulong length); #else ulong max_allowed_packet=16*1024*1024L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; #endif -#ifdef __WIN__ -/* The following is because alarms doesn't work on windows. */ -#undef MYSQL_SERVER +#if defined(__WIN__) || !defined(MYSQL_SERVER) + /* The following is because alarms doesn't work on windows. */ +#define NO_ALARM #endif - -#ifdef MYSQL_SERVER + +#ifndef NO_ALARM #include "my_pthread.h" void sql_print_error(const char *format,...); #define RETRY_COUNT mysqld_net_retry_count extern ulong mysqld_net_retry_count; extern ulong bytes_sent, bytes_received; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; - -extern void query_cache_insert(NET *net, const char *packet, ulong length); #else #undef statistic_add #define statistic_add(A,B,C) #define DONT_USE_THR_ALARM #define RETRY_COUNT 1 -#endif /* MYSQL_SERVER */ +#endif /* NO_ALARM */ #include "thr_alarm.h" @@ -167,7 +167,7 @@ static my_bool net_realloc(NET *net, ulong length) void net_clear(NET *net) { -#ifndef EXTRA_DEBUG +#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY) int count; /* One may get 'unused' warn */ bool is_blocking=vio_is_blocking(net->vio); if (is_blocking) @@ -322,15 +322,16 @@ net_real_write(NET *net,const char *packet,ulong len) long int length; char *pos,*end; thr_alarm_t alarmed; -#if defined(MYSQL_SERVER) +#ifndef NO_ALARM ALARM alarm_buff; #endif uint retry_count=0; my_bool net_blocking = vio_is_blocking(net->vio); DBUG_ENTER("net_real_write"); -#ifdef MYSQL_SERVER - query_cache_insert(net, packet, len); +#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE) + if (net->query_cache_query != 0) + query_cache_insert(net, packet, len); #endif if (net->error == 2) @@ -370,13 +371,13 @@ net_real_write(NET *net,const char *packet,ulong len) #endif /* HAVE_COMPRESS */ /* DBUG_DUMP("net",packet,len); */ -#ifdef MYSQL_SERVER +#ifndef NO_ALARM thr_alarm_init(&alarmed); if (net_blocking) thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff); #else alarmed=0; -#endif /* MYSQL_SERVER */ +#endif /* NO_ALARM */ pos=(char*) packet; end=pos+len; while (pos != end) @@ -458,8 +459,7 @@ net_real_write(NET *net,const char *packet,ulong len) ** Read something from server/clinet *****************************************************************************/ -#ifdef MYSQL_SERVER - +#ifndef NO_ALARM /* Help function to clear the commuication buffer when we get a too big packet @@ -492,7 +492,7 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) statistic_add(bytes_received,length,&LOCK_bytes_received); } } -#endif /* MYSQL_SERVER */ +#endif /* NO_ALARM */ /* @@ -509,7 +509,7 @@ my_real_read(NET *net, ulong *complen) uint i,retry_count=0; ulong len=packet_error; thr_alarm_t alarmed; -#if defined(MYSQL_SERVER) +#ifndef NO_ALARM ALARM alarm_buff; #endif my_bool net_blocking=vio_is_blocking(net->vio); @@ -519,10 +519,10 @@ my_real_read(NET *net, ulong *complen) net->reading_or_writing=1; thr_alarm_init(&alarmed); -#ifdef MYSQL_SERVER +#ifndef NO_ALARM if (net_blocking) thr_alarm(&alarmed,net->timeout,&alarm_buff); -#endif /* MYSQL_SERVER */ +#endif /* NO_ALARM */ pos = net->buff + net->where_b; /* net->packet -4 */ for (i=0 ; i < 2 ; i++) @@ -645,7 +645,7 @@ my_real_read(NET *net, ulong *complen) { if (net_realloc(net,helping)) { -#ifdef MYSQL_SERVER +#ifndef NO_ALARM if (i == 1) my_net_skip_rest(net, (uint32) len, &alarmed); #endif @@ -814,3 +814,13 @@ my_net_read(NET *net) #endif /* HAVE_COMPRESS */ return len; } + +int net_request_file(NET* net, const char* fname) +{ + char tmp [FN_REFLEN+1],*end; + DBUG_ENTER("net_request_file"); + tmp[0] = (char) 251; /* NULL_LENGTH */ + end=strnmov(tmp+1,fname,sizeof(tmp)-2); + DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) || + net_flush(net)); +} diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 575f5e5429a..4eed80c4cc9 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -3,10 +3,10 @@ format(1.5555,0) format(123.5555,1) format(1234.5555,2) format(12345.5555,3) for 2 123.6 1,234.56 12,345.556 123,456.5555 1,234,567.55550 12,345.24 select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255")); inet_ntoa(inet_aton("255.255.255.255.255.255.255.255")) -255.255.255.255.255.255.255.255 +NULL select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255"); inet_aton("255.255.255.255.255") inet_aton("255.255.1.255") inet_aton("0.1.255") 1099511627775 4294902271 511 select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511); inet_ntoa(1099511627775) inet_ntoa(4294902271) inet_ntoa(511) -255.255.255.255.255 255.255.1.255 0.0.1.255 +NULL 255.255.1.255 0.0.1.255 diff --git a/sql/field.cc b/sql/field.cc index 32679f549ba..23419a53d3d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -362,9 +362,9 @@ void Field::store_time(TIME *ltime,timestamp_type type) } -bool Field::optimize_range() +bool Field::optimize_range(uint idx) { - return test(table->file->option_flag() & HA_READ_NEXT); + return test(table->file->index_flags(idx) & HA_READ_NEXT); } /**************************************************************************** diff --git a/sql/field.h b/sql/field.h index a9b257f0c3a..df31721186e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -107,7 +107,7 @@ public: inline bool real_maybe_null(void) { return null_ptr != 0; } virtual void make_field(Send_field *)=0; virtual void sort_string(char *buff,uint length)=0; - virtual bool optimize_range(); + virtual bool optimize_range(uint idx); virtual bool store_for_compare() { return 0; } Field *new_field(MEM_ROOT *root, struct st_table *new_table) { @@ -944,7 +944,7 @@ public: uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return FIELD_TYPE_ENUM; } virtual bool zero_pack() const { return 0; } - bool optimize_range() { return 0; } + bool optimize_range(uint idx) { return 0; } bool binary() const { return 0; } bool eq_def(Field *field); }; diff --git a/sql/filesort.cc b/sql/filesort.cc index 7e3d1c96f57..8f3e8b10629 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -303,7 +303,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, ref_pos= ref_buff; quick_select=select && select->quick; record=0; - flag= ((!indexfile && file->option_flag() & HA_REC_NOT_IN_SEQ) + flag= ((!indexfile && file->table_flags() & HA_REC_NOT_IN_SEQ) || quick_select); if (indexfile || flag) ref_pos= &file->ref[0]; diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index f30d4e12d6d..f56ee5ef1a9 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -52,7 +52,7 @@ class ha_berkeley: public handler u_int32_t *key_type; DBC *cursor; BDB_SHARE *share; - ulong int_option_flag; + ulong int_table_flags; ulong alloced_rec_buff_length; ulong changed_rows; uint primary_key,last_dup_key, hidden_primary_key, version; @@ -86,13 +86,12 @@ class ha_berkeley: public handler public: ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), - int_option_flag(HA_READ_NEXT | HA_READ_PREV | - HA_REC_NOT_IN_SEQ | - HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY | - HA_BLOB_KEY | HA_NOT_EXACT_COUNT | - HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | - HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), + int_table_flags(HA_REC_NOT_IN_SEQ | + HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY | + HA_BLOB_KEY | HA_NOT_EXACT_COUNT | + HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | + HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) { } @@ -100,7 +99,7 @@ class ha_berkeley: public handler const char *table_type() const { return "BerkeleyDB"; } const char *index_type(uint key_number) { return "BTREE"; } const char **bas_ext() const; - ulong option_flag() const { return int_option_flag; } + ulong table_flags(void) const { return int_table_flags; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY-1; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_heap.h b/sql/ha_heap.h index c8f29dea53c..aa675cfffea 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -31,12 +31,24 @@ class ha_heap: public handler ha_heap(TABLE *table): handler(table), file(0) {} ~ha_heap() {} const char *table_type() const { return "HEAP"; } - const char *index_type(uint key_number) { return "HASH"; } + const char *index_type(uint inx) + { + return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" : + "HASH"); + } const char **bas_ext() const; - ulong option_flag() const - { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX | - HA_WRONG_ASCII_ORDER | HA_KEYPOS_TO_RNDPOS | HA_NO_BLOBS | - HA_NULL_KEY | HA_REC_NOT_IN_SEQ | HA_NOT_READ_PREFIX_LAST); } + ulong table_flags() const + { + return (HA_READ_RND_SAME | HA_NO_INDEX | HA_KEYPOS_TO_RNDPOS | + HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ | + HA_NOT_READ_PREFIX_LAST | HA_NO_AUTO_INCREMENT); + } + ulong index_flags(uint inx) const + { + return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? + (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER) : + (HA_ONLY_WHOLE_INDEX | HA_WRONG_ASCII_ORDER)); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index a0f3ea28d2c..b2aa963f91a 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -54,7 +54,7 @@ class ha_innobase: public handler to Innodb format */ uint ref_stored_len; /* length of the key value stored to 'ref' buffer of the handle, if any */ - ulong int_option_flag; + ulong int_table_flags; uint primary_key; uint last_dup_key; ulong start_of_scan; /* this is set to 1 when we are @@ -75,15 +75,14 @@ class ha_innobase: public handler /* Init values for the class: */ public: ha_innobase(TABLE *table): handler(table), - int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | - HA_REC_NOT_IN_SEQ | + int_table_flags(HA_REC_NOT_IN_SEQ | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | + HA_HAVE_KEY_READ_ONLY | HA_NULL_KEY | HA_NOT_EXACT_COUNT | HA_NO_WRITE_DELAYED | HA_PRIMARY_KEY_IN_READ_INDEX | - HA_DROP_BEFORE_CREATE | HA_NOT_READ_PREFIX_LAST | + HA_DROP_BEFORE_CREATE | HA_NO_PREFIX_CHAR_KEYS | HA_TABLE_SCAN_ON_INDEX), last_dup_key((uint) -1), @@ -95,7 +94,12 @@ class ha_innobase: public handler const char* table_type() const { return("InnoDB");} const char *index_type(uint key_number) { return "BTREE"; } const char** bas_ext() const; - ulong option_flag() const { return int_option_flag; } + ulong table_flags() const { return int_table_flags; } + ulong index_flags(uint idx) const + { + return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | + HA_NOT_READ_PREFIX_LAST); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 7c9c7a64c9d..55d24f5edb9 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -52,7 +52,7 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked) if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) (void) nisam_extra(file,HA_EXTRA_WAIT_LOCK); if (!table->db_record_offset) - int_option_flag|=HA_REC_NOT_IN_SEQ; + int_table_flags|=HA_REC_NOT_IN_SEQ; return (0); } diff --git a/sql/ha_isam.h b/sql/ha_isam.h index 4194632ddbe..bae9700f149 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -26,13 +26,13 @@ class ha_isam: public handler { N_INFO *file; - uint int_option_flag; + uint int_table_flags; public: ha_isam(TABLE *table): handler(table), file(0), - int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME | - HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | + int_table_flags(HA_READ_RND_SAME | + HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_HAVE_KEY_READ_ONLY | HA_KEY_READ_WRONG_STR | HA_DUPP_POS | HA_NOT_DELETE_WITH_CACHE) {} @@ -40,7 +40,7 @@ class ha_isam: public handler const char *table_type() const { return "ISAM"; } const char *index_type(uint key_number) { return "BTREE"; } const char **bas_ext() const; - ulong option_flag() const { return int_option_flag; } + ulong table_flags() const { return int_table_flags; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return N_MAXKEY; } uint max_key_parts() const { return N_MAXKEY_SEG; } diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h index 1ee0b0e2547..bbe75a74db8 100644 --- a/sql/ha_isammrg.h +++ b/sql/ha_isammrg.h @@ -32,9 +32,10 @@ class ha_isammrg: public handler ~ha_isammrg() {} const char *table_type() const { return "MRG_ISAM"; } const char **bas_ext() const; - ulong option_flag() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | + ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_NOT_READ_PREFIX_LAST | HA_REC_NOT_IN_SEQ); } + ulong index_flags(uint idx) const { return 0; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return 0; } uint max_key_parts() const { return 0; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index df55cdd0033..50088c238e0 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -223,7 +223,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) VOID(mi_extra(file,HA_EXTRA_WAIT_LOCK)); if (!table->db_record_offset) - int_option_flag|=HA_REC_NOT_IN_SEQ; + int_table_flags|=HA_REC_NOT_IN_SEQ; return (0); } diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 75655a2b505..d304085fdd5 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -37,18 +37,16 @@ extern ulong myisam_recover_options; class ha_myisam: public handler { MI_INFO *file; - uint int_option_flag; + uint int_table_flags; char *data_file_name, *index_file_name; bool enable_activate_all_index; int repair(THD *thd, MI_CHECK ¶m, bool optimize); public: ha_myisam(TABLE *table): handler(table), file(0), - int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME | - HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY | - HA_NULL_KEY | - HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | + int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_HAVE_KEY_READ_ONLY | + HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY), enable_activate_all_index(1) {} @@ -56,7 +54,7 @@ class ha_myisam: public handler const char *table_type() const { return "MyISAM"; } const char *index_type(uint key_number); const char **bas_ext() const; - ulong option_flag() const { return int_option_flag; } + ulong table_flags() const { return int_table_flags; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MI_MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 2ab3a807543..ed2817f3ca6 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -32,13 +32,13 @@ class ha_myisammrg: public handler ~ha_myisammrg() {} const char *table_type() const { return "MRG_MyISAM"; } const char **bas_ext() const; - ulong option_flag() const - { return (HA_REC_NOT_IN_SEQ | HA_READ_NEXT | - HA_READ_PREV | HA_READ_RND_SAME | - HA_HAVE_KEY_READ_ONLY | - HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | - HA_LASTKEY_ORDER | HA_READ_NOT_EXACT_KEY | - HA_NULL_KEY | HA_BLOB_KEY); } + ulong table_flags() const + { + return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | + HA_HAVE_KEY_READ_ONLY | HA_KEYPOS_TO_RNDPOS | + HA_LASTKEY_ORDER | + HA_NULL_KEY | HA_BLOB_KEY); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MI_MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/handler.cc b/sql/handler.cc index 178f631569d..7947ae5a9f0 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -547,7 +547,7 @@ int handler::read_first_row(byte * buf, uint primary_key) scanning the table. */ if (deleted < 10 || primary_key >= MAX_KEY || - !(option_flag() & HA_READ_ORDER)) + !(index_flags(primary_key) & HA_READ_ORDER)) { (void) rnd_init(); while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; @@ -835,7 +835,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, if (update_create_info) { update_create_info_from_table(create_info, &table); - if (table.file->option_flag() & HA_DROP_BEFORE_CREATE) + if (table.file->table_flags() & HA_DROP_BEFORE_CREATE) table.file->delete_table(name); // Needed for BDB tables } error=table.file->create(name,&table,create_info); diff --git a/sql/handler.h b/sql/handler.h index 868badf4d49..668453f8905 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -41,26 +41,19 @@ #define HA_ADMIN_INTERNAL_ERROR -4 #define HA_ADMIN_INVALID -5 -/* Bits in bas_flag to show what database can do */ -#define HA_READ_NEXT 1 /* Read next record with same key */ -#define HA_READ_PREV 2 /* Read prev. record with same key */ -#define HA_READ_ORDER 4 /* Read through record-keys in order */ -#define HA_READ_RND_SAME 8 /* Read RND-record to KEY-record +/* Bits in table_flags() to show what database can do */ +#define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record (To update with RND-read) */ -#define HA_KEYPOS_TO_RNDPOS 16 /* ha_info gives pos to record */ -#define HA_TABLE_SCAN_ON_INDEX 32 /* No separate data/index file */ -#define HA_REC_NOT_IN_SEQ 64 /* ha_info don't return recnumber; +#define HA_KEYPOS_TO_RNDPOS 2 /* ha_info gives pos to record */ +#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_ONLY_WHOLE_INDEX 128 /* Can't use part key searches */ -#define HA_NOT_READ_PREFIX_LAST 256 /* RSAME can't restore index */ -#define HA_WRONG_ASCII_ORDER 512 /* Can't use sorting through key */ -#define HA_HAVE_KEY_READ_ONLY 1024 /* Can read only keys (no record) */ -#define HA_READ_NOT_EXACT_KEY 2048 /* Can read record after/before key */ -#define HA_NO_INDEX 4096 /* No index needed for next/prev */ -#define HA_KEY_READ_WRONG_STR 16384 /* keyread returns converted strings */ -#define HA_NULL_KEY 32768 /* One can have keys with NULL */ -#define HA_DUPP_POS 65536 /* ha_position() gives dupp row */ -#define HA_NO_BLOBS 131072 /* Doesn't support blobs */ +#define HA_HAVE_KEY_READ_ONLY 16 /* Can read only keys (no record) */ +#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) @@ -74,31 +67,41 @@ #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) -/* Old not used flags */ /* Next record gives next record according last record read (even - if database is updated after read) + if database is updated after read). Not used at this point. */ -#define HA_LASTKEY_ORDER 0 +#define HA_LASTKEY_ORDER (HA_NO_AUTO_INCREMENT*2) - /* Parameters for open() (in register form->filestat) */ - /* HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED */ + +/* bits in index_flags(index_number) for what you can do with index */ +#define HA_WRONG_ASCII_ORDER 1 /* Can't use sorting through key */ +#define HA_READ_NEXT 2 /* Read next record with same key */ +#define HA_READ_PREV 4 /* Read prev. record with same key */ +#define HA_READ_ORDER 8 /* Read through record-keys in order */ +#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */ +#define HA_NOT_READ_PREFIX_LAST 32 + +/* + Parameters for open() (in register form->filestat) + HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED +*/ #define HA_OPEN_KEYFILE 1 #define HA_OPEN_RNDFILE 2 #define HA_GET_INDEX 4 #define HA_GET_INFO 8 /* do a ha_info() after open */ #define HA_READ_ONLY 16 /* File opened as readonly */ -#define HA_TRY_READ_ONLY 32 /* Try readonly if can't */ - /* open with read and write */ +/* Try readonly if can't open with read and write */ +#define HA_TRY_READ_ONLY 32 #define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */ #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/ #define HA_BLOCK_LOCK 256 /* unlock when reading some records */ #define HA_OPEN_TEMPORARY 512 - /* Error on write which is recoverable (Key exist) */ - + /* Errors on write which is recoverable (Key exist) */ #define HA_WRITE_SKIP 121 /* Duplicate key on write */ #define HA_READ_CHECK 123 /* Update with is recoverable */ #define HA_CANT_DO_THAT 131 /* Databasehandler can't do it */ @@ -295,10 +298,11 @@ public: 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); + /* + restore assumes .frm file must exist, and that generate_table() has been + called; It will just copy the data file and run repair. + */ virtual int restore(THD* thd, HA_CHECK_OPT* check_opt); - // assumes .frm file must exist, and you must have already called - // generate_table() - it will just copy the data file and run repair - virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; } virtual void deactivate_non_unique_index(ha_rows rows) {} virtual bool activate_all_index(THD *thd) {return 0;} @@ -314,7 +318,11 @@ public: /* The following can be called without an open handler */ virtual const char *table_type() const =0; virtual const char **bas_ext() const =0; - virtual ulong option_flag() const =0; + virtual ulong table_flags(void) const =0; + virtual ulong index_flags(uint idx) const + { + return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); + } virtual uint max_record_length() const =0; virtual uint max_keys() const =0; virtual uint max_key_parts() const =0; @@ -360,10 +368,8 @@ int ha_delete_table(enum db_type db_type, const char *path); void ha_drop_database(char* path); void ha_key_cache(void); int ha_start_stmt(THD *thd); -int ha_report_binlog_offset_and_commit( - THD *thd, - char *log_file_name, - my_off_t end_offset); +int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name, + my_off_t end_offset); int ha_commit_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans); int ha_autocommit_or_rollback(THD *thd, int error); diff --git a/sql/log.cc b/sql/log.cc index c393d2eb413..40cafeeaad1 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -476,7 +476,6 @@ err: pthread_mutex_lock(&rli->log_space_lock); rli->log_space_total -= s.st_size; - fprintf(stderr,"purge_first_log: %ld\n", rli->log_space_total); pthread_mutex_unlock(&rli->log_space_lock); // ok to broadcast after the critical region as there is no risk of // the mutex being destroyed by this thread later - this helps save diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 9884adf9b46..0d6e548a873 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -329,12 +329,10 @@ net_real_write(NET *net,const char *packet,ulong len) my_bool net_blocking = vio_is_blocking(net->vio); DBUG_ENTER("net_real_write"); -#ifdef MYSQL_SERVER -#ifdef HAVE_QUERY_CACHE +#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE) if (net->query_cache_query != 0) query_cache_insert(net, packet, len); #endif -#endif if (net->error == 2) DBUG_RETURN(-1); /* socket can't be used */ @@ -824,6 +822,5 @@ int net_request_file(NET* net, const char* fname) tmp[0] = (char) 251; /* NULL_LENGTH */ end=strnmov(tmp+1,fname,sizeof(tmp)-2); DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) || - net_flush(net)); + net_flush(net)); } - diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 20f198182f4..7d2d04dbdf1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -595,7 +595,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range || !limit) DBUG_RETURN(0); /* purecov: inspected */ - if (!((basflag= head->file->option_flag()) & HA_KEYPOS_TO_RNDPOS) && + if (!((basflag= head->file->table_flags()) & HA_KEYPOS_TO_RNDPOS) && keys_to_use == (uint) ~0 || !keys_to_use) DBUG_RETURN(0); /* Not smart database */ records=head->file->records; @@ -692,7 +692,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, found_records=check_quick_select(¶m,idx, *key); if (found_records != HA_POS_ERROR && found_records > 2 && head->used_keys & ((table_map) 1 << param.real_keynr[idx]) && - (head->file->option_flag() & HA_HAVE_KEY_READ_ONLY)) + (head->file->table_flags() & HA_HAVE_KEY_READ_ONLY)) { /* ** We can resolve this by only reading through this key @@ -929,7 +929,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, String tmp(buff1,sizeof(buff1)),*res; uint length,offset,min_length,max_length; - if (!field->optimize_range()) + if (!field->optimize_range((uint) key_part->key)) DBUG_RETURN(0); // Can't optimize this if (!(res= value->val_str(&tmp))) DBUG_RETURN(&null_element); @@ -1010,7 +1010,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, DBUG_RETURN(tree); } - if (!field->optimize_range() && type != Item_func::EQ_FUNC && + if (!field->optimize_range((uint) key_part->key) && + type != Item_func::EQ_FUNC && type != Item_func::EQUAL_FUNC) DBUG_RETURN(0); // Can't optimize this @@ -2535,7 +2536,7 @@ int QUICK_SELECT::cmp_next(QUICK_RANGE *range) QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts) : QUICK_SELECT(*q), rev_it(rev_ranges) { - bool not_read_after_key = file->option_flag() & HA_NOT_READ_AFTER_KEY; + bool not_read_after_key = file->table_flags() & HA_NOT_READ_AFTER_KEY; QUICK_RANGE *r; it.rewind(); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 78878c40b37..efb4c4916a5 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -55,7 +55,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) TABLE_LIST *table; for (table=tables; table ; table=table->next) { - if (table->on_expr || (table->table->file->option_flag() & + if (table->on_expr || (table->table->file->table_flags() & HA_NOT_EXACT_COUNT)) { const_result=0; // Can't optimize left join @@ -141,7 +141,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) break; } TABLE *table=((Item_field*) expr)->field->table; - if ((table->file->option_flag() & HA_NOT_READ_AFTER_KEY)) + if ((table->file->table_flags() & HA_NOT_READ_AFTER_KEY)) { const_result=0; break; @@ -294,16 +294,22 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) return 0; // Not part of a key. Skip it TABLE *table=field->table; - if (table->file->option_flag() & HA_WRONG_ASCII_ORDER) - return(0); // Can't use key to find last row uint idx=0; /* Check if some key has field as first key part */ if ((field->key_start & field->table->keys_in_use_for_query) && (! cond || ! (cond->used_tables() & table->map))) { - for (key_map key=field->key_start ; !(key & 1) ; idx++) - key>>=1; + for (key_map key=field->key_start ;;) + { + for (; !(key & 1) ; idx++) + key>>=1; + if (!(table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER)) + break; // Key is ok + /* Can't use this key, for looking up min() or max(), end if last one */ + if (key == 1) + return 0; + } ref->key_length=0; ref->key=idx; if (field->part_of_key & ((key_map) 1 << idx)) @@ -323,6 +329,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) return 0; KEY *keyinfo,*keyinfo_end; + idx=0; for (keyinfo=table->key_info, keyinfo_end=keyinfo+table->keys ; keyinfo != keyinfo_end; keyinfo++,idx++) @@ -338,7 +345,8 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) part++) { if (!part_of_cond(cond,part->field) || - left_length < part->store_length) + left_length < part->store_length || + (table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER)) break; // Save found constant if (part->null_bit) diff --git a/sql/records.cc b/sql/records.cc index f156fdaf406..29ace3cd652 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -102,7 +102,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY || !(table->db_options_in_use & HA_OPTION_PACK_RECORD) || (use_record_cache < 0 && - !(table->file->option_flag() & HA_NOT_DELETE_WITH_CACHE))) + !(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE))) VOID(table->file->extra(HA_EXTRA_CACHE)); // Cache reads } DBUG_VOID_RETURN; diff --git a/sql/sql_class.h b/sql/sql_class.h index d8824e80686..e755deeea61 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -217,11 +217,13 @@ class Key :public Sql_alloc { public: enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT }; enum Keytype type; + enum ha_key_alg algorithm; List<key_part_spec> columns; const char *Name; Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols) - :type(type_par), columns(cols),Name(name_arg) {} + :type(type_par), algorithm(HA_KEY_ALG_UNDEF), columns(cols), Name(name_arg) + {} ~Key() {} const char *name() { return Name; } }; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 8f9d3474ce2..f1dc5599f46 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -55,7 +55,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) return -1; // there can be only one table in *tables - if (!(tables->table->file->option_flag() & HA_CAN_SQL_HANDLER)) + if (!(tables->table->file->table_flags() & HA_CAN_SQL_HANDLER)) { my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->name); mysql_ha_close(thd, tables,1); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 235adcc02c1..69fc7c00955 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -386,7 +386,7 @@ int write_record(TABLE *table,COPY_INFO *info) if (table->next_number_field && key_nr == table->next_number_index && table->file->auto_increment_column_changed) goto err; - if (table->file->option_flag() & HA_DUPP_POS) + if (table->file->table_flags() & HA_DUPP_POS) { if (table->file->rnd_pos(table->record[1],table->file->dupp_ref)) goto err; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 32f2e274132..18f256d9edb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -982,7 +982,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, s->dependent=(table_map) 0; s->key_dependent=(table_map) 0; if ((table->system || table->file->records <= 1) && ! s->dependent && - !(table->file->option_flag() & HA_NOT_EXACT_COUNT) && + !(table->file->table_flags() & HA_NOT_EXACT_COUNT) && !table->fulltext_searched) { set_position(join,const_count++,s,(KEYUSE*) 0); @@ -1073,7 +1073,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (s->dependent & ~(join->const_table_map)) continue; if (table->file->records <= 1L && - !(table->file->option_flag() & HA_NOT_EXACT_COUNT)) + !(table->file->table_flags() & HA_NOT_EXACT_COUNT)) { // system table int tmp; s->type=JT_SYSTEM; @@ -1882,7 +1882,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, ** Set tmp to (previous record count) * (records / combination) */ if ((found_part & 1) && - !(table->file->option_flag() & HA_ONLY_WHOLE_INDEX)) + !(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX)) { max_key_part=max_part_bit(found_part); /* Check if quick_range could determinate how many rows we @@ -1970,7 +1970,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, if ((records >= s->found_records || best > s->read_time) && !(s->quick && best_key && s->quick->index == best_key->key && best_max_key_part >= s->table->quick_key_parts[best_key->key]) && - !((s->table->file->option_flag() & HA_TABLE_SCAN_ON_INDEX) && + !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) && s->table->used_keys && best_key)) { // Check full join if (s->on_expr) @@ -4899,7 +4899,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), JOIN_TAB *jt=join->join_tab; if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group && !join->send_group_parts && !join->having && !jt->select_cond && - !(jt->table->file->option_flag() & HA_NOT_EXACT_COUNT)) + !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT)) { /* Join over all rows in table; Return number of found rows */ join->select_options ^= OPTION_FOUND_ROWS; @@ -5533,7 +5533,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, Use a traversal function that starts by reading the last row with key part (A) and then traverse the index backwards. */ - if (table->file->option_flag() & HA_NOT_READ_PREFIX_LAST) + if (table->file->table_flags() & HA_NOT_READ_PREFIX_LAST) DBUG_RETURN(1); tab->read_first_record= join_read_last_key; tab->read_record.read_record= join_read_prev_same; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 08c17c2e25d..8d7df7eb8e9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -678,7 +678,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) net_store_data(packet,convert, key_part->field ? key_part->field->field_name : "?unknown field?"); - if (table->file->option_flag() & HA_READ_ORDER) + if (table->file->index_flags(i) & HA_READ_ORDER) net_store_data(packet,convert, ((key_part->key_part_flag & HA_REVERSE_SORT) ? "D" : "A"), 1); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index cda5d8c9b6b..dcbfd709f97 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -282,7 +282,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, file=get_new_handler((TABLE*) 0, create_info->db_type); if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && - (file->option_flag() & HA_NO_TEMP_TABLES)) + (file->table_flags() & HA_NO_TEMP_TABLES)) { my_error(ER_ILLEGAL_HA,MYF(0),table_name); DBUG_RETURN(-1); @@ -381,13 +381,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } if (auto_increment && - (file->option_flag() & HA_WRONG_ASCII_ORDER)) + (file->table_flags() & HA_NO_AUTO_INCREMENT)) { my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0)); DBUG_RETURN(-1); } - if (blob_columns && (file->option_flag() & HA_NO_BLOBS)) + if (blob_columns && (file->table_flags() & HA_NO_BLOBS)) { my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0)); DBUG_RETURN(-1); @@ -443,10 +443,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; + key_info->algorithm=key->algorithm; + /* TODO: Add proper checks if handler supports key_type and algorithm */ if (key->type == Key::FULLTEXT) { - if (!(file->option_flag() & HA_CAN_FULLTEXT)) + if (!(file->table_flags() & HA_CAN_FULLTEXT)) { my_error(ER_TABLE_CANT_HANDLE_FULLTEXT, MYF(0)); DBUG_RETURN(-1); @@ -470,7 +472,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (f_is_blob(sql_field->pack_flag)) { - if (!(file->option_flag() & HA_BLOB_KEY)) + if (!(file->table_flags() & HA_BLOB_KEY)) { my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), column->field_name); @@ -496,7 +498,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0)); DBUG_RETURN(-1); } - if (!(file->option_flag() & HA_NULL_KEY)) + if (!(file->table_flags() & HA_NULL_KEY)) { my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), MYF(0),column->field_name); @@ -506,7 +508,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) { - if (column_nr == 0 || (file->option_flag() & HA_AUTO_PART_KEY)) + if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY)) auto_increment--; // Field is used } key_part_info->fieldnr= field; @@ -526,14 +528,14 @@ 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) || - ((file->option_flag() & HA_NO_PREFIX_CHAR_KEYS) && + ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && (key_info->flags & HA_NOSAME))) && column->length != length)) { my_error(ER_WRONG_SUB_KEY,MYF(0)); DBUG_RETURN(-1); } - if (!(file->option_flag() & HA_NO_PREFIX_CHAR_KEYS)) + if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) length=column->length; } else if (length == 0) @@ -593,7 +595,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } } if (!unique_key && !primary_key && - (file->option_flag() & HA_REQUIRE_PRIMARY_KEY)) + (file->table_flags() & HA_REQUIRE_PRIMARY_KEY)) { my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0)); DBUG_RETURN(-1); diff --git a/sql/structs.h b/sql/structs.h index 9e577128c8d..2250ea784f2 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -67,6 +67,7 @@ typedef struct st_key { uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ + enum ha_key_alg algorithm; KEY_PART_INFO *key_part; char *name; /* Name of key */ ulong *rec_per_key; /* Key part distribution */ diff --git a/sql/table.cc b/sql/table.cc index 023d4d85df9..315f8bacf34 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -46,7 +46,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, reg2 uchar *strpos; int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, - interval_count,interval_parts,read_length,db_create_options; + interval_count,interval_parts,read_length,db_create_options; + uint key_info_length; ulong pos; char index_file[FN_REFLEN], *names,*keynames; uchar head[288],*disk_buff,new_field_pack_flag; @@ -127,8 +128,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->min_rows=uint4korr(head+22); /* Read keyinformation */ + key_info_length= (uint) uint2korr(head+28); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); - if (read_string(file,(gptr*) &disk_buff,(uint) uint2korr(head+28))) + if (read_string(file,(gptr*) &disk_buff,key_info_length)) goto err_not_open; /* purecov: inspected */ outparam->keys=keys= disk_buff[0]; outparam->keys_in_use= set_bits(key_map, keys); @@ -187,8 +189,16 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (keyinfo->flags & HA_NOSAME) set_if_bigger(outparam->max_unique_length,keyinfo->key_length); } - - (void) strmov(keynames= (char *) key_part,(char *) strpos); + keynames=(char*) key_part; + strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; + /* Test if new 4.0 format */ + if ((uint) (strpos - disk_buff) < key_info_length) + { + /* Read key types */ + keyinfo=outparam->key_info; + for (i=0 ; i < keys ; i++, keyinfo++) + keyinfo->algorithm= (enum ha_key_alg) *(strpos++); + } outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -369,7 +379,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames, 3)-1); - uint ha_option=outparam->file->option_flag(); + uint ha_option=outparam->file->table_flags(); keyinfo=outparam->key_info; key_part=keyinfo->key_part; @@ -442,8 +452,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (!(ha_option & HA_KEY_READ_WRONG_STR) && !(keyinfo->flags & HA_FULLTEXT))) field->part_of_key|= ((key_map) 1 << key); - if (field->key_type() != HA_KEYTYPE_TEXT || - !(keyinfo->flags & HA_FULLTEXT)) + if ((field->key_type() != HA_KEYTYPE_TEXT || + !(keyinfo->flags & HA_FULLTEXT)) && + !(outparam->file->index_flags(key) & + HA_WRONG_ASCII_ORDER)) field->part_of_sortkey|= ((key_map) 1 << key); } if (!(key_part->key_part_flag & HA_REVERSE_SORT) && diff --git a/sql/unireg.cc b/sql/unireg.cc index 16ba8c7d58b..1c35f7a6a08 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -246,7 +246,7 @@ static uchar * pack_screens(List<create_field> &create_fields, static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) { uint key_parts,length; - uchar *pos,*keyname_pos; + uchar *pos, *keyname_pos, *key_alg_pos; KEY *key,*end; KEY_PART_INFO *key_part,*key_part_end; DBUG_ENTER("pack_keys"); @@ -290,11 +290,18 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) } *(pos++)=0; + /* For MySQL 4.0; Store key algoritms last */ + key_alg_pos= pos; + for (key=keyinfo ; key != end ; key++) + { + *(pos++)= (uchar) key->algorithm; + } + keybuff[0]=(uchar) key_count; keybuff[1]=(uchar) key_parts; length=(uint) (keyname_pos-keybuff); int2store(keybuff+2,length); - length=(uint) (pos-keyname_pos); + length=(uint) (key_alg_pos-keyname_pos); int2store(keybuff+4,length); DBUG_RETURN((uint) (pos-keybuff)); } /* pack_keys */ |