Commit 09dce662 authored by monty@tik.mysql.com's avatar monty@tik.mysql.com

Automatic repair of MyISAM tables + portability fixes

parent 16f11f94
monty@tramp.mysql.fi
monty@donna.mysql.com
monty@tik.mysql.com
......@@ -315,7 +315,7 @@ Is There Anything Special to Do when Upgrading/Downgrading MySQL?
How Standards-compatible Is MySQL?
* Extensions to ANSI:: @strong{MySQL} extensions to ANSI SQL92
* Ansi mode:: Running @strong{MySQL} in ANSI mode
* ANSI mode:: Running @strong{MySQL} in ANSI mode
* Differences from ANSI:: @strong{MySQL} differences compared to ANSI SQL92
* Missing functions:: Functionality missing from @strong{MySQL}
* Standards:: What standards does @strong{MySQL} follow?
......@@ -1550,7 +1550,8 @@ clauses. Support for group functions (@code{COUNT()},
@code{MAX()} and @code{MIN()}).
@item
Support for @code{LEFT OUTER JOIN} with ANSI SQL and ODBC syntax.
Support for @code{LEFT OUTER JOIN} and @code{RIGHT OUTER JOIN} with ANSI
SQL and ODBC syntax.
@item
You can mix tables from different databases in the same query (as of
......@@ -6024,6 +6025,16 @@ you are probably using @code{gcc} (or using an old binary compiled with
/usr/bin/perl: can't resolve symbol '__divdi3'
@end example
Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command when the
@file{mysql.so} library gets built (check the output from @code{make} for
@file{mysql.so} when you compile the Perl client). The @code{-L} option
should specify the pathname of the directory where @file{libgcc.a} is located
on your system.
Another cause of this problem may be that Perl and @strong{MySQL} aren't both
compiled with @code{gcc}. In this case, you can solve the mismatch by
compiling both with @code{gcc}.
If you get the following error from @code{Msql-Mysql-modules}
when you run the tests:
......@@ -6032,7 +6043,8 @@ t/00base............install_driver(mysql) failed: Can't load '../blib/arch/auto/
@end example
it means that you need to include the compression library, -lz, to the
link line. This can be done by changing the line:
link line. This can be doing the following change in the file
@file{lib/DBD/mysql/Install.pm}:
@example
$sysliblist .= " -lm";
......@@ -6042,20 +6054,9 @@ to
$sysliblist .= " -lm -lz";
@end example
in file lib/DBD/mysql/Install.pm in the Msql-Mysql-modules directory.
After this, you MUST run 'make realclean' and then proceed with the
installation from the beginning.
Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command when the
@file{mysql.so} library gets built (check the output from @code{make} for
@file{mysql.so} when you compile the Perl client). The @code{-L} option
should specify the pathname of the directory where @file{libgcc.a} is located
on your system.
Another cause of this problem may be that Perl and @strong{MySQL} aren't both
compiled with @code{gcc}. In this case, you can solve the mismatch by
compiling both with @code{gcc}.
If you want to use the Perl module on a system that doesn't support dynamic
linking (like SCO) you can generate a static version of Perl that includes
@code{DBI} and @code{DBD-mysql}. The way this works is that you generate a
......@@ -8931,7 +8932,7 @@ The @code{mysql.server} script uses the following variables:
@table @code
@item --ansi
Use ANSI SQL syntax instead of MySQL syntax. @xref{Ansi mode}.
Use ANSI SQL syntax instead of MySQL syntax. @xref{ANSI mode}.
@item -b, --basedir=path
Path to installation directory. All paths are
......@@ -9631,14 +9632,14 @@ information.
@menu
* Extensions to ANSI:: @strong{MySQL} extensions to ANSI SQL92
* Ansi mode:: Running @strong{MySQL} in ANSI mode
* ANSI mode:: Running @strong{MySQL} in ANSI mode
* Differences from ANSI:: @strong{MySQL} differences compared to ANSI SQL92
* Missing functions:: Functionality missing from @strong{MySQL}
* Standards:: What standards does @strong{MySQL} follow?
* Commit-rollback:: How to cope without @code{COMMIT}-@code{ROLLBACK}
@end menu
@node Extensions to ANSI, Ansi mode, Compatibility, Compatibility
@node Extensions to ANSI, ANSI mode, Compatibility, Compatibility
@section MySQL Extensions to ANSI SQL92
@strong{MySQL} includes some extensions that you probably will not find in
......@@ -9882,7 +9883,7 @@ SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
@end itemize
@node Ansi mode, Differences from ANSI, Extensions to ANSI, Compatibility
@node ANSI mode, Differences from ANSI, Extensions to ANSI, Compatibility
@section Running MySQL in ANSI Mode
@cindex running, ANSI mode
@cindex ANSI mode, running
......@@ -9895,7 +9896,7 @@ of @strong{MySQL} changes:
@code{||} is string concatenation instead of @code{OR}.
@item
You can have any number of spaces between a function name and the @samp{(}.
This makes also all function names reserved words.
This forces all function names to be treated as reserved words.
@item
@samp{"} will be an identifier quote character (like the @strong{MySQL}
@samp{`} quote character) and not a string quote character.
......@@ -9904,7 +9905,7 @@ This makes also all function names reserved words.
@code{DOUBLE}.
@end itemize
@node Differences from ANSI, Missing functions, Ansi mode, Compatibility
@node Differences from ANSI, Missing functions, ANSI mode, Compatibility
@section MySQL Differences Compared to ANSI SQL92
We try to make @strong{MySQL} follow the ANSI SQL standard and the
......@@ -9913,7 +9914,8 @@ differently:
@itemize @bullet
@item
@code{--} is only a comment if followed by a white space. @xref{Missing comments}.
@code{--} is only a comment if followed by a white space. @xref{Missing
comments}.
@item
For @code{VARCHAR} columns, trailing spaces are removed when the value is
stored. @xref{Bugs}.
......@@ -9936,11 +9938,11 @@ extra conditions in this case.
@cindex functionality, missing
The following functionality is missing in the current version of
@strong{MySQL}. For a prioritized list indicating when new extensions may be
added to @strong{MySQL}, you should consult
@uref{http://www.mysql.com/documentation/manual.php?section=TODO, the online
@strong{MySQL} TODO list}. That is the latest version of the TODO list in
this manual. @xref{TODO}.
@strong{MySQL}. For a prioritized list indicating when new extensions
may be added to @strong{MySQL}, you should consult
@uref{http://www.mysql.com/documentation/manual.php?section=TODO, the
online @strong{MySQL} TODO list}. That is the latest version of the TODO
list in this manual. @xref{TODO}.
@menu
* Missing Sub-selects:: Sub-selects
......@@ -12726,8 +12728,8 @@ Database, table, index, column, and alias names all follow the same rules in
@tindex "
Note that the rules changed starting with @strong{MySQL} Version 3.23.6 when we
introduced quoting of identifiers (database, table, and column names)
with @samp{`} (@samp{"} will also work to quote identifiers if you run
in ANSI mode).
with @samp{`}. @samp{"} will also work to quote identifiers if you run
in ANSI mode. @xref{ANSI mode}.
@multitable @columnfractions .15 .15 .70
@item @strong{Identifier} @tab @strong{Max length} @tab @strong{Allowed characters}
......@@ -13405,7 +13407,7 @@ standard, @strong{MySQL} recognizes @code{DOUBLE} as a synonym for the
@code{DOUBLE PRECISION} type. In contrast with the standard's
requirement that the precision for @code{REAL} be smaller than that used
for @code{DOUBLE PRECISION}, @strong{MySQL} implements both as 8-byte
double-precision floating-point values (when not running in ``Ansi mode'').
double-precision floating-point values (when not running in ``ANSI mode'').
For maximum portability, code requiring storage of approximate numeric
data values should use @code{FLOAT} or @code{DOUBLE PRECISION} with no
specification of precision or number of decimal points.
......@@ -17838,7 +17840,9 @@ running!
@section @code{CHECK TABLE} Syntax
@example
CHECK TABLE tbl_name[,tbl_name...] [TYPE = [QUICK | FAST | EXTEND | CHANGED]]
CHECK TABLE tbl_name[,tbl_name...] [option [option...]]
option = QUICK | FAST | EXTEND | CHANGED
@end example
@code{CHECK TABLE} only works on @code{MyISAM} tables and is the same thing
......@@ -17872,6 +17876,14 @@ The different check types stand for the following:
@item @code{EXTENDED} @tab Do a full key lookup for all keys for each row. This ensures that the table is 100 % consistent, but will take a long time!
@end multitable
You can combine check options as in:
@example
CHECK TABLE test_table FAST QUICK;
@end example
Which only would do a quick check on the table if it wasn't closed properly.
If a table is corrupted, then it's most likely that the problem is in
the indexes and not in the data part. All of the above check types
checks the indexes throughly and should thus find most errors.
......@@ -17881,7 +17893,8 @@ no check options or the @code{QUICK} option. The later should be used
when you are in a hurry and can take the very small risk that
@code{QUICK} didn't find an error in the data file (In most cases
@strong{MySQL} should find, under normal usage, any error in the data
file. If this happens then the table will be marked as 'corrupted'.
file. If this happens then the table will be marked as 'corrupted',
in which case the table can't be used until it's repaired).
@code{FAST} and @code{CHANGED} are mostly intended to be used from a
script (for example to be executed from cron) if you want to check your
......@@ -17988,7 +18001,7 @@ the table will not be analyzed again.
@section @code{REPAIR TABLE} syntax
@example
REPAIR TABLE tbl_name[,tbl_name...] [TYPE = QUICK]
REPAIR TABLE tbl_name[,tbl_name...] [QUICK]
@end example
@code{REPAIR TABLE} only works on @code{MyISAM} tables and is the same things
......@@ -18012,7 +18025,7 @@ repairing the table with @code{myisamchk -o}, as @code{REPAIR TABLE}
does not yet implement all the options of @code{myisamchk}. In the near
future, we will make it more flexible.
If @code{TYPE=QUICK} is given then @strong{MySQL} will try to do a
If @code{QUICK} is given then @strong{MySQL} will try to do a
@code{REPAIR} of only the index tree.
@findex DELETE
......@@ -19692,7 +19705,7 @@ indicates 16 megabytes. The case of suffix letters does not matter;
@table @code
@item @code{ansi_mode}.
Is @code{ON} if @code{mysqld} was started with @code{--ansi}.
@xref{Ansi mode}.
@xref{ANSI mode}.
@item @code{back_log}
The number of outstanding connection requests @strong{MySQL} can have. This
......@@ -37858,6 +37871,13 @@ though, so 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.26
@itemize @bullet
@item
Automatic repair of @code{MyISAM} tables if you start @code{mysqld} with
@code{--myisam-recover}.
@item
Removed the @code{TYPE=} keyword from @code{CHECK} and
@code{REPAIR}. Allow one to combine @code{CHECK} options. (One can still
use @code{TYPE=} but this usage is deprecated).
@item
Added optimization of queries where @code{DISTINCT} is only used on columns
from some of the tables.
@item
......@@ -46,6 +46,7 @@
#define HA_OPEN_TMP_TABLE 4 /* Table is a temp table */
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
#define HA_OPEN_ABORT_IF_CRASHED 16
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
/* The following is parameter to ha_rkey() how to use key */
......
......@@ -308,22 +308,23 @@ typedef struct st_sort_info {
typedef struct st_mi_check_param
{
ulonglong auto_increment_value;
ulonglong max_data_file_length;
ulonglong keys_in_use;
my_off_t search_after_block;
my_off_t new_file_pos,key_file_blocks;
my_off_t keydata,totaldata,key_blocks,start_check_pos;
ha_rows total_records,total_deleted;
ha_checksum record_checksum,glob_crc;
ulong use_buffers,read_buffer_length,write_buffer_length,
sort_buffer_length,sort_key_blocks;
uint out_flag,warning_printed,error_printed,
opt_rep_quick,verbose;
uint opt_sort_key,total_files,max_level;
uint testflag;
uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
uint testflag;
ha_rows total_records,total_deleted;
ulonglong auto_increment_value;
my_off_t search_after_block;
ulonglong max_data_file_length;
ulonglong keys_in_use;
my_off_t new_file_pos,key_file_blocks;
my_off_t keydata,totaldata,key_blocks,start_check_pos;
ha_checksum record_checksum,glob_crc;
my_bool retry_repair,retry_without_quick;
char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir;
int tmpfile_createflag;
myf myf_rw;
......
......@@ -64,7 +64,7 @@ static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
return NULL;
}
/* Handle the case where all columns are NULL */
if (!parsed && !(parsed=ft_parse(0, "", 0)))
if (!parsed && !(parsed=ft_parse(0, (byte*) "", 0)))
return NULL;
return ft_linearize(info, keynr, keybuf, parsed);
}
......
......@@ -192,6 +192,7 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
}
DBUG_RETURN(0);
wrong:
param->retry_without_quick=1; // Don't use quick repair
if (test_flag & T_VERBOSE) puts("");
mi_check_print_error(param,"record delete-link-chain corrupted");
DBUG_RETURN(1);
......@@ -291,6 +292,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
error=1;
mi_check_print_error(param,"Size of datafile is: %-8s Should be: %s",
llstr(size,buff), llstr(skr,buff2));
param->retry_without_quick=1; // Don't use quick repair
}
else
{
......@@ -750,7 +752,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
{
if (block_info.block_len < info->s->base.min_block_length)
{
mi_check_print_error(param,"Deleted block with impossible length %lu at %s",
mi_check_print_error(param,
"Deleted block with impossible length %lu at %s",
block_info.block_len,llstr(pos,llbuff));
goto err2;
}
......@@ -1071,7 +1074,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
new_file= -1;
if (!(param->testflag & T_SILENT))
{
printf("- recovering MyISAM-table '%s'\n",name);
printf("- recovering (with keycache) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(info->state->records,llbuff));
}
......@@ -1211,6 +1214,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
param->retry_repair=param->retry_without_quick=1;
goto err;
}
......@@ -1651,7 +1655,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
share->pack.header_length;
if (!(param->testflag & T_SILENT))
{
printf("- recovering MyISAM-table '%s'\n",name);
printf("- recovering (with sort) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff));
}
bzero((char*) sort_info,sizeof(*sort_info));
......@@ -1805,7 +1809,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
if (_create_index_by_sort(&sort_param,
(my_bool) (!(param->testflag & T_VERBOSE)),
(uint) param->sort_buffer_length))
{
param->retry_repair=1;
goto err;
}
/* Set for next loop */
sort_param.max_records=sort_info->max_records=
......@@ -1862,6 +1869,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
param->retry_repair=param->retry_without_quick=1;
goto err;
}
......@@ -3037,7 +3045,8 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
even if the temporary file would be quite big!
*/
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, my_bool force)
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
my_bool force __attribute__((unused)))
{
MYISAM_SHARE *share=info->s;
uint i;
......
......@@ -174,9 +174,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base);
share->state.state_length=base_pos;
if ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
((share->state.changed & STATE_CRASHED) ||
(my_disable_locking && share->state.open_count)))
((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
(my_disable_locking && share->state.open_count))))
{
DBUG_PRINT("error",("Table is marked as crashed"));
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
......
......@@ -92,7 +92,7 @@ int main(int argc, char **argv)
error=0;
while (--argc >= 0)
{
error|= myisamchk(&check_param, *(argv++));
int new_error=myisamchk(&check_param, *(argv++));
VOID(fflush(stdout));
VOID(fflush(stderr));
if ((check_param.error_printed | check_param.warning_printed) &&
......@@ -101,13 +101,16 @@ int main(int argc, char **argv)
T_SORT_INDEX))))
{
uint old_testflag=check_param.testflag;
check_param.testflag|=T_REP;
if (!(check_param.testflag & T_REP))
check_param.testflag|= T_REP_BY_SORT;
check_param.testflag&= ~T_EXTEND; /* Don't needed */
error|=myisamchk(&check_param, argv[-1]);
check_param.testflag= old_testflag;
VOID(fflush(stdout));
VOID(fflush(stderr));
}
else
error|=new_error;
if (argc && (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO))
{
puts("\n---------\n");
......@@ -193,7 +196,7 @@ static struct option long_options[] =
static void print_version(void)
{
printf("%s Ver 1.32 for %s at %s\n",my_progname,SYSTEM_TYPE,
printf("%s Ver 1.34 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
}
......@@ -229,7 +232,7 @@ static void usage(void)
-f, --force Restart with -r if there are any errors in the table\n\
-i, --information Print statistics information about table that is checked\n\
-m, --medium-check Faster than extended-check, but only finds 99.99% of\n\
all errors. Should however be good enough for most cases\n\
all errors. Should be good enough for most cases\n\
-U --update-state Mark tables as crashed if you find any errors\n\
-T, --read-only Don't mark table as checked\n");
......@@ -488,10 +491,11 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (!(info=mi_open(filename,
(param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR,
(param->testflag & T_WAIT_FOREVER) ?
HA_OPEN_FOR_REPAIR |
((param->testflag & T_WAIT_FOREVER) ?
HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ?
HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED)))
HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
{
/* Avoid twice printing of isam file name */
param->error_printed=1;
......@@ -748,8 +752,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
error =chk_size(param,info);
if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE)))
error|=chk_del(param, info,param->testflag);
if ((!error || !(param->testflag & (T_FAST | T_FORCE_CREATE)) &&
!param->start_check_pos))
if ((!error || (!(param->testflag & (T_FAST | T_FORCE_CREATE)) &&
!param->start_check_pos)))
{
error|=chk_key(param, info);
if (!error && (param->testflag & (T_STATISTICS | T_AUTO_INC)))
......
......@@ -155,10 +155,10 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
printf(" - Merging %lu keys\n",records);
if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
goto err;
}
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
goto err;
}
if (!no_messages)
puts(" - Last merge and dumping keys");
if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,&tempfile))
......
......@@ -67,7 +67,7 @@ static char *name_from_csnum(CS_ID **cs, uint number)
for (c = cs; *c; ++c)
if ((*c)->number == number)
return (*c)->name;
return "?"; /* this mimics find_type() */
return (char*) "?"; /* this mimics find_type() */
}
static my_bool get_word(struct simpleconfig_buf_st *fb, char *buf)
......@@ -487,7 +487,7 @@ char * list_charsets(myf want_flags)
{
CS_ID **c;
char buf[FN_REFLEN];
MY_STAT stat;
MY_STAT status;
if((c=available_charsets))
for (; *c; ++c)
......@@ -495,7 +495,7 @@ char * list_charsets(myf want_flags)
if (charset_in_string((*c)->name, &s))
continue;
get_charset_conf_name((*c)->number, buf);
if (!my_stat(buf, &stat, MYF(0)))
if (!my_stat(buf, &status, MYF(0)))
continue; /* conf file doesn't exist */
dynstr_append(&s, (*c)->name);
dynstr_append(&s, " ");
......
......@@ -148,7 +148,7 @@ void load_defaults(const char *conf_file, const char **groups,
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
int error;
int error=0;
if (**dirs)
error=search_default_file(&args, &alloc, *dirs, conf_file,
default_ext, &group);
......@@ -359,7 +359,12 @@ void print_defaults(const char *conf_file, const char **groups)
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
if (**dirs)
strmov(name,*dirs);
else if (defaults_extra_file)
strmov(name,defaults_extra_file);
else
continue;
convert_dirname(name);
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
strcat(name,".");
......@@ -377,6 +382,7 @@ void print_defaults(const char *conf_file, const char **groups)
puts("\nThe following options may be given as the first argument:\n\
--print-defaults Print the program argument list and exit\n\
--no-defaults Don't read default options from any options file\n\
--defaults-file=# Only read default options from the given file #");
--defaults-file=# Only read default options from the given file #\n\
--defaults-extra-file=# Read this file after the global files are read");
}
......@@ -36,7 +36,8 @@ extern char **environ;
*/
File create_temp_file(char *to, const char *dir, const char *prefix,
int mode, myf MyFlags)
int mode __attribute__((unused)),
myf MyFlags __attribute__((unused)))
{
File file= -1;
DBUG_ENTER("open_temp_file");
......@@ -85,12 +86,12 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
}
#elif defined(HAVE_MKSTEMP)
{
char prefix[30];
char prefix_buff[30];
uint pfx_len;
pfx_len=(strmov(strnmov(prefix,
pfx_len=(strmov(strnmov(prefix_buff,
prefix ? prefix : "tmp.",
sizeof(prefix)-7),"XXXXXX") - prefix);
sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff);
if (!dir && ! (dir =getenv("TMPDIR")))
dir=P_tmpdir;
if (strlen(dir)+ pfx_len > FN_REFLEN-2)
......
......@@ -48,7 +48,7 @@ static my_bool win32_init_tcp_ip();
static my_bool my_init_done=0;
ulong atoi_octal(const char *str)
static ulong atoi_octal(const char *str)
{
long int tmp;
while (*str && isspace(*str))
......
......@@ -80,7 +80,6 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
myf MyFlags)
{
int error;
uint writenbytes,errors;
ulong written;
DBUG_ENTER("my_pwrite");
......@@ -91,6 +90,7 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
for (;;)
{
#ifndef HAVE_PREAD
int error;
writenbytes= (uint) -1;
pthread_mutex_lock(&my_file_info[Filedes].mutex);
error=(lseek(Filedes, offset, MY_SEEK_SET) != -1L &&
......
......@@ -161,6 +161,7 @@ sub new
$limits{'func_extra_in_num'} = 1; # Has function in
$limits{'limit'} = 1; # supports the limit attribute
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
$smds{'time'} = 1;
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
......@@ -378,6 +379,7 @@ sub new
$limits{'group_func_extra_std'} = 0;
$limits{'limit'} = 1; # supports the limit attribute
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 0;
$limits{'func_odbc_mod'} = 0;
$limits{'func_extra_%'} = 0;
......@@ -576,6 +578,7 @@ sub new
$limits{'max_text_size'} = 7000; # 8000 crashes pg 6.3
$limits{'query_size'} = 16777216;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
# the different cases per query ...
$smds{'q1'} = 'b'; # with time
......@@ -849,6 +852,7 @@ sub new
$limits{'NEG'} = 1;
$limits{'func_extra_in_num'} = 1;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
# for the smds small benchmark test ....
# the different cases per query ...
......@@ -1087,6 +1091,7 @@ sub new
$limits{'NEG'} = 1;
$limits{'func_extra_in_num'} = 0;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
# for the smds small benchmark test ....
# the different cases per query ... EMPRESS
......@@ -1364,6 +1369,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 1; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
$smds{'time'} = 1;
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
......@@ -1612,6 +1618,7 @@ sub new
$limits{'subqueries'} = 1; # Doesn't support sub-queries.
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
return $self;
}
......@@ -1809,6 +1816,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 1; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
return $self;
}
......@@ -1980,6 +1988,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 0; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
return $self;
}
......@@ -2163,6 +2172,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 0; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
return $self;
}
......@@ -2349,6 +2359,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 1; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
$smds{'time'} = 1;
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
......@@ -2558,6 +2569,7 @@ sub new
$limits{'NEG'} = 1; # Supports -id
$limits{'func_extra_in_num'} = 0; # Has function in
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
return $self;
}
......@@ -2726,6 +2738,7 @@ sub new
$limits{'func_extra_in_num'} = 1; # Has function in
$limits{'limit'} = 0; # Does not support the limit attribute
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
$smds{'time'} = 1;
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
......
......@@ -97,6 +97,8 @@ goto select_test if ($opt_skip_create);
print "Creating tables\n";
$dbh->do("drop table bench1");
$dbh->do("drop table bench2");
$dbh->do("drop table bench3");
do_many($dbh,$server->create("bench1",
["id int NOT NULL",
"id2 int NOT NULL",
......@@ -240,7 +242,7 @@ if ($limits->{'unique_index'})
}
$end_time=new Benchmark;
print "Time for insert_duplicates (" . ($total_rows) . "): " .
print "Time for insert_duplicates (" . ($opt_loop_count) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#if ($opt_fast && defined($server->{vacuum}))
......@@ -611,7 +613,7 @@ if ($limits->{'functions'})
}
$end_time=new Benchmark;
print "Time for update_of_key ($range_loop_count): " .
print "Time for update_of_key ($update_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
if ($opt_lock_tables)
......@@ -775,7 +777,7 @@ for ($i=0 ; $i < $opt_loop_count*3 ; $i++)
}
$end_time=new Benchmark;
print "Time for update_with_key ($opt_loop_count): " .
print "Time for update_with_key (" . ($opt_loop_count*3) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
print "\nTesting update of all rows\n";
......@@ -785,7 +787,7 @@ for ($i=0 ; $i < $small_loop_count ; $i++)
$sth = $dbh->do("update bench1 set dummy1='updated $i'") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for update_big ($range_loop_count): " .
print "Time for update_big ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
......@@ -859,6 +861,49 @@ if ($server->small_rollback_segment())
$dbh = $server->connect();
}
####
#### Test INSERT INTO ... SELECT
####
if ($limits->{'insert_select'})
{
print "\nTesting INSERT INTO ... SELECT\n";
do_many($dbh,$server->create("bench2",
["id int NOT NULL",
"id2 int NOT NULL",
"id3 int NOT NULL",
"dummy1 char(30)"],
["primary key (id,id2)"]));
do_many($dbh,$server->create("bench3",
["id int NOT NULL",
"id2 int NOT NULL",
"id3 int NOT NULL",
"dummy1 char(30)"],
["primary key (id,id2)",
"index index_id3 (id3)"]));
$loop_time=new Benchmark;
$sth = $dbh->do("INSERT INTO bench2 SELECT * from bench1") ||
die $DBI::errstr;
$end_time=new Benchmark;
print "Time for insert_select_1_key (1): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$sth = $dbh->do("INSERT INTO bench3 SELECT * from bench1") ||
die $DBI::errstr;
$end_time=new Benchmark;
print "Time for insert_select_2_keys (1): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$sth = $dbh->do("DROP TABLE bench2") ||
die $DBI::errstr;
$sth = $dbh->do("DROP TABLE bench3") ||
die $DBI::errstr;
$end_time=new Benchmark;
print "Time for drop table(2): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
}
####
#### Do some deletes on the table
####
......
......@@ -254,7 +254,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
STATE_CRASHED_ON_REPAIR)) &&
share->state.open_count == 0) ||
((param.testflag & T_FAST) && (share->state.open_count ==
(share->global_changed ? 1 : 0)))))
(uint) (share->global_changed ? 1 : 0)))))
return HA_ADMIN_ALREADY_DONE;
error = chk_size(&param, file);
......@@ -298,6 +298,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
mi_mark_crashed(file);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
check_opt->retry_without_quick=param.retry_without_quick;
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
......@@ -317,7 +318,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
myisamchk_init(&param);
param.thd = thd;
param.op_name = (char*)" analyze";
param.op_name = (char*) "analyze";
param.table_name = table->table_name;
param.testflag=(T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
......@@ -338,6 +339,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
{
HA_CHECK_OPT tmp_check_opt;
......@@ -404,6 +406,7 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
if (!file) return HA_ADMIN_INTERNAL_ERROR;
MI_CHECK param;
......@@ -415,7 +418,21 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
if (check_opt->quick)
param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
return repair(thd,param,0);
while ((error=repair(thd,param,0)))
{
if (param.retry_without_quick && param.opt_rep_quick)
{
param.opt_rep_quick=0;
continue;
}
if ((param.testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
continue;
}
break;
}
return error;
}
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
......@@ -576,19 +593,19 @@ bool ha_myisam::activate_all_index(THD *thd)
}
bool ha_myisam::check_and_repair(THD *thd, const char *name)
bool ha_myisam::check_and_repair(THD *thd)
{
int error=0;
HA_CHECK_OPT check_opt;
DBUG_ENTER("ha_myisam::auto_check_and_repair");
if (open(name, O_RDWR, HA_OPEN_WAIT_IF_LOCKED))
DBUG_RETURN(1);
check_opt.init();
check_opt.flags=T_MEDIUM;
check_opt.flags= T_MEDIUM;
check_opt.quick= !file->state->del; // Don't use quick if deleted rows
if (mi_is_crashed(file) || check(thd, &check_opt))
{
if (check_opt.retry_without_quick)
check_opt.quick=0;
check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ?
T_BACKUP_DATA : 0) |
(!(myisam_recover_options & HA_RECOVER_FORCE) ?
......@@ -596,11 +613,14 @@ bool ha_myisam::check_and_repair(THD *thd, const char *name)
if (repair(thd, &check_opt))
error=1;
}
if (close())
error=1;
DBUG_RETURN(error);
}
bool ha_myisam::is_crashed() const
{
return (file->s->state.changed & STATE_CRASHED ||
(my_disable_locking && file->s->state.open_count));
}
int ha_myisam::update_row(const byte * old_data, byte * new_data)
{
......
......@@ -45,8 +45,7 @@ class ha_myisam: public handler
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
HA_LONGLONG_KEYS | HA_NULL_KEY |
HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY |
HA_CHECK_AND_REPAIR)
HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY)
{}
~ha_myisam() {}
const char *table_type() const { return "MyISAM"; }
......@@ -103,7 +102,9 @@ class ha_myisam: public handler
int check(THD* thd, HA_CHECK_OPT* check_opt);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
bool check_and_repair(THD *thd, const char *name);
bool check_and_repair(THD *thd);
bool is_crashed() const;
bool auto_repair() const { return myisam_recover_options != 0; }
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt);
......
......@@ -66,7 +66,6 @@
#define HA_NO_WRITE_DELAYED (HA_NOT_EXACT_COUNT*2)
#define HA_PRIMARY_KEY_IN_READ_INDEX (HA_NO_WRITE_DELAYED*2)
#define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2)
#define HA_CHECK_AND_REPAIR (HA_DROP_BEFORE_CREATE*2)
/* Parameters for open() (in register form->filestat) */
/* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */
......@@ -146,9 +145,10 @@ typedef struct st_ha_check_opt
bool quick;
bool changed_files;
bool optimize;
bool retry_without_quick;
inline void init()
{
flags= 0; quick= optimize=0;
flags= 0; quick= optimize= retry_without_quick=0;
sort_buffer_size = myisam_sort_buffer_size;
}
} HA_CHECK_OPT;
......@@ -249,7 +249,7 @@ class handler :public Sql_alloc
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
virtual int check(THD* thd, HA_CHECK_OPT* check_opt );
virtual int repair(THD* thd, HA_CHECK_OPT* check_opt);
virtual bool check_and_repair(THD *thd, const char *name) {return 1;}
virtual bool check_and_repair(THD *thd) {return 1;}
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
......@@ -274,6 +274,8 @@ class handler :public Sql_alloc
virtual uint max_key_length()const =0;
virtual uint min_record_length(uint options) const { return 1; }
virtual bool low_byte_first() const { return 1; }
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
......
......@@ -434,7 +434,10 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
table_list->table=table;
if (hash_insert(&open_cache, (byte*) table))
{
my_free((gptr) table,MYF(0));
DBUG_RETURN(-1);
}
if (remove_table_from_cache(thd, table_list->db, table_list->name))
DBUG_RETURN(1); // Table is in use
DBUG_RETURN(0);
......
......@@ -261,7 +261,7 @@ void Log_event::print_header(FILE* file)
{
fputc('#', file);
print_timestamp(file);
fprintf(file, " server id %d ", server_id);
fprintf(file, " server id %ld ", server_id);
}
void Log_event::print_timestamp(FILE* file, time_t* ts = 0)
......@@ -709,7 +709,7 @@ void Load_log_event::print(FILE* file, bool short_form)
}
if((int)skip_lines > 0)
fprintf(file, " IGNORE %d LINES ", skip_lines);
fprintf(file, " IGNORE %ld LINES ", skip_lines);
if(num_fields)
{
......
......@@ -34,7 +34,7 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
const char *alias);
const char *alias, bool locked);
static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
List_iterator<Item> *it);
static void free_cache_entry(TABLE *entry);
......@@ -572,7 +572,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
pthread_mutex_lock(&LOCK_open);
if (open_unireg_entry(table, db, table_name, table_name) ||
if (open_unireg_entry(table, db, table_name, table_name,0) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length)))
{
......@@ -706,7 +706,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
/* make a new table */
if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
DBUG_RETURN(NULL);
if (open_unireg_entry(table,db,table_name,alias) ||
if (open_unireg_entry(table,db,table_name,alias,0) ||
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
key_length)))
{
......@@ -816,7 +816,7 @@ bool reopen_table(TABLE *table,bool locked)
if (!locked)
VOID(pthread_mutex_lock(&LOCK_open));
if (open_unireg_entry(&tmp,db,table_name,table->table_name))
if (open_unireg_entry(&tmp,db,table_name,table->table_name,locked))
goto end;
free_io_cache(table);
......@@ -1113,9 +1113,10 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
*/
static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
const char *alias)
const char *alias, bool locked)
{
char path[FN_REFLEN];
int error;
DBUG_ENTER("open_unireg_entry");
(void) sprintf(path,"%s/%s/%s",mysql_data_home,db,name);
......@@ -1126,10 +1127,58 @@ static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
ha_open_options,
entry))
{
DBUG_RETURN(1);
THD *thd=current_thd;
if (!entry->crashed)
goto err; // Can't repair the table
TABLE_LIST table_list;
table_list.db=(char*) db;
table_list.name=(char*) name;
table_list.next=0;
if (!locked)
pthread_mutex_lock(&LOCK_open);
if ((error=lock_table_name(thd,&table_list)))
{
if (error < 0)
{
if (!locked)
pthread_mutex_lock(&LOCK_open);
goto err;
}
if (wait_for_locked_table_names(thd,&table_list))
{
unlock_table_name(thd,&table_list);
if (!locked)
pthread_mutex_lock(&LOCK_open);
goto err;
}
}
pthread_mutex_unlock(&LOCK_open);
thd->net.last_error[0]=0; // Clear error message
thd->net.last_errno=0;
error=0;
sql_print_error("Warning: Repairing table: %s.%s",db,name);
if (openfrm(path,alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
ha_open_options | HA_OPEN_FOR_REPAIR,
entry) ||
(entry->file->is_crashed() && entry->file->check_and_repair(thd)))
{
sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
error=1;
}
unlock_table_name(thd,&table_list);
if (locked)
pthread_mutex_lock(&LOCK_open); // Get back old lock
if (error)
goto err;
}
(void) entry->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
}
......
......@@ -127,7 +127,7 @@ class TMP_TABLE_PARAM {
uint group_parts,group_length;
uint quick_group;
TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {}
TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {}
~TMP_TABLE_PARAM()
{
cleanup();
......
......@@ -745,7 +745,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
{
String *packet = &thd->packet;
if(table->table) // do not overwrite existing tables on restore
if (table->table) // do not overwrite existing tables on restore
{
return send_check_errmsg(thd, table, "restore",
"table exists, will not overwrite on restore"
......@@ -758,27 +758,27 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
char* table_name = table->name;
char* db = thd->db ? thd->db : table->db;
if(!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
return -1; // protect buffer overflow
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
int lock_retcode;
pthread_mutex_lock(&LOCK_open);
if((lock_retcode = lock_table_name(thd, table)) < 0)
if ((lock_retcode = lock_table_name(thd, table)) < 0)
{
pthread_mutex_unlock(&LOCK_open);
return -1;
}
if(lock_retcode && wait_for_locked_table_names(thd, table))
if (lock_retcode && wait_for_locked_table_names(thd, table))
{
pthread_mutex_unlock(&LOCK_open);
return -1;
}
pthread_mutex_unlock(&LOCK_open);
if(my_copy(src_path,
if (my_copy(src_path,
fn_format(dst_path, dst_path,"",
reg_ext, 4),
MYF(MY_WME)))
......@@ -791,7 +791,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
// generate table will try to send OK which messes up the output
// for the client
if(generate_table(thd, table, 0))
if (generate_table(thd, table, 0))
{
thd->net.no_send_ok = save_no_send_ok;
return send_check_errmsg(thd, table, "restore",
......
......@@ -1134,8 +1134,13 @@ repair:
opt_mi_check_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
| TYPE_SYM EQ mi_check_types {}
| mi_check_types {}
mi_check_types:
mi_check_type {}
| mi_check_type mi_check_types {}
mi_check_type:
QUICK { Lex->check_opt.quick = 1; }
| FAST_SYM { Lex->check_opt.flags|= T_FAST; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
......
......@@ -212,18 +212,25 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
error=2;
if (db_stat)
{
if ((outparam->file->
int err;
if ((err=(outparam->file->
ha_open(index_file,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
(db_stat & HA_WAIT_IF_LOCKED ||
specialflag & SPECIAL_WAIT_IF_LOCKED) ?
((db_stat & HA_WAIT_IF_LOCKED) ||
(specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
HA_OPEN_WAIT_IF_LOCKED :
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
HA_OPEN_ABORT_IF_LOCKED :
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
{
/* Set a flag if the table is crashed and it can be auto. repaired */
outparam->crashed=(err == HA_ERR_CRASHED &&
outparam->file->auto_repair() &&
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
goto err_not_open; /* purecov: inspected */
}
}
outparam->db_low_byte_first=outparam->file->low_byte_first();
error=4;
......@@ -549,6 +556,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
delete crypted;
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG);
delete outparam->file;
outparam->file=0; // For easyer errorchecking
free_root(&outparam->mem_root,MYF(0));
my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR));
......
......@@ -92,6 +92,7 @@ struct st_table {
my_bool db_low_byte_first; /* Portable row format */
my_bool locked_by_flush;
my_bool locked_by_name;
my_bool crashed;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment