RIGHT JOIN, part of automatic repair of MyISAM tables, backup on repair,

reading from FIFO, fixes for FULLTEXT, @@IDENTITY
This commit is contained in:
monty@tramp.mysql.fi 2000-09-26 00:33:25 +03:00
parent 50486eeb80
commit e32799e4dd
83 changed files with 391 additions and 200 deletions

View File

@ -1,21 +1 @@
bk@work.mysql.com monty@tramp.mysql.fi
davida@work.mysql.com
jamppa@work.mysql.com
jcole@ham.spaceapes.com
jcole@jcole.burghcom.com
jcole@tetra.bedford.progress.com
jcole@tetra.spaceapes.com
matt@work.mysql.com
mwagner@evoq.home.mwagner.org
monty@donna.mysql.com
monty@work.mysql.com
paul@central.snake.net
paul@work.mysql.com
sasha@mysql.sashanet.com
sasha@work.mysql.com
serg@infomag.ape.relarn.ru
serg@work.mysql.com
sinisa@work.mysql.com
tim@localhost.polyesthetic.msg
tim@work.mysql.com
tonu@work.mysql.com

View File

@ -581,7 +581,7 @@ Speed of queries that access or update data
* Estimating performance:: Estimating query performance * Estimating performance:: Estimating query performance
* SELECT speed:: Speed of @code{SELECT} queries * SELECT speed:: Speed of @code{SELECT} queries
* Where optimizations:: How MySQL optimizes @code{WHERE} clauses * Where optimizations:: How MySQL optimizes @code{WHERE} clauses
* LEFT JOIN optimization:: How MySQL optimizes @code{LEFT JOIN} * LEFT JOIN optimization:: How MySQL optimizes @code{LEFT JOIN} and ${RIGHT JOIN}
* LIMIT optimization:: How MySQL optimizes @code{LIMIT} * LIMIT optimization:: How MySQL optimizes @code{LIMIT}
* Insert speed:: Speed of @code{INSERT} queries * Insert speed:: Speed of @code{INSERT} queries
* Update speed:: Speed of @code{UPDATE} queries * Update speed:: Speed of @code{UPDATE} queries
@ -9049,7 +9049,7 @@ almost always sorted. In 3.23, you must use @code{GROUP BY} or
@code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching @code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching
rows. This is according to ANSI SQL. rows. This is according to ANSI SQL.
@item @item
New restricted words: @code{CASE, THEN, WHEN, ELSE and END} New restricted words: @code{CASE, THEN, WHEN, ELSE, END and RIGHT}
@item An @code{AND} or @code{OR} with @code{NULL} values will now return @item An @code{AND} or @code{OR} with @code{NULL} values will now return
@code{NULL} instead of 0. This mostly affects queries that uses @code{NOT} @code{NULL} instead of 0. This mostly affects queries that uses @code{NOT}
on an @code{AND/OR} expression as @code{NOT NULL} = @code{NULL}. on an @code{AND/OR} expression as @code{NOT NULL} = @code{NULL}.
@ -16504,10 +16504,22 @@ DROP DATABASE [IF EXISTS] db_name
@code{DROP DATABASE} drops all tables in the database and deletes the @code{DROP DATABASE} drops all tables in the database and deletes the
database. @strong{Be VERY careful with this command!} database. @strong{Be VERY careful with this command!}
@code{DROP DATABASE} returns the number of files that were removed from the @code{DROP DATABASE} returns the number of files that were removed from
database directory. Normally, this is three times the number of tables, the database directory. Normally, this is three times the number of
because each table corresponds to a @file{.MYD} file, a @file{.MYI} file and a tables, because normally each table corresponds to a @file{.MYD} file, a
@file{.frm} file. @file{.MYI} file and a @file{.frm} file.
The @code{DROP DATABASE} command removes from the given database
directory all files with the following extensions:
@multitable @columnfractions .25 .25 .25 .25
@item .BAK @tab .DAT @tab .HSH @tab .ISD
@item .ISM @tab .ISM @tab .MRG @tab .MYD
@item .MYI @tab .db @tab .frm
@end multitable
All sub directories that consists of 2 digits (@code{RAID} directories)
are also removed.
In @strong{MySQL} 3.22 or later, you can use the keywords @code{IF EXISTS} to In @strong{MySQL} 3.22 or later, you can use the keywords @code{IF EXISTS} to
prevent an error from occurring if the database doesn't exist. prevent an error from occurring if the database doesn't exist.
@ -17712,6 +17724,10 @@ store a blob in a file.
@findex LEFT OUTER JOIN @findex LEFT OUTER JOIN
@findex NATURAL LEFT JOIN @findex NATURAL LEFT JOIN
@findex NATURAL LEFT OUTER JOIN @findex NATURAL LEFT OUTER JOIN
@findex RIGHT JOIN
@findex RIGHT OUTER JOIN
@findex NATURAL RIGHT JOIN
@findex NATURAL RIGHT OUTER JOIN
@findex STRAIGHT_JOIN @findex STRAIGHT_JOIN
@node JOIN, INSERT, SELECT, Reference @node JOIN, INSERT, SELECT, Reference
@section @code{JOIN} syntax @section @code{JOIN} syntax
@ -17728,6 +17744,9 @@ table_reference LEFT [OUTER] JOIN table_reference join_condition
table_reference LEFT [OUTER] JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference
table_reference NATURAL [LEFT [OUTER]] JOIN table_reference table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
@{ oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr @} @{ oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr @}
table_reference RIGHT [OUTER] JOIN table_reference join_condition
table_reference RIGHT [OUTER] JOIN table_reference
table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
@end example @end example
Where @code{table_reference} is defined as Where @code{table_reference} is defined as
@ -17784,7 +17803,7 @@ mysql> select table1.* from table1
This example finds all rows in @code{table1} with an @code{id} value that is This example finds all rows in @code{table1} with an @code{id} value that is
not present in @code{table2} (i.e., all rows in @code{table1} with no not present in @code{table2} (i.e., all rows in @code{table1} with no
corresponding row in @code{table2}). This assumes that @code{table2.id} is corresponding row in @code{table2}). This assumes that @code{table2.id} is
declared @code{NOT NULL}, of course. declared @code{NOT NULL}, of course. @xref{LEFT JOIN optimization}.
@item @item
The @code{USING} @code{(column_list)} clause names a list of columns that must The @code{USING} @code{(column_list)} clause names a list of columns that must
@ -17807,6 +17826,11 @@ semantically equivalent to a @code{INNER JOIN} or a @code{LEFT JOIN}
with a @code{USING} clause that names all columns that exist in both with a @code{USING} clause that names all columns that exist in both
tables. tables.
@item
@code{RIGHT JOIN} works analogously as @code{LEFT JOIN}. To keep code
portable across databases, it's recommended to use @code{LEFT JOIN}
instead of @code{RIGHT JOIN}.
@item @item
@code{STRAIGHT_JOIN} is identical to @code{JOIN}, except that the left table @code{STRAIGHT_JOIN} is identical to @code{JOIN}, except that the left table
is always read before the right table. This can be used for those (few) is always read before the right table. This can be used for those (few)
@ -18151,9 +18175,11 @@ files directly, because the contents of the file must travel from the client
host to the server host. On the other hand, you do not need the host to the server host. On the other hand, you do not need the
@strong{file} privilege to load local files. @strong{file} privilege to load local files.
Note that you can't read from a FIFO with @code{LOAD DATA INFILE}; If @c old version
you need to read from a FIFO (for example the output from gunzip), use If you are using @strong{MySQL} before 3.23.24 you can't read from a
@code{LOAD DATA LOCAL INFILE} instead. FIFO with @code{LOAD DATA INFILE}; If you need to read from a FIFO (for
example the output from gunzip), use @code{LOAD DATA LOCAL INFILE}
instead.
@cindex @code{mysqlimport} @cindex @code{mysqlimport}
You can also load data files by using the @code{mysqlimport} utility; it You can also load data files by using the @code{mysqlimport} utility; it
@ -18567,7 +18593,7 @@ well. If you get warnings and want to know exactly why you got them, one way
to do this is to use @code{SELECT ... INTO OUTFILE} into another file and to do this is to use @code{SELECT ... INTO OUTFILE} into another file and
compare this to your original input file. compare this to your original input file.
If you need @code{LOAD DATA INFILE} to read from a pipe, you can use the If you need @code{LOAD DATA} to read from a pipe, you can use the
following trick: following trick:
@example @example
@ -18577,6 +18603,9 @@ cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
@end example @end example
If you are using and older @strong{MySQL} version than 3.23.25
you can only do the above with @code{LOAD DATA LOCAL INFILE}.
For more information about the efficiency of @code{INSERT} versus For more information about the efficiency of @code{INSERT} versus
@code{LOAD DATA INFILE} and speeding up @code{LOAD DATA INFILE}, @code{LOAD DATA INFILE} and speeding up @code{LOAD DATA INFILE},
@xref{Insert speed}. @xref{Insert speed}.
@ -25566,7 +25595,7 @@ mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,...
@end example @end example
@node LEFT JOIN optimization, LIMIT optimization, Where optimizations, Query Speed @node LEFT JOIN optimization, LIMIT optimization, Where optimizations, Query Speed
@subsection How MySQL optimizes @code{LEFT JOIN} @subsection How MySQL optimizes @code{LEFT JOIN} and @code{RIGHT JOIN}
@code{A LEFT JOIN B} is in @strong{MySQL} implemented as follows: @code{A LEFT JOIN B} is in @strong{MySQL} implemented as follows:
@ -25598,9 +25627,12 @@ table and you have the following test: @code{column_name IS NULL} in the
matches the @code{LEFT JOIN} condition. matches the @code{LEFT JOIN} condition.
@end itemize @end itemize
The table read order forced by @code{LEFT JOIN} and @code{STRAIGHT JOIN} will help @code{RIGHT JOIN} is implemented analogously as @code{LEFT JOIN}.
the join optimizer (which calculates in which order tables should be joined) to do
its work much more quickly as there are fewer table permutations to check. The table read order forced by @code{LEFT JOIN} and @code{STRAIGHT JOIN}
will help the join optimizer (which calculates in which order tables
should be joined) to do its work much more quickly as there are fewer
table permutations to check.
Note that the above means that if you do a query of type: Note that the above means that if you do a query of type:
@ -25608,8 +25640,8 @@ Note that the above means that if you do a query of type:
SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
@end example @end example
Then @strong{MySQL} will do a full scan on @code{b} as the @code{LEFT JOIN} will Then @strong{MySQL} will do a full scan on @code{b} as the @code{LEFT
force it to be read before @code{d}. JOIN} will force it to be read before @code{d}.
The fix in this case is to change the query to: The fix in this case is to change the query to:
@ -36742,6 +36774,16 @@ though, so 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.25 @appendixsubsec Changes in release 3.23.25
@itemize @bullet @itemize @bullet
@item @item
Added @code{RIGHT JOIN}. This makes @code{RIGHT} a reserved word.
@item
Added @code{@@@@IDENTITY} as a synonym for @code{LAST_INSERT_ID()}.
(for Visual Basic)
@item
Fixed bug in myisamchk and @code{REPAIR} when using @code{FULLTEXT} index.
@item
@code{LOAD DATA INFILE} now works for FIFO's.
(Patch by Toni L. Harbaugh-Blackford).
@item
Fixed a bug in MyISAM with packed multi-part keys. Fixed a bug in MyISAM with packed multi-part keys.
@item @item
Fixed crash when using @code{CHECK TABLE} on Windows. Fixed crash when using @code{CHECK TABLE} on Windows.

View File

@ -1409,19 +1409,20 @@ print_table_data_html(MYSQL_RES *result)
MYSQL_FIELD *field; MYSQL_FIELD *field;
mysql_field_seek(result,0); mysql_field_seek(result,0);
printf("<TABLE BORDER=1>\n"); fputs("<TABLE BORDER=1><TR>",stdout);
printf("<TR>\n");
if (!skip_column_names) if (!skip_column_names)
{ {
while((field = mysql_fetch_field(result))) while((field = mysql_fetch_field(result)))
{ {
printf("<TH>%s</TH>",field->name ? (field->name[0] ? field->name:" &nbsp; "):"NULL"); printf("<TH>%s</TH>", (field->name ? (field->name[0] ? field->name :
" &nbsp; ") :
"NULL"));
} }
puts("\n</TR>"); puts("</TR>");
} }
while ((cur = mysql_fetch_row(result))) while ((cur = mysql_fetch_row(result)))
{ {
puts("<TR>"); fputs("<TR>",stdout);
for (uint i=0; i < mysql_num_fields(result); i++) for (uint i=0; i < mysql_num_fields(result); i++)
{ {
ulong *lengths=mysql_fetch_lengths(result); ulong *lengths=mysql_fetch_lengths(result);
@ -1429,7 +1430,7 @@ print_table_data_html(MYSQL_RES *result)
safe_put_field(cur[i],lengths[i]); safe_put_field(cur[i],lengths[i]);
fputs("</TD>",stdout); fputs("</TD>",stdout);
} }
puts("\n</TR>"); puts("</TR>");
} }
puts("</TABLE>"); puts("</TABLE>");
} }

View File

@ -17,7 +17,7 @@
/* Return error-text for system error messages and nisam messages */ /* Return error-text for system error messages and nisam messages */
#define PERROR_VERSION "2.3" #define PERROR_VERSION "2.4"
#include <global.h> #include <global.h>
#include <my_sys.h> #include <my_sys.h>
@ -64,6 +64,7 @@ static HA_ERRORS ha_errlist[]=
{ 141,"Duplicate unique on write or update"}, { 141,"Duplicate unique on write or update"},
{ 142,"Unknown character set used"}, { 142,"Unknown character set used"},
{ 143,"Conflicting table definition between MERGE and mapped table"}, { 143,"Conflicting table definition between MERGE and mapped table"},
{ 144,"Table is crashed and last repair failed"},
{ 0,NullS }, { 0,NullS },
}; };

View File

@ -43,8 +43,9 @@
#define HA_OPEN_ABORT_IF_LOCKED 0 /* default */ #define HA_OPEN_ABORT_IF_LOCKED 0 /* default */
#define HA_OPEN_WAIT_IF_LOCKED 1 #define HA_OPEN_WAIT_IF_LOCKED 1
#define HA_OPEN_IGNORE_IF_LOCKED 2 #define HA_OPEN_IGNORE_IF_LOCKED 2
#define HA_OPEN_TMP_TABLE 4 #define HA_OPEN_TMP_TABLE 4 /* Table is a temp table */
#define HA_OPEN_DELAY_KEY_WRITE 8 #define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
#define HA_OPEN_ABORT_IF_CRASHED 16
/* The following is parameter to ha_rkey() how to use key */ /* The following is parameter to ha_rkey() how to use key */
@ -163,7 +164,7 @@ enum ha_base_keytype {
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */ #define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */ #define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
/* Bits in flag to ni_create() */ /* Bits in flag to create() */
#define HA_DONT_TOUCH_DATA 1 /* Don't empty datafile (isamchk) */ #define HA_DONT_TOUCH_DATA 1 /* Don't empty datafile (isamchk) */
#define HA_PACK_RECORD 2 /* Request packed record format */ #define HA_PACK_RECORD 2 /* Request packed record format */
@ -203,6 +204,7 @@ enum ha_base_keytype {
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */ #define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
#define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */ #define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */
#define HA_ERR_WRONG_TABLE_DEF 143 #define HA_ERR_WRONG_TABLE_DEF 143
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
/* Other constants */ /* Other constants */

View File

@ -62,6 +62,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */ #define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */ #define MY_COPYTIME 64 /* my_redel() copys time */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */ #define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
#define MY_REDEL_MAKE_BACKUP 256
#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */ #define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */
#define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */ #define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */
#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */ #define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */
@ -219,7 +220,7 @@ typedef struct st_typelib { /* Different types saved here */
const char **type_names; const char **type_names;
} TYPELIB; } TYPELIB;
enum cache_type {READ_CACHE,WRITE_CACHE,READ_NET,WRITE_NET}; enum cache_type {READ_CACHE,WRITE_CACHE,READ_FIFO,READ_NET,WRITE_NET};
enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED,
FLUSH_FORCE_WRITE}; FLUSH_FORCE_WRITE};

View File

@ -273,9 +273,11 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
#define T_CREATE_MISSING_KEYS T_TRUST_HEADER*2 #define T_CREATE_MISSING_KEYS T_TRUST_HEADER*2
#define T_SAFE_REPAIR T_CREATE_MISSING_KEYS*2 #define T_SAFE_REPAIR T_CREATE_MISSING_KEYS*2
#define T_AUTO_REPAIR T_SAFE_REPAIR*2 #define T_AUTO_REPAIR T_SAFE_REPAIR*2
#define T_BACKUP_DATA T_AUTO_REPAIR*2
#define O_NEW_INDEX 1 /* Bits set in out_flag */ #define O_NEW_INDEX 1 /* Bits set in out_flag */
#define O_NEW_DATA 2 #define O_NEW_DATA 2
#define O_DATA_LOST 4
/* these struct is used by my_check to tell it what to do */ /* these struct is used by my_check to tell it what to do */
@ -359,7 +361,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name);
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick); const char * name, int rep_quick);
int change_to_newfile(const char * filename, const char * old_ext, int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext, uint raid_chunks); const char * new_ext, uint raid_chunks,
myf myflags);
int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type, int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type,
const char *filetype, const char *filename); const char *filetype, const char *filename);
void lock_memory(MI_CHECK *param); void lock_memory(MI_CHECK *param);
@ -378,7 +381,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
int test_if_almost_full(MI_INFO *info); int test_if_almost_full(MI_INFO *info);
int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename); int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows); my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, my_bool force);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -193,4 +193,5 @@
#define ER_MASTER_NET_WRITE 1190 #define ER_MASTER_NET_WRITE 1190
#define ER_FT_MATCHING_KEY_NOT_FOUND 1191 #define ER_FT_MATCHING_KEY_NOT_FOUND 1191
#define ER_LOCK_OR_ACTIVE_TRANSACTION 1192 #define ER_LOCK_OR_ACTIVE_TRANSACTION 1192
#define ER_ERROR_MESSAGES 193 #define ER_UNKNOWN_SYSTEM_VARIABLE 1193
#define ER_ERROR_MESSAGES 194

View File

@ -1246,7 +1246,6 @@ err:
MYF(MY_WME))); MYF(MY_WME)));
} }
mi_mark_crashed_on_repair(info); mi_mark_crashed_on_repair(info);
info->update|= HA_STATE_CHANGED;
} }
if (sort_info->record) if (sort_info->record)
my_free(sort_info->record,MYF(0)); my_free(sort_info->record,MYF(0));
@ -1544,7 +1543,8 @@ err:
int change_to_newfile(const char * filename, const char * old_ext, int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext, const char * new_ext,
uint raid_chunks __attribute__((unused))) uint raid_chunks __attribute__((unused)),
myf MyFlags)
{ {
char old_filename[FN_REFLEN],new_filename[FN_REFLEN]; char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
#ifdef USE_RAID #ifdef USE_RAID
@ -1552,11 +1552,11 @@ int change_to_newfile(const char * filename, const char * old_ext,
return my_raid_redel(fn_format(old_filename,filename,"",old_ext,2+4), return my_raid_redel(fn_format(old_filename,filename,"",old_ext,2+4),
fn_format(new_filename,filename,"",new_ext,2+4), fn_format(new_filename,filename,"",new_ext,2+4),
raid_chunks, raid_chunks,
MYF(MY_WME+MY_LINK_WARNING)); MYF(MY_WME | MY_LINK_WARNING | MyFlags));
#endif #endif
return my_redel(fn_format(old_filename,filename,"",old_ext,2+4), return my_redel(fn_format(old_filename,filename,"",old_ext,2+4),
fn_format(new_filename,filename,"",new_ext,2+4), fn_format(new_filename,filename,"",new_ext,2+4),
MYF(MY_WME+MY_LINK_WARNING)); MYF(MY_WME | MY_LINK_WARNING | MyFlags));
} /* change_to_newfile */ } /* change_to_newfile */
@ -1901,9 +1901,10 @@ err:
VOID(my_close(new_file,MYF(0))); VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks, VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
MYF(MY_WME))); MYF(MY_WME)));
if (info->dfile == new_file)
info->dfile=0;
} }
mi_mark_crashed_on_repair(info); mi_mark_crashed_on_repair(info);
info->update|= HA_STATE_CHANGED;
} }
else if (key_map == share->state.key_map) else if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
@ -1986,7 +1987,11 @@ static int sort_get_next_record(SORT_INFO *sort_info)
{ {
if (my_b_read(&param->read_cache,sort_info->record, if (my_b_read(&param->read_cache,sort_info->record,
share->base.pack_reclength)) share->base.pack_reclength))
{
if (param->read_cache.error)
param->out_flag |= O_DATA_LOST;
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
sort_info->start_recpos=sort_info->pos; sort_info->start_recpos=sort_info->pos;
if (!sort_info->fix_datafile) if (!sort_info->fix_datafile)
sort_info->filepos=sort_info->pos; sort_info->filepos=sort_info->pos;
@ -2201,7 +2206,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (pos + MI_BLOCK_INFO_HEADER_LENGTH > param->read_cache.end_of_file) if (pos + MI_BLOCK_INFO_HEADER_LENGTH > param->read_cache.end_of_file)
{ {
mi_check_print_info(param,"Found link that points at %s (outside data file) at %s", mi_check_print_info(param,"Found link that points at %s (outside data file) at %s",
llstr(pos,llbuff2), llstr(sort_info->start_recpos,llbuff)); llstr(pos,llbuff2),
llstr(sort_info->start_recpos,llbuff));
goto try_next; goto try_next;
} }
} while (left_length); } while (left_length);
@ -2251,7 +2257,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
{ {
if (! searching) if (! searching)
mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n", mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
block_info.rec_len, llstr(sort_info->pos,llbuff)); block_info.rec_len,
llstr(sort_info->pos,llbuff));
continue; continue;
} }
if (_mi_read_cache(&param->read_cache,(byte*) info->rec_buff, if (_mi_read_cache(&param->read_cache,(byte*) info->rec_buff,
@ -2266,7 +2273,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
block_info.rec_len)) block_info.rec_len))
{ {
if (! searching) if (! searching)
mi_check_print_info(param,"Found wrong record at %s", llstr(sort_info->pos,llbuff)); mi_check_print_info(param,"Found wrong record at %s",
llstr(sort_info->pos,llbuff));
continue; continue;
} }
if (!sort_info->fix_datafile) if (!sort_info->fix_datafile)
@ -3011,9 +3019,13 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
} }
/* Return TRUE if we can use repair by sorting */ /*
Return TRUE if we can use repair by sorting
One can set the force argument to force to use sorting
even if the temporary file would be quite big!
*/
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows) my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, my_bool force)
{ {
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
uint i; uint i;

View File

@ -392,7 +392,7 @@ int _mi_test_if_changed(register MI_INFO *info)
} /* _mi_test_if_changed */ } /* _mi_test_if_changed */
/* Put a mark in the .ISM file that someone is updating the table */ /* Put a mark in the .MYI file that someone is updating the table */
int _mi_mark_file_changed(MI_INFO *info) int _mi_mark_file_changed(MI_INFO *info)
{ {

View File

@ -57,16 +57,14 @@ static MI_INFO *test_if_reopen(char *filename)
/****************************************************************************** /******************************************************************************
open a isam database. open a MyISAM database.
if handle_locking is 0 then exit with error if database is locked See my_base.h for the handle_locking argument
if handle_locking is 1 then wait if database is locked if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table
if handle_locking is 2 then continue, but count-vars in st_i_info is marked crashed or if we are not using locking and the table doesn't
may be wrong. count-vars are automaticly fixed after next isam have an open count of 0.
request.
******************************************************************************/ ******************************************************************************/
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
{ {
int lock_error,kfile,open_mode,save_errno; int lock_error,kfile,open_mode,save_errno;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys, uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
@ -139,12 +137,12 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
errpos=2; errpos=2;
VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0))); VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
if (!(handle_locking & HA_OPEN_TMP_TABLE)) if (!(open_flags & HA_OPEN_TMP_TABLE))
{ {
if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF, if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
MYF(handle_locking & HA_OPEN_WAIT_IF_LOCKED ? MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
0 : MY_DONT_WAIT))) && 0 : MY_DONT_WAIT))) &&
!(handle_locking & HA_OPEN_IGNORE_IF_LOCKED)) !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
goto err; goto err;
} }
errpos=3; errpos=3;
@ -176,6 +174,14 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base); disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base);
share->state.state_length=base_pos; share->state.state_length=base_pos;
if ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
((share->state.changed & STATE_CRASHED) ||
(my_disable_locking && share->state.open_count)))
{
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED);
goto err;
}
/* Correct max_file_length based on length of sizeof_t */ /* Correct max_file_length based on length of sizeof_t */
max_data_file_length= max_data_file_length=
(share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
@ -273,7 +279,10 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
} }
} }
if (share->keyinfo[i].flag & HA_FULLTEXT) /* SerG */ if (share->keyinfo[i].flag & HA_FULLTEXT) /* SerG */
{
share->keyinfo[i].seg=pos-FT_SEGS; /* SerG */ share->keyinfo[i].seg=pos-FT_SEGS; /* SerG */
share->fulltext_index=1;
}
share->keyinfo[i].end=pos; share->keyinfo[i].end=pos;
pos->type=HA_KEYTYPE_END; /* End */ pos->type=HA_KEYTYPE_END; /* End */
pos->length=share->base.rec_reflength; pos->length=share->base.rec_reflength;
@ -401,7 +410,7 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE | ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
HA_OPTION_COMPRESS_RECORD | HA_OPTION_COMPRESS_RECORD |
HA_OPTION_TEMP_COMPRESS_RECORD)) || HA_OPTION_TEMP_COMPRESS_RECORD)) ||
(handle_locking & HA_OPEN_TMP_TABLE)) ? 0 : 1; (open_flags & HA_OPEN_TMP_TABLE)) ? 0 : 1;
if (share->concurrent_insert) if (share->concurrent_insert)
{ {
share->lock.get_status=mi_get_status; share->lock.get_status=mi_get_status;
@ -484,7 +493,7 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
info.lock_type=F_RDLCK; info.lock_type=F_RDLCK;
share->r_locks++; share->r_locks++;
} }
if ((handle_locking & HA_OPEN_TMP_TABLE) || if ((open_flags & HA_OPEN_TMP_TABLE) ||
(share->options & HA_OPTION_TMP_TABLE)) (share->options & HA_OPTION_TMP_TABLE))
{ {
share->temporary=share->delay_key_write=1; share->temporary=share->delay_key_write=1;
@ -492,7 +501,7 @@ MI_INFO *mi_open(const char *name, int mode, uint handle_locking)
share->w_locks++; /* We don't have to update status */ share->w_locks++; /* We don't have to update status */
info.lock_type=F_WRLCK; info.lock_type=F_WRLCK;
} }
if (((handle_locking & HA_OPEN_DELAY_KEY_WRITE) || if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
(share->options & HA_OPTION_DELAY_KEY_WRITE)) && (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
myisam_delay_key_write) myisam_delay_key_write)
share->delay_key_write=1; share->delay_key_write=1;

View File

@ -16,7 +16,7 @@
/* Descript, check and repair of ISAM tables */ /* Descript, check and repair of ISAM tables */
#include "myisamdef.h" #include "fulltext.h"
#include <m_ctype.h> #include <m_ctype.h>
#include <stdarg.h> #include <stdarg.h>
@ -123,6 +123,7 @@ int main(int argc, char **argv)
llstr(check_param.total_deleted,buff2)); llstr(check_param.total_deleted,buff2));
} }
free_defaults(default_argv); free_defaults(default_argv);
ft_free_stopwords();
my_end(check_param.testflag & T_INFO ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); my_end(check_param.testflag & T_INFO ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(error); exit(error);
#ifndef _lint #ifndef _lint
@ -153,11 +154,12 @@ static struct option long_options[] =
{ {
{"analyze", no_argument, 0, 'a'}, {"analyze", no_argument, 0, 'a'},
{"block-search", required_argument,0, 'b'}, {"block-search", required_argument,0, 'b'},
{"backup", no_argument, 0, 'B'},
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
{"check", no_argument, 0, 'c'}, {"check", no_argument, 0, 'c'},
{"check-only-changed",no_argument, 0, 'C'}, {"check-only-changed",no_argument, 0, 'C'},
#ifndef DBUG_OFF #ifndef DBUG_OFF
{"debug", required_argument, 0, '#'}, {"debug", optional_argument, 0, '#'},
#endif #endif
{"description", no_argument, 0, 'd'}, {"description", no_argument, 0, 'd'},
{"data-file-length", required_argument, 0, 'D'}, {"data-file-length", required_argument, 0, 'D'},
@ -232,6 +234,7 @@ static void usage(void)
-T, --read-only Don't mark table as checked\n"); -T, --read-only Don't mark table as checked\n");
puts("Repair options (When using -r or -o) \n\ puts("Repair options (When using -r or -o) \n\
-B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\
-D, --data-file-length=# Max length of data file (when recreating data\n\ -D, --data-file-length=# Max length of data file (when recreating data\n\
file when it's full)\n\ file when it's full)\n\
-e, --extend-check Try to recover every possible row from the data file\n\ -e, --extend-check Try to recover every possible row from the data file\n\
@ -296,7 +299,7 @@ static void get_options(register int *argc,register char ***argv)
set_all_changeable_vars(changeable_vars); set_all_changeable_vars(changeable_vars);
if (isatty(fileno(stdout))) if (isatty(fileno(stdout)))
check_param.testflag|=T_WRITE_LOOP; check_param.testflag|=T_WRITE_LOOP;
while ((c=getopt_long(*argc,*argv,"acCdeifF?lqrmosSTuUvVw#:b:D:k:O:R:A::t:", while ((c=getopt_long(*argc,*argv,"aBcCdeifF?lqrmosSTuUvVw#:b:D:k:O:R:A::t:",
long_options, &option_index)) != EOF) long_options, &option_index)) != EOF)
{ {
switch(c) { switch(c) {
@ -313,6 +316,9 @@ static void get_options(register int *argc,register char ***argv)
case 'b': case 'b':
check_param.search_after_block=strtoul(optarg,NULL,10); check_param.search_after_block=strtoul(optarg,NULL,10);
break; break;
case 'B':
check_param.testflag|= T_BACKUP_DATA;
break;
case 'c': case 'c':
check_param.testflag|= T_CHECK; check_param.testflag|= T_CHECK;
break; break;
@ -406,7 +412,7 @@ static void get_options(register int *argc,register char ***argv)
check_param.testflag|= T_UPDATE_STATE; check_param.testflag|= T_UPDATE_STATE;
break; break;
case '#': case '#':
DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/isamchk"); DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/myisamchk.trace");
break; break;
case 'V': case 'V':
print_version(); print_version();
@ -520,7 +526,6 @@ static int myisamchk(MI_CHECK *param, my_string filename)
share->r_locks=0; share->r_locks=0;
raid_chunks=share->base.raid_chunks; raid_chunks=share->base.raid_chunks;
/* /*
Skipp the checking of the file if: Skipp the checking of the file if:
We are using --fast and the table is closed properly We are using --fast and the table is closed properly
@ -606,6 +611,9 @@ static int myisamchk(MI_CHECK *param, my_string filename)
} }
else else
{ {
if (share->fulltext_index)
ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
if (!(param->testflag & T_READONLY)) if (!(param->testflag & T_READONLY))
lock_type = F_WRLCK; /* table is changed */ lock_type = F_WRLCK; /* table is changed */
else else
@ -649,9 +657,10 @@ static int myisamchk(MI_CHECK *param, my_string filename)
} }
if (!error) if (!error)
{ {
if (param->testflag & T_REP_BY_SORT && if ((param->testflag & T_REP_BY_SORT) &&
(share->state.key_map || (share->state.key_map ||
(rep_quick && !param->keys_in_use && !recreate))) (rep_quick && !param->keys_in_use && !recreate)) &&
mi_test_if_sort_rep(info, info->state->records, 1))
error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick); error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
else if (param->testflag & (T_REP | T_REP_BY_SORT)) else if (param->testflag & (T_REP | T_REP_BY_SORT))
error=mi_repair(&check_param, info,fixed_name,rep_quick); error=mi_repair(&check_param, info,fixed_name,rep_quick);
@ -662,7 +671,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
{ /* Change temp file to org file */ { /* Change temp file to org file */
VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */ VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */
error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT, error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks); raid_chunks,
MYF(0));
#ifdef USE_RAID #ifdef USE_RAID
if (share->base.raid_type) if (share->base.raid_type)
{ {
@ -811,9 +821,12 @@ end2:
{ {
if (param->out_flag & O_NEW_DATA) if (param->out_flag & O_NEW_DATA)
error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT, error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks); raid_chunks,
((param->testflag & T_BACKUP_DATA) ?
MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
if (param->out_flag & O_NEW_INDEX) if (param->out_flag & O_NEW_INDEX)
error|=change_to_newfile(fixed_name,MI_NAME_IEXT,INDEX_TMP_EXT,0); error|=change_to_newfile(fixed_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0));
} }
VOID(fflush(stdout)); VOID(fflush(stderr)); VOID(fflush(stdout)); VOID(fflush(stderr));
if (param->error_printed) if (param->error_printed)
@ -1381,6 +1394,7 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
if (param->testflag & T_SILENT) if (param->testflag & T_SILENT)
fprintf(stderr,"%s: MyISAM file %s\n",my_progname, fprintf(stderr,"%s: MyISAM file %s\n",my_progname,
param->isam_file_name); param->isam_file_name);
param->out_flag|= O_DATA_LOST;
} }
param->warning_printed=1; param->warning_printed=1;
va_start(args,fmt); va_start(args,fmt);
@ -1405,6 +1419,7 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
{ {
if (param->testflag & T_SILENT) if (param->testflag & T_SILENT)
fprintf(stderr,"%s: ISAM file %s\n",my_progname,param->isam_file_name); fprintf(stderr,"%s: ISAM file %s\n",my_progname,param->isam_file_name);
param->out_flag|= O_DATA_LOST;
} }
param->error_printed|=1; param->error_printed|=1;
va_start(args,fmt); va_start(args,fmt);

View File

@ -179,7 +179,8 @@ typedef struct st_mi_isam_share { /* Shared between opens */
global_changed, /* If changed since open */ global_changed, /* If changed since open */
not_flushed, not_flushed,
temporary,delay_key_write, temporary,delay_key_write,
concurrent_insert; concurrent_insert,
fulltext_index;
myf write_flag; myf write_flag;
int rnd; /* rnd-counter */ int rnd; /* rnd-counter */
MI_DECODE_TREE *decode_trees; MI_DECODE_TREE *decode_trees;
@ -294,7 +295,7 @@ struct st_myisam_info {
mi_int2store(x,boh); } mi_int2store(x,boh); }
#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
#define mi_mark_crashed(x) (x)->s->state.changed|=STATE_CRASHED #define mi_mark_crashed(x) (x)->s->state.changed|=STATE_CRASHED
#define mi_mark_crashed_on_repair(x) (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR #define mi_mark_crashed_on_repair(x) { (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR ; (x)->update|= HA_STATE_CHANGED; }
#define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED) #define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
#define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR) #define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)

View File

@ -23,6 +23,7 @@
/* /*
If flag & 1 Return date and time If flag & 1 Return date and time
If flag & 2 Return short date format YYMMDD If flag & 2 Return short date format YYMMDD
if flag & 4 Return time in HHMMDD format.
*/ */
@ -56,4 +57,9 @@ void get_date(register my_string to, int flag, time_t date)
start_time->tm_hour, start_time->tm_hour,
start_time->tm_min, start_time->tm_min,
start_time->tm_sec); start_time->tm_sec);
else if (flag & 4)
sprintf(strend(to),"%02d%02d%02d",
start_time->tm_hour,
start_time->tm_min,
start_time->tm_sec);
} /* get_date */ } /* get_date */

View File

@ -97,6 +97,7 @@ int my_close(File fd, myf MyFlags)
pthread_mutex_lock(&THR_LOCK_open); pthread_mutex_lock(&THR_LOCK_open);
if ((err = close(fd))) if ((err = close(fd)))
{ {
DBUG_PRINT("error",("Got error %d on close",err));
my_errno=errno; my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME)) if (MyFlags & (MY_FAE | MY_WME))
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno); my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);

View File

@ -18,6 +18,7 @@
#define USES_TYPES /* sys/types is included */ #define USES_TYPES /* sys/types is included */
#include "mysys_priv.h" #include "mysys_priv.h"
#include <my_dir.h> #include <my_dir.h>
#include <m_string.h>
#include "mysys_err.h" #include "mysys_err.h"
#if defined(HAVE_SYS_UTIME_H) #if defined(HAVE_SYS_UTIME_H)
#include <sys/utime.h> #include <sys/utime.h>
@ -30,21 +31,45 @@ struct utimbuf {
}; };
#endif #endif
/* Rename with copy stat form old file */ /*
/* Copy stats from old file to new file, deletes orginal and */ Rename with copy stat form old file
/* changes new file name to old file name */ Copy stats from old file to new file, deletes orginal and
changes new file name to old file name
if MY_REDEL_MAKE_COPY is given, then the orginal file
is renamed to org_name-'current_time'.BAK
*/
#define REDEL_EXT ".BAK"
int my_redel(const char *org_name, const char *tmp_name, myf MyFlags) int my_redel(const char *org_name, const char *tmp_name, myf MyFlags)
{ {
int error=1;
DBUG_ENTER("my_redel"); DBUG_ENTER("my_redel");
DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d",
org_name,tmp_name,MyFlags)); org_name,tmp_name,MyFlags));
if (my_copystat(org_name,tmp_name,MyFlags) < 0 || if (my_copystat(org_name,tmp_name,MyFlags) < 0)
my_delete(org_name,MyFlags) || goto end;
my_rename(tmp_name,org_name,MyFlags)) if (MyFlags & MY_REDEL_MAKE_BACKUP)
DBUG_RETURN(1); {
DBUG_RETURN(0); char name_buff[FN_REFLEN+20];
char ext[20];
ext[0]='-';
get_date(ext+1,2+4,(time_t) 0);
strmov(strend(ext),REDEL_EXT);
if (my_rename(org_name, fn_format(name_buff, org_name, "", ext, 2),
MyFlags))
goto end;
}
else if (my_delete(org_name,MyFlags))
goto end;
if (my_rename(tmp_name,org_name,MyFlags))
goto end;
error=0;
end:
DBUG_RETURN(error);
} /* my_redel */ } /* my_redel */

View File

@ -254,7 +254,7 @@ berkeley_cmp_fix_length_key(const DBT *new_key, const DBT *saved_key)
} }
int ha_berkeley::open(const char *name, int mode, int test_if_locked) int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
uint open_mode=(mode == O_RDONLY ? DB_RDONLY : 0) | DB_THREAD; uint open_mode=(mode == O_RDONLY ? DB_RDONLY : 0) | DB_THREAD;

View File

@ -87,7 +87,7 @@ class ha_berkeley: public handler
bool fast_key_read() { return 1;} bool fast_key_read() { return 1;}
bool has_transactions() { return 1;} bool has_transactions() { return 1;}
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
void initialize(void); void initialize(void);
int close(void); int close(void);
double scan_time(); double scan_time();

View File

@ -31,7 +31,7 @@ const char **ha_heap::bas_ext() const
{ static const char *ext[1]= { NullS }; return ext; } { static const char *ext[1]= { NullS }; return ext; }
int ha_heap::open(const char *name, int mode, int test_if_locked) int ha_heap::open(const char *name, int mode, uint test_if_locked)
{ {
uint key,part,parts; uint key,part,parts;
HP_KEYDEF *keydef; HP_KEYDEF *keydef;

View File

@ -44,7 +44,7 @@ class ha_heap: public handler
virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; } virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
virtual bool fast_key_read() { return 1;} virtual bool fast_key_read() { return 1;}
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);

View File

@ -37,7 +37,7 @@ const char **ha_isam::bas_ext() const
{ static const char *ext[]= { ".ISD",".ISM", NullS }; return ext; } { static const char *ext[]= { ".ISD",".ISM", NullS }; return ext; }
int ha_isam::open(const char *name, int mode, int test_if_locked) int ha_isam::open(const char *name, int mode, uint test_if_locked)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
if (!(file=nisam_open(fn_format(name_buff,name,"","",2 | 4), mode, if (!(file=nisam_open(fn_format(name_buff,name,"","",2 | 4), mode,

View File

@ -46,7 +46,7 @@ class ha_isam: public handler
uint min_record_length(uint options) const; uint min_record_length(uint options) const;
bool low_byte_first() const { return 0; } bool low_byte_first() const { return 0; }
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);

View File

@ -35,7 +35,7 @@
const char **ha_isammrg::bas_ext() const const char **ha_isammrg::bas_ext() const
{ static const char *ext[]= { ".MRG", NullS }; return ext; } { static const char *ext[]= { ".MRG", NullS }; return ext; }
int ha_isammrg::open(const char *name, int mode, int test_if_locked) int ha_isammrg::open(const char *name, int mode, uint test_if_locked)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
if (!(file=mrg_open(fn_format(name_buff,name,"","",2 | 4), mode, if (!(file=mrg_open(fn_format(name_buff,name,"","",2 | 4), mode,

View File

@ -40,7 +40,7 @@ class ha_isammrg: public handler
bool low_byte_first() const { return 0; } bool low_byte_first() const { return 0; }
uint min_record_length(uint options) const; uint min_record_length(uint options) const;
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);

View File

@ -31,6 +31,13 @@
#endif #endif
ulong myisam_sort_buffer_size; ulong myisam_sort_buffer_size;
myisam_recover_types myisam_recover_type= HA_RECOVER_NONE;
const char *myisam_recover_names[] =
{ "NO","DEFAULT", "BACKUP"};
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
myisam_recover_names};
/***************************************************************************** /*****************************************************************************
** MyISAM tables ** MyISAM tables
@ -76,6 +83,7 @@ extern "C" {
void mi_check_print_error(MI_CHECK *param, const char *fmt,...) void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
{ {
param->error_printed|=1; param->error_printed|=1;
param->out_flag|= O_DATA_LOST;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
mi_check_print_msg(param, "error", fmt, args); mi_check_print_msg(param, "error", fmt, args);
@ -93,6 +101,7 @@ void mi_check_print_info(MI_CHECK *param, const char *fmt,...)
void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
{ {
param->warning_printed=1; param->warning_printed=1;
param->out_flag|= O_DATA_LOST;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
mi_check_print_msg(param, "warning", fmt, args); mi_check_print_msg(param, "warning", fmt, args);
@ -187,15 +196,14 @@ err:
return error; return error;
} }
int ha_myisam::open(const char *name, int mode, int test_if_locked) int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
if (!(file=mi_open(fn_format(name_buff,name,"","",2 | 4), mode, if (!(file=mi_open(fn_format(name_buff,name,"","",2 | 4), mode,
test_if_locked))) test_if_locked)))
return (my_errno ? my_errno : -1); return (my_errno ? my_errno : -1);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED || if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
VOID(mi_extra(file,HA_EXTRA_NO_WAIT_LOCK)); VOID(mi_extra(file,HA_EXTRA_NO_WAIT_LOCK));
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
@ -447,7 +455,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS)))) !(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
{ {
optimize_done=1; optimize_done=1;
if (mi_test_if_sort_rep(file,file->state->records)) if (mi_test_if_sort_rep(file,file->state->records,0))
{ {
param.testflag|= T_STATISTICS; // We get this for free param.testflag|= T_STATISTICS; // We get this for free
thd->proc_info="Repairing by sorting"; thd->proc_info="Repairing by sorting";
@ -506,7 +514,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
{ {
/* /*
We have to close all instances of this file to ensure that we can We have to close all instances of this file to ensure that we can
do the rename safely and that all threads are using the new version. do the rename safely on all operating system and to ensure that
all threads are using the new version.
*/ */
thd->proc_info="renaming file"; thd->proc_info="renaming file";
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
@ -515,11 +524,11 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
if (param.out_flag & O_NEW_DATA) if (param.out_flag & O_NEW_DATA)
error|=change_to_newfile(fixed_name,MI_NAME_DEXT, error|=change_to_newfile(fixed_name,MI_NAME_DEXT,
DATA_TMP_EXT, 0); DATA_TMP_EXT, 0, MYF(0));
if (param.out_flag & O_NEW_INDEX) if (param.out_flag & O_NEW_INDEX)
error|=change_to_newfile(fixed_name,MI_NAME_IEXT, error|=change_to_newfile(fixed_name,MI_NAME_IEXT,
INDEX_TMP_EXT,0); INDEX_TMP_EXT, 0, MYF(0));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
} }

View File

@ -24,7 +24,12 @@
#include <myisam.h> #include <myisam.h>
#include <ft_global.h> #include <ft_global.h>
enum myisam_recover_types { HA_RECOVER_NONE, HA_RECOVER_DEFAULT,
HA_RECOVER_BACKUP};
extern ulong myisam_sort_buffer_size; extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib;
extern myisam_recover_types myisam_recover_type;
class ha_myisam: public handler class ha_myisam: public handler
{ {
@ -49,7 +54,7 @@ class ha_myisam: public handler
uint max_key_parts() const { return MAX_REF_PARTS; } uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; } uint max_key_length() const { return MAX_KEY_LENGTH; }
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);

View File

@ -35,7 +35,7 @@
const char **ha_myisammrg::bas_ext() const const char **ha_myisammrg::bas_ext() const
{ static const char *ext[]= { ".MRG", NullS }; return ext; } { static const char *ext[]= { ".MRG", NullS }; return ext; }
int ha_myisammrg::open(const char *name, int mode, int test_if_locked) int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode, if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,

View File

@ -46,7 +46,7 @@ class ha_myisammrg: public handler
virtual double scan_time() virtual double scan_time()
{ return ulonglong2double(data_file_length) / IO_SIZE + file->tables; } { return ulonglong2double(data_file_length) / IO_SIZE + file->tables; }
int open(const char *name, int mode, int test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int close(void); int close(void);
int write_row(byte * buf); int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data); int update_row(const byte * old_data, byte * new_data);

View File

@ -205,7 +205,7 @@ public:
virtual int index_init(uint idx) { active_index=idx; return 0;} virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; } virtual int index_end() {return 0; }
uint get_index(void) const { return active_index; } uint get_index(void) const { return active_index; }
virtual int open(const char *name, int mode, int test_if_locked)=0; virtual int open(const char *name, int mode, uint test_if_locked)=0;
virtual void initialize(void) {} virtual void initialize(void) {}
virtual int close(void)=0; virtual int close(void)=0;
virtual int write_row(byte * buf)=0; virtual int write_row(byte * buf)=0;

View File

@ -430,3 +430,4 @@ extern Item_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item); extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item); extern bool field_is_equal_to_item(Field *field,Item *item);
Item *get_system_var(LEX_STRING name);

View File

@ -2018,3 +2018,16 @@ bool Item_func_match::eq(const Item *item) const
} }
/***************************************************************************
System variables
This has to be recoded after we get more than 3 system variables
****************************************************************************/
Item *get_system_var(LEX_STRING name)
{
if (!strcmp(name.str,"IDENTITY"))
return new Item_int((char*) "@@IDENTITY",
current_thd->insert_id(),21);
my_error(ER_UNKNOWN_SYSTEM_VARIABLE,MYF(0),name);
return 0;
}

View File

@ -252,6 +252,7 @@ static SYMBOL symbols[] = {
{ "RESTRICT", SYM(RESTRICT),0,0}, { "RESTRICT", SYM(RESTRICT),0,0},
{ "RETURNS", SYM(UDF_RETURNS_SYM),0,0}, { "RETURNS", SYM(UDF_RETURNS_SYM),0,0},
{ "REVOKE", SYM(REVOKE),0,0}, { "REVOKE", SYM(REVOKE),0,0},
{ "RIGHT", SYM(RIGHT),0,0},
{ "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */ { "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */
{ "ROLLBACK", SYM(ROLLBACK_SYM),0,0}, { "ROLLBACK", SYM(ROLLBACK_SYM),0,0},
{ "ROW", SYM(ROW_SYM),0,0}, { "ROW", SYM(ROW_SYM),0,0},
@ -414,7 +415,6 @@ static SYMBOL sql_functions[] = {
{ "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, { "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
{ "REPEAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_repeat)}, { "REPEAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_repeat)},
{ "REVERSE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)}, { "REVERSE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
{ "RIGHT", SYM(RIGHT),0,0},
{ "ROUND", SYM(ROUND),0,0}, { "ROUND", SYM(ROUND),0,0},
{ "RPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)}, { "RPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
{ "RTRIM", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)}, { "RTRIM", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)},

View File

@ -94,13 +94,15 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
} }
else else
info->buffer=0; info->buffer=0;
DBUG_PRINT("info",("init_io_cache: cachesize = %u",cachesize));
info->pos_in_file= seek_offset; info->pos_in_file= seek_offset;
info->read_length=info->buffer_length=cachesize; info->read_length=info->buffer_length=cachesize;
info->seek_not_done=test(file >= 0); /* Seek not done */ info->seek_not_done= test(file >= 0 && type != READ_FIFO &&
type != READ_NET);
info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP); info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
info->rc_request_pos=info->rc_pos=info->buffer; info->rc_request_pos=info->rc_pos=info->buffer;
if (type == READ_CACHE || type == READ_NET) /* the same logic */ if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
{ {
info->rc_end=info->buffer; /* Nothing in cache */ info->rc_end=info->buffer; /* Nothing in cache */
} }
@ -108,7 +110,9 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
{ {
info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1)); info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
} }
info->end_of_file=(type == READ_NET) ? 0 : MY_FILEPOS_ERROR; /* May be changed by user */ /* end_of_file may be changed by user later */
info->end_of_file= ((type == READ_NET || type == READ_FIFO ) ? 0
: MY_FILEPOS_ERROR);
info->type=type; info->type=type;
info->error=0; info->error=0;
info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read; /* net | file */ info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read; /* net | file */
@ -187,7 +191,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
DBUG_RETURN(1); DBUG_RETURN(1);
info->pos_in_file=seek_offset; info->pos_in_file=seek_offset;
info->rc_request_pos=info->rc_pos=info->buffer; info->rc_request_pos=info->rc_pos=info->buffer;
if (type == READ_CACHE || type == READ_NET) if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
{ {
info->rc_end=info->buffer; /* Nothing in cache */ info->rc_end=info->buffer; /* Nothing in cache */
} }
@ -195,7 +199,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
{ {
info->rc_end=info->buffer+info->buffer_length- info->rc_end=info->buffer+info->buffer_length-
(seek_offset & (IO_SIZE-1)); (seek_offset & (IO_SIZE-1));
info->end_of_file=(type == READ_NET) ? 0 : MY_FILEPOS_ERROR; info->end_of_file= ((type == READ_NET || type == READ_FIFO) ? 0 :
MY_FILEPOS_ERROR);
} }
} }
info->type=type; info->type=type;
@ -259,9 +264,10 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
left_length+=length; left_length+=length;
diff_length=0; diff_length=0;
} }
max_length=info->end_of_file - pos_in_file;
if (max_length > info->read_length-diff_length)
max_length=info->read_length-diff_length; max_length=info->read_length-diff_length;
if (info->type != READ_FIFO &&
(info->end_of_file - pos_in_file) < max_length)
max_length = info->end_of_file - pos_in_file;
if (!max_length) if (!max_length)
{ {
if (Count) if (Count)

View File

@ -2200,7 +2200,7 @@ enum options {
OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB,
OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB,
OPT_BINLOG_IGNORE_DB, OPT_WANT_CORE, OPT_BINLOG_IGNORE_DB, OPT_WANT_CORE,
OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER,
}; };
static struct option long_options[] = { static struct option long_options[] = {
@ -2254,6 +2254,7 @@ static struct option long_options[] = {
{"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, {"master-port", required_argument, 0, (int) OPT_MASTER_PORT},
{"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY},
{"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE},
{"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER},
{"memlock", no_argument, 0, (int) OPT_MEMLOCK}, {"memlock", no_argument, 0, (int) OPT_MEMLOCK},
{"new", no_argument, 0, 'n'}, {"new", no_argument, 0, 'n'},
{"old-protocol", no_argument, 0, 'o'}, {"old-protocol", no_argument, 0, 'o'},
@ -2854,11 +2855,13 @@ static void get_options(int argc,char **argv)
default_table_type=DB_TYPE_ISAM; default_table_type=DB_TYPE_ISAM;
myisam_delay_key_write=0; myisam_delay_key_write=0;
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
myisam_recover_type= HA_RECOVER_NONE;
break; break;
case (int) OPT_SAFE: case (int) OPT_SAFE:
opt_specialflag|= SPECIAL_SAFE_MODE; opt_specialflag|= SPECIAL_SAFE_MODE;
myisam_delay_key_write=0; myisam_delay_key_write=0;
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
myisam_recover_type= HA_RECOVER_NONE; // For now
break; break;
case (int) OPT_SKIP_CONCURRENT_INSERT: case (int) OPT_SKIP_CONCURRENT_INSERT:
myisam_concurrent_insert=0; myisam_concurrent_insert=0;
@ -3020,6 +3023,17 @@ static void get_options(int argc,char **argv)
berkeley_skip=1; berkeley_skip=1;
break; break;
#endif #endif
case OPT_MYISAM_RECOVER:
{
int type;
if ((type=find_type(optarg, &myisam_recover_typelib, 2)) <= 0)
{
fprintf(stderr,"Unknown option to myisam-recover: %s\n",optarg);
exit(1);
}
myisam_recover_type=(myisam_recover_types) (type-1);
break;
}
case OPT_MASTER_HOST: case OPT_MASTER_HOST:
master_host=optarg; master_host=optarg;
break; break;

Binary file not shown.

View File

@ -208,3 +208,4 @@
"S-Bí»ová chyba pøi zápisu na master",-A "S-Bí»ová chyba pøi zápisu na master",-A
"-B®ádný sloupec nemá vytvoøen fulltextový index",-A "-B®ádný sloupec nemá vytvoøen fulltextový index",-A
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -197,3 +197,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -198,3 +198,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -197,3 +197,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -196,3 +196,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Errore di rete inviando al master", "Errore di rete inviando al master",
"Impossibile trovare un indice FULLTEXT che corrisponda all'elenco delle colonne", "Impossibile trovare un indice FULLTEXT che corrisponda all'elenco delle colonne",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -196,3 +196,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

View File

@ -196,3 +196,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

View File

@ -196,3 +196,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -198,3 +198,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -194,3 +194,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

View File

@ -198,3 +198,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -197,3 +197,4 @@
"Net error writing to master", "Net error writing to master",
"FULLTEXT ÉÎÄÅËÓ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÊ ÚÁÄÁÎÎÏÍÕ ÓÐÉÓËÕ ÓÔÏÌÂÃÏ×, ÎÅ ÎÁÊÄÅÎ", "FULLTEXT ÉÎÄÅËÓ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÊ ÚÁÄÁÎÎÏÍÕ ÓÐÉÓËÕ ÓÔÏÌÂÃÏ×, ÎÅ ÎÁÊÄÅÎ",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -202,3 +202,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

Binary file not shown.

View File

@ -195,3 +195,4 @@
"Net error writing to master", "Net error writing to master",
"Can't find FULLTEXT index matching the column list", "Can't find FULLTEXT index matching the column list",
"Can't execute the given command because you have active locked tables or an active transaction", "Can't execute the given command because you have active locked tables or an active transaction",
"Unknown system variable '%-.64'",

View File

@ -192,5 +192,7 @@
"Fick en master: '%-.64s'", "Fick en master: '%-.64s'",
"Fick nätverksfel vid läsning från master", "Fick nätverksfel vid läsning från master",
"Fick nätverksfel vid skrivning till master", "Fick nätverksfel vid skrivning till master",
"Hittar inte ett FULLTEXT index i kolumnlist", "Hittar inte ett FULLTEXT index i kolumnlistan",
"Can't execute the given command because you have active locked tables or an active transaction", "Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion",
#ER_UNKNOWN_SYSTEM_VARIABLE
"Okänd system variabel '%-.64'",

Binary file not shown.

View File

@ -192,5 +192,6 @@
"Fick en master: '%-.64s'", "Fick en master: '%-.64s'",
"Fick nätverksfel vid läsning från master", "Fick nätverksfel vid läsning från master",
"Fick nätverksfel vid skrivning till master", "Fick nätverksfel vid skrivning till master",
"Hittar inte ett FULLTEXT index i kolumnlist", "Hittar inte ett FULLTEXT index i kolumnlistan",
"Can't execute the given command because you have active locked tables or an active transaction", "Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion",
"Okänd system variabel '%-.64'",

View File

@ -66,8 +66,10 @@ static int send_file(THD *thd)
} }
fn_format(fname, (char*)net->read_pos + 1, "", "", 4); fn_format(fname, (char*)net->read_pos + 1, "", "", 4);
if(!strcmp(fname,"/dev/null")) goto end; // this is needed to make replicate-ignore-db // this is needed to make replicate-ignore-db
// work on the well-known system that does not have a /dev/null :-) if (!strcmp(fname,"/dev/null"))
goto end;
// TODO: work on the well-known system that does not have a /dev/null :-)
if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
{ {
@ -1951,6 +1953,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
/* Check if we are using outer joins */ /* Check if we are using outer joins */
for (TABLE_LIST *table=tables ; table ; table=table->next) for (TABLE_LIST *table=tables ; table ; table=table->next)
{ {
if (table->on_expr)
{
/* Make a join an a expression */
thd->where="on clause";
if (table->on_expr->fix_fields(thd,tables))
DBUG_RETURN(1);
thd->cond_count++;
/* If it's a normal join, add the ON/USING expression to the WHERE */
if (!table->outer_join)
{
if (!(*conds=and_conds(*conds, table->on_expr)))
DBUG_RETURN(1);
table->on_expr=0;
}
}
if (table->natural_join) if (table->natural_join)
{ {
/* Make a join of all fields with have the same name */ /* Make a join of all fields with have the same name */
@ -1990,23 +2008,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
else else
table->on_expr=cond_and; table->on_expr=and_conds(table->on_expr,cond_and);
}
else if (table->on_expr)
{
/* Make a join an a expression */
thd->where="on clause";
if (table->on_expr->fix_fields(thd,tables))
DBUG_RETURN(1);
thd->cond_count++;
/* If it's a normal join, add the ON/USING expression to the WHERE */
if (!table->outer_join)
{
if (!(*conds=and_conds(*conds, table->on_expr)))
DBUG_RETURN(1);
table->on_expr=0;
}
} }
} }
DBUG_RETURN(test(thd->fatal_error)); DBUG_RETURN(test(thd->fatal_error));

View File

@ -91,8 +91,7 @@ exit:
} }
const char *del_exts[]= const char *del_exts[]=
{".frm",".ISM",".ISD",".ISM",".HSH",".DAT",".MRG",".PSM",".MYI",".MYD", ".db", {".frm",".ISM",".ISD",".ISM",".HSH",".DAT",".MRG",".MYI",".MYD", ".db", ".BAK", NullS};
NullS};
static TYPELIB deletable_extentions= static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts}; {array_elements(del_exts)-1,"del_exts", del_exts};

View File

@ -42,7 +42,7 @@ public:
READ_INFO(File file,uint tot_length, READ_INFO(File file,uint tot_length,
String &field_term,String &line_start,String &line_term, String &field_term,String &line_start,String &line_term,
String &enclosed,int escape,bool get_it_from_net); String &enclosed,int escape,bool get_it_from_net, bool is_fifo);
~READ_INFO(); ~READ_INFO();
int read_field(); int read_field();
int read_fixed_length(void); int read_fixed_length(void);
@ -70,6 +70,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
uint save_skip_lines = ex->skip_lines; uint save_skip_lines = ex->skip_lines;
String *field_term=ex->field_term,*escaped=ex->escaped, String *field_term=ex->field_term,*escaped=ex->escaped,
*enclosed=ex->enclosed; *enclosed=ex->enclosed;
bool is_fifo=0;
DBUG_ENTER("mysql_load"); DBUG_ENTER("mysql_load");
if (escaped->length() > 1 || enclosed->length() > 1) if (escaped->length() > 1 || enclosed->length() > 1)
@ -161,22 +162,16 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_RETURN(-1); DBUG_RETURN(-1);
// the file must be: // the file must be:
if (!( if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
(stat_info.st_mode & S_IROTH) == S_IROTH (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
&& // readable by others ((stat_info.st_mode & S_IFREG) == S_IFREG ||
(stat_info.st_mode & S_IFLNK) != S_IFLNK (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
&& // and not a symlink
((stat_info.st_mode & S_IFREG) == S_IFREG
||
(stat_info.st_mode & S_IFIFO) == S_IFIFO
)
// and either regular or a pipe
)
)
{ {
my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name); my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
is_fifo = 1;
#endif #endif
} }
if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
@ -190,7 +185,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
READ_INFO read_info(file,tot_length,*field_term, READ_INFO read_info(file,tot_length,*field_term,
*ex->line_start, *ex->line_term, *enclosed, *ex->line_start, *ex->line_term, *enclosed,
info.escape_char,read_file_from_client); info.escape_char, read_file_from_client, is_fifo);
if (read_info.error) if (read_info.error)
{ {
if (file >= 0) if (file >= 0)
@ -423,7 +418,8 @@ READ_INFO::unescape(char chr)
READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term, READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
String &line_start, String &line_term, String &line_start, String &line_term,
String &enclosed_par, int escape, bool get_it_from_net) String &enclosed_par, int escape, bool get_it_from_net,
bool is_fifo)
:file(file_par),escape_char(escape) :file(file_par),escape_char(escape)
{ {
field_term_ptr=(char*) field_term.ptr(); field_term_ptr=(char*) field_term.ptr();
@ -467,7 +463,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
{ {
end_of_buff=buffer+buff_length; end_of_buff=buffer+buff_length;
if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0, if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0,
(get_it_from_net) ? READ_NET : READ_CACHE,0L,1, (get_it_from_net) ? READ_NET :
(is_fifo ? READ_FIFO : READ_CACHE),0L,1,
MYF(MY_WME))) MYF(MY_WME)))
{ {
my_free((gptr) buffer,MYF(0)); /* purecov: inspected */ my_free((gptr) buffer,MYF(0)); /* purecov: inspected */

View File

@ -2387,7 +2387,13 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
void add_join_on(TABLE_LIST *b,Item *expr) void add_join_on(TABLE_LIST *b,Item *expr)
{ {
if (!b->on_expr)
b->on_expr=expr; b->on_expr=expr;
else
{
// This only happens if you have both a right and left join
b->on_expr=new Item_cond_and(b->on_expr,expr);
}
} }

View File

@ -810,7 +810,10 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
} }
s->key_dependent=s->dependent= s->key_dependent=s->dependent=
s->on_expr->used_tables() & ~(table->map); s->on_expr->used_tables() & ~(table->map);
if (table->outer_join & JOIN_TYPE_LEFT)
s->dependent|=stat_vector[i-1]->dependent | table_vector[i-1]->map; s->dependent|=stat_vector[i-1]->dependent | table_vector[i-1]->map;
if (tables->outer_join & JOIN_TYPE_RIGHT)
s->dependent|=tables->next->table->map;
outer_join|=table->map; outer_join|=table->map;
continue; continue;
} }

View File

@ -839,8 +839,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
packet->length(0); packet->length(0);
if (operator_func == &handler::restore) if (operator_func == &handler::restore)
{ {
switch(prepare_for_restore(thd, table)) switch (prepare_for_restore(thd, table)) {
{
case 1: continue; // error, message written to net case 1: continue; // error, message written to net
case -1: goto err; // error, message could be written to net case -1: goto err; // error, message could be written to net
default: ;// should be 0 otherwise default: ;// should be 0 otherwise

View File

@ -1392,6 +1392,7 @@ simple_expr:
| literal | literal
| '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); } | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); }
| '@' ident_or_text { $$= new Item_func_get_user_var($2); } | '@' ident_or_text { $$= new Item_func_get_user_var($2); }
| '@' '@' ident_or_text { if (!($$= get_system_var($3))) YYABORT; }
| sum_expr | sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); } | '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); } | '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
@ -1700,14 +1701,23 @@ join_table_list:
USING '(' using_list ')' USING '(' using_list ')'
{ add_join_on($4,$8); $$=$4; } { add_join_on($4,$8); $$=$4; }
| join_table_list LEFT opt_outer JOIN_SYM join_table ON expr | join_table_list LEFT opt_outer JOIN_SYM join_table ON expr
{ add_join_on($5,$7); $5->outer_join=1; $$=$5; } { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| join_table_list LEFT opt_outer JOIN_SYM join_table | join_table_list LEFT opt_outer JOIN_SYM join_table
{ Lex->db1=$1->db; Lex->table1=$1->name; { Lex->db1=$1->db; Lex->table1=$1->name;
Lex->db2=$5->db; Lex->table2=$5->name; } Lex->db2=$5->db; Lex->table2=$5->name; }
USING '(' using_list ')' USING '(' using_list ')'
{ add_join_on($5,$9); $5->outer_join=1; $$=$5; } { add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table
{ add_join_natural($1,$6); $6->outer_join=1; $$=$6; } { add_join_natural($1,$6); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; }
| join_table_list RIGHT opt_outer JOIN_SYM join_table ON expr
{ add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list RIGHT opt_outer JOIN_SYM join_table
{ Lex->db1=$1->db; Lex->table1=$1->name;
Lex->db2=$5->db; Lex->table2=$5->name; }
USING '(' using_list ')'
{ add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table
{ add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
| join_table_list NATURAL JOIN_SYM join_table | join_table_list NATURAL JOIN_SYM join_table
{ add_join_natural($1,$4); $$=$4; } { add_join_natural($1,$4); $$=$4; }
@ -1722,7 +1732,7 @@ join_table:
{ if (!($$=add_table_to_list($2,$3,TL_UNLOCK, Lex->use_index_ptr, { if (!($$=add_table_to_list($2,$3,TL_UNLOCK, Lex->use_index_ptr,
Lex->ignore_index_ptr))) YYABORT; } Lex->ignore_index_ptr))) YYABORT; }
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
{ add_join_on($7,$9); $7->outer_join=1; $$=$7; } { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
opt_outer: opt_outer:
/* empty */ {} /* empty */ {}

View File

@ -451,8 +451,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (ha_option & HA_HAVE_KEY_READ_ONLY && if (ha_option & HA_HAVE_KEY_READ_ONLY &&
field->key_length() == key_part->length) field->key_length() == key_part->length)
{ {
if (field->key_type() != HA_KEYTYPE_TEXT || if (field->key_type() != HA_KEYTYPE_TEXT &&
!(ha_option & HA_KEY_READ_WRONG_STR)) !(ha_option & HA_KEY_READ_WRONG_STR) &&
!(keyinfo->flags & HA_FULLTEXT))
field->part_of_key|= ((key_map) 1 << key); field->part_of_key|= ((key_map) 1 << key);
} }
if (!(key_part->key_part_flag & HA_REVERSE_SORT) && if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&

View File

@ -123,15 +123,18 @@ struct st_table {
}; };
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2
typedef struct st_table_list { typedef struct st_table_list {
struct st_table_list *next; struct st_table_list *next;
char *db,*name,*real_name; char *db,*name,*real_name;
thr_lock_type lock_type;
bool straight; /* optimize with prev table */
bool outer_join;
TABLE *table;
Item *on_expr; /* Used with outer join */ Item *on_expr; /* Used with outer join */
struct st_table_list *natural_join; /* natural join on this table*/ struct st_table_list *natural_join; /* natural join on this table*/
List<String> *use_index,*ignore_index; List<String> *use_index,*ignore_index;
TABLE *table;
GRANT_INFO grant; GRANT_INFO grant;
thr_lock_type lock_type;
uint outer_join; /* Which join type */
bool straight; /* optimize with prev table */
} TABLE_LIST; } TABLE_LIST;