Commit ec45c88d authored by unknown's avatar unknown

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0

into  perch.ndb.mysql.com:/home/jonas/src/mysql-5.0-push

parents 9ca07a42 da0f9ece
......@@ -98,6 +98,10 @@
#define DEFAULT_DELIMITER ";"
#define MAX_DELIMITER 16
#define RESULT_OK 0
#define RESULT_CONTENT_MISMATCH 1
#define RESULT_LENGTH_MISMATCH 2
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
......@@ -679,7 +683,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_PRINT("info",("Size differs: result size: %u file size: %u",
ds->length, stat_info.st_size));
DBUG_PRINT("info",("result: '%s'", ds->str));
DBUG_RETURN(2);
DBUG_RETURN(RESULT_LENGTH_MISMATCH);
}
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
die(NullS);
......@@ -696,7 +700,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
res_ptr = res_ds.str;
if ((res_len = res_ds.length) != ds->length)
{
res = 2;
res= RESULT_LENGTH_MISMATCH;
goto err;
}
}
......@@ -706,7 +710,8 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
res_len = stat_info.st_size;
}
res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0;
res= (memcmp(res_ptr, ds->str, res_len)) ?
RESULT_CONTENT_MISMATCH : RESULT_OK;
err:
if (res && eval_result)
......@@ -723,22 +728,23 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
static int check_result(DYNAMIC_STRING* ds, const char *fname,
my_bool require_option)
{
int error = 0;
int res=dyn_string_cmp(ds, fname);
int error= RESULT_OK;
int res= dyn_string_cmp(ds, fname);
DBUG_ENTER("check_result");
if (res && require_option)
abort_not_supported_test();
switch (res) {
case 0:
case RESULT_OK:
break; /* ok */
case 2:
case RESULT_LENGTH_MISMATCH:
verbose_msg("Result length mismatch");
error = 1;
error= RESULT_LENGTH_MISMATCH;
break;
case 1:
case RESULT_CONTENT_MISMATCH:
verbose_msg("Result content mismatch");
error = 1;
error= RESULT_CONTENT_MISMATCH;
break;
default: /* impossible */
die("Unknown error code from dyn_string_cmp()");
......@@ -3944,8 +3950,10 @@ int main(int argc, char **argv)
{
int error = 0;
struct st_query *q;
my_bool require_file=0, q_send_flag=0, abort_flag= 0;
my_bool require_file=0, q_send_flag=0, abort_flag= 0,
query_executed= 0;
char save_file[FN_REFLEN];
MY_STAT res_info;
MY_INIT(argv[0]);
/* Use all time until exit if no explicit 'start_timer' */
......@@ -4141,6 +4149,7 @@ int main(int argc, char **argv)
save_file[0]=0;
}
error |= run_query(&cur_con->mysql, q, flags);
query_executed= 1;
q->last_argument= q->end;
break;
}
......@@ -4161,6 +4170,7 @@ int main(int argc, char **argv)
is given on this connection.
*/
error |= run_query(&cur_con->mysql, q, QUERY_SEND);
query_executed= 1;
q->last_argument= q->end;
break;
case Q_RESULT:
......@@ -4201,6 +4211,7 @@ int main(int argc, char **argv)
break;
case Q_EXEC:
do_exec(q);
query_executed= 1;
break;
case Q_START_TIMER:
/* Overwrite possible earlier start of timer */
......@@ -4280,6 +4291,18 @@ int main(int argc, char **argv)
parser.current_line += current_line_inc;
}
if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
{
/*
my_stat() successful on result file. Check if we have not run a
single query, but we do have a result file that contains data.
Note that we don't care, if my_stat() fails. For example for
non-existing or non-readable file we assume it's fine to have
no query output from the test file, e.g. regarded as no error.
*/
if (res_info.st_size)
error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH);
}
if (result_file && ds_res.length && !error)
{
if (!record)
......
......@@ -409,6 +409,7 @@ my_bool check_scramble(const char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
void octet2hex(char *to, const unsigned char *str, unsigned int len);
/* end of password.c */
......
.TH WHICH 1 "20 December 2000"
.SH NAME
which - Jani please supply one.
.SH USAGE
which [options] [--] programname [...]
.SH SYNOPSIS
.B which
.RB [ \-\-version | \-[vV] ]
.RB [ \-\-skip\-dot ]
.RB [ \-\-skip\-tilde ]
.RB [ \-\-show\-dot ]
.RB [ \-\-show\-tilde ]
.RB [ \-\-tty\-only ]
.RB [ \-\-all | \-a ]
.RB [ \-\-read\-alias | \-i ]
.RB [ \-\-skip\-alias ]
.SH DESCRIPTION
.TP
.BR which
supports by executing
.TP
.BR \-\-version | \-[vV]
Print version and exit successfully.
.TP
.BR \-\-skip\-dot
Skip directories in PATH that start with a dot.
.TP
.BR \-\-skip\-tilde
Skip directories in PATH that start with a tilde.
.TP
.BR \-\-show\-dot
Don\'t expand a dot to current directory in output.
.TP
.BR \-\-show\-tilde
Output a tilde for HOME directory for non-root.
.TP
.BR \-\-tty\-only
Stop processing options on the right if not on tty.
.TP
.BR \-\-all | \-a
Print all matches in PATH, not just the first
.TP
.BR \-\-read\-alias | \-i
Read list of aliases from stdin.
.TP
.BR \-\-skip\-alias
Ignore option
.BR --read-alias;
don\'t read stdin.
.SH "SEE ALSO"
isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), mysqld_safe (1), which1 (1), zap (1),
.SH AUTHOR
Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
.\" end of man page
\ No newline at end of file
......@@ -241,8 +241,10 @@ our $opt_ps_protocol;
our $opt_sleep_time_after_restart= 1;
our $opt_sleep_time_for_delete= 10;
our $opt_testcase_timeout= 5; # 5 min max
our $opt_suite_timeout= 120; # 2 hours max
our $opt_testcase_timeout;
our $opt_suite_timeout;
my $default_testcase_timeout= 10; # 10 min max
my $default_suite_timeout= 120; # 2 hours max
our $opt_socket;
......@@ -260,6 +262,7 @@ our $opt_user;
our $opt_user_test;
our $opt_valgrind;
our $opt_valgrind_mysqltest;
our $opt_valgrind_all;
our $opt_valgrind_options;
......@@ -521,8 +524,9 @@ sub command_line_setup () {
# Coverage, profiling etc
'gcov' => \$opt_gcov,
'gprof' => \$opt_gprof,
'valgrind' => \$opt_valgrind,
'valgrind-all' => \$opt_valgrind_all,
'valgrind:s' => \$opt_valgrind,
'valgrind-mysqltest:s' => \$opt_valgrind_mysqltest,
'valgrind-all:s' => \$opt_valgrind_all,
'valgrind-options=s' => \$opt_valgrind_options,
# Misc
......@@ -700,29 +704,42 @@ sub command_line_setup () {
$opt_with_ndbcluster= 0;
}
# FIXME
# The ":s" in the argument spec, means we have three different cases
#
# undefined option not set
# "" option set with no argument
# "somestring" option is name/path of valgrind executable
# Take executable path from any of them, if any
$opt_valgrind= $opt_valgrind_mysqltest if $opt_valgrind_mysqltest;
$opt_valgrind= $opt_valgrind_all if $opt_valgrind_all;
# If valgrind flag not defined, define if other valgrind flags are
unless ( defined $opt_valgrind )
{
$opt_valgrind= ""
if defined $opt_valgrind_mysqltest or defined $opt_valgrind_all;
}
#if ( $opt_valgrind or $opt_valgrind_all )
#{
# VALGRIND=`which valgrind` # this will print an error if not found FIXME
# Give good warning to the user and stop
# if ( ! $VALGRIND )
# {
# print "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org.\n"
# exit 1
# }
if ( ! $opt_testcase_timeout )
{
$opt_testcase_timeout= $default_testcase_timeout;
$opt_testcase_timeout*= 10 if defined $opt_valgrind;
}
if ( ! $opt_suite_timeout )
{
$opt_suite_timeout= $default_suite_timeout;
$opt_suite_timeout*= 4 if defined $opt_valgrind;
}
if ( defined $opt_valgrind )
{
$opt_sleep_time_after_restart= 10;
$opt_sleep_time_for_delete= 60;
# >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
# valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
# VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
# $opt_extra_mysqld_opt.= " --skip-safemalloc --skip-bdb";
# SLEEP_TIME_AFTER_RESTART=10
# $opt_sleep_time_for_delete= 60
# $glob_use_running_server= ""
# if ( "$1"= "--valgrind-all" )
# {
# VALGRIND="$VALGRIND -v --show-reachable=yes"
# }
#}
# valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
}
if ( ! $opt_user )
{
......@@ -1883,7 +1900,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
if ( $opt_valgrind )
if ( defined $opt_valgrind )
{
mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
mtr_add_arg($args, "%s--skip-bdb", $prefix);
......@@ -2109,29 +2126,9 @@ sub mysqld_start ($$$$) {
mtr_init_args(\$args);
if ( $opt_valgrind )
if ( defined $opt_valgrind )
{
mtr_add_arg($args, "--tool=memcheck");
mtr_add_arg($args, "--alignment=8");
mtr_add_arg($args, "--leak-check=yes");
mtr_add_arg($args, "--num-callers=16");
if ( $opt_valgrind_all )
{
mtr_add_arg($args, "-v");
mtr_add_arg($args, "--show-reachable=yes");
}
if ( $opt_valgrind_options )
{
# FIXME split earlier and put into @glob_valgrind_*
mtr_add_arg($args, split(' ', $opt_valgrind_options));
}
mtr_add_arg($args, $exe);
$exe= $opt_valgrind;
valgrind_arguments($args, \$exe);
}
mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info);
......@@ -2403,6 +2400,11 @@ sub run_mysqltest ($) {
mtr_init_args(\$args);
if ( defined $opt_valgrind_mysqltest )
{
valgrind_arguments($args, \$exe);
}
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "--silent");
mtr_add_arg($args, "-v");
......@@ -2498,6 +2500,36 @@ sub run_mysqltest ($) {
return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,"");
}
sub valgrind_arguments {
my $args= shift;
my $exe= shift;
mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
mtr_add_arg($args, "--alignment=8");
mtr_add_arg($args, "--leak-check=yes");
mtr_add_arg($args, "--num-callers=16");
mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
if -f "$glob_mysql_test_dir/valgrind.supp";
if ( defined $opt_valgrind_all )
{
mtr_add_arg($args, "-v");
mtr_add_arg($args, "--show-reachable=yes");
}
if ( $opt_valgrind_options )
{
# FIXME split earlier and put into @glob_valgrind_*
mtr_add_arg($args, split(' ', $opt_valgrind_options));
}
mtr_add_arg($args, $$exe);
$$exe= $opt_valgrind || "valgrind";
}
##############################################################################
#
# Usage
......@@ -2562,8 +2594,11 @@ Options for coverage, profiling etc
gcov FIXME
gprof FIXME
valgrind FIXME
valgrind-all FIXME
valgrind[=EXE] Run the "mysqltest" executable as well as the "mysqld"
server using valgrind, optionally specifying the
executable path/name
valgrind-mysqltest[=EXE] In addition, run the "mysqltest" executable with valgrind
valgrind-all[=EXE] Adds verbose flag, and --show-reachable to valgrind
valgrind-options=ARGS Extra options to give valgrind
Misc options
......
......@@ -1028,6 +1028,45 @@ xxx
yyy
DROP TABLE t1;
set names utf8;
select hex(char(1));
hex(char(1))
01
select char(0xd1,0x8f);
char(0xd1,0x8f)
я
select char(0xd18f);
char(0xd18f)
я
select char(53647);
char(53647)
я
select char(0xff,0x8f);
char(0xff,0x8f)
Warnings:
Warning 1300 Invalid utf8 character string: 'FF8F'
set sql_mode=traditional;
select char(0xff,0x8f);
char(0xff,0x8f)
NULL
Warnings:
Error 1300 Invalid utf8 character string: 'FF8F'
select char(195);
char(195)
NULL
Warnings:
Error 1300 Invalid utf8 character string: 'C3'
select char(196);
char(196)
NULL
Warnings:
Error 1300 Invalid utf8 character string: 'C4'
select char(2557);
char(2557)
NULL
Warnings:
Error 1300 Invalid utf8 character string: 'FD'
set names utf8;
create table t1 (a char(1)) default character set utf8;
create table t2 (a char(1)) default character set utf8;
insert into t1 values('a'),('a'),(0xE38182),(0xE38182);
......
......@@ -845,6 +845,15 @@ select * from v1;
cast(1 as char(3))
1
drop view v1;
create table t1 (a int);
create view v1 as select a from t1;
create database seconddb;
rename table v1 to seconddb.v1;
ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed.
rename table v1 to v2;
drop table t1;
drop view v2;
drop database seconddb;
create view v1 as select 'a',1;
create view v2 as select * from v1 union all select * from v1;
create view v3 as select * from v2 where 1 = (select `1` from v2);
......
......@@ -864,6 +864,24 @@ SELECT DISTINCT id FROM t1 ORDER BY id;
DROP TABLE t1;
#
# Bugs#10504: Character set does not support traditional mode
#
set names utf8;
# correct value
select hex(char(1));
select char(0xd1,0x8f);
select char(0xd18f);
select char(53647);
# incorrect value: return with warning
select char(0xff,0x8f);
# incorrect value in strict mode: return NULL with "Error" level warning
set sql_mode=traditional;
select char(0xff,0x8f);
select char(195);
select char(196);
select char(2557);
#
# Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters
#
......
......@@ -785,6 +785,19 @@ show create view v1;
select * from v1;
drop view v1;
#
# renaming views
#
create table t1 (a int);
create view v1 as select a from t1;
create database seconddb;
-- error 1450
rename table v1 to seconddb.v1;
rename table v1 to v2;
drop table t1;
drop view v2;
drop database seconddb;
#
# bug handling from VIEWs
#
......
......@@ -229,7 +229,8 @@ NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
: m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
m_dictionary(ndb),
theCurrentConnectIndex(0),
theNdbObjectIdMap(1024,1024),
theNdbObjectIdMap(ndb_cluster_connection->m_impl.m_transporter_facade->theMutexPtr,
1024,1024),
theNoOfDBnodes(0)
{
int i;
......
......@@ -30,7 +30,7 @@ class NdbObjectIdMap //: NdbLockable
{
public:
STATIC_CONST( InvalidId = ~(Uint32)0 );
NdbObjectIdMap(Uint32 initalSize = 128, Uint32 expandSize = 10);
NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
~NdbObjectIdMap();
Uint32 map(void * object);
......@@ -46,14 +46,16 @@ private:
void * m_obj;
} * m_map;
NdbMutex * m_mutex;
void expand(Uint32 newSize);
};
inline
NdbObjectIdMap::NdbObjectIdMap(Uint32 sz, Uint32 eSz) {
NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
......@@ -131,21 +133,26 @@ NdbObjectIdMap::getObject(Uint32 id){
inline void
NdbObjectIdMap::expand(Uint32 incSize){
NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry));
MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
if (m_map) {
memcpy(tmp, m_map, m_size * sizeof(MapEntry));
free((void*)m_map);
if (likely(tmp != 0))
{
m_map = tmp;
for(Uint32 i = m_size; i<newSize; i++){
m_map[i].m_next = i + 1;
}
m_firstFree = m_size;
m_map[newSize-1].m_next = InvalidId;
m_size = newSize;
}
m_map = tmp;
for(Uint32 i = m_size; i<newSize; i++){
m_map[i].m_next = i + 1;
else
{
ndbout_c("NdbObjectIdMap::expand unable to expand!!");
}
m_firstFree = m_size;
m_map[newSize-1].m_next = InvalidId;
m_size = newSize;
NdbMutex_Unlock(m_mutex);
}
#endif
......@@ -1980,6 +1980,33 @@ b1: str->append((char)(num>>8));
}
str->set_charset(collation.collation);
str->realloc(str->length()); // Add end 0 (for Purify)
/* Check whether we got a well-formed string */
CHARSET_INFO *cs= collation.collation;
int well_formed_error;
uint wlen= cs->cset->well_formed_len(cs,
str->ptr(), str->ptr() + str->length(),
str->length(), &well_formed_error);
if (wlen < str->length())
{
THD *thd= current_thd;
char hexbuf[7];
enum MYSQL_ERROR::enum_warning_level level;
uint diff= str->length() - wlen;
set_if_smaller(diff, 3);
octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff);
if (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
{
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
null_value= 1;
str= 0;
}
else
level= MYSQL_ERROR::WARN_LEVEL_WARN;
push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
}
return str;
}
......
......@@ -333,6 +333,59 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
DBUG_RETURN(TRUE);
}
/*
Renames a frm file (including backups) in same schema
SYNOPSIS
rename_in_schema_file
schema name of given schema
old_name original file name
new_name new file name
revision revision number
num_view_backups number of backups
RETURN
0 - OK
1 - Error (only if renaming of frm failed)
*/
my_bool rename_in_schema_file(const char *schema, const char *old_name,
const char *new_name, ulonglong revision,
uint num_view_backups)
{
char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN];
strxnmov(old_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
old_name, reg_ext, NullS);
(void) unpack_filename(old_path, old_path);
strxnmov(new_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
new_name, reg_ext, NullS);
(void) unpack_filename(new_path, new_path);
if (my_rename(old_path, new_path, MYF(MY_WME)))
return 1;
/* check if arc_dir exists */
strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS);
(void) unpack_filename(arc_path, arc_path);
if (revision > 0 && !access(arc_path, F_OK))
{
ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0;
while (revision > limit) {
my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
arc_path, old_name, reg_ext, (ulong)revision);
(void) unpack_filename(old_path, old_path);
my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu",
arc_path, new_name, reg_ext, (ulong)revision);
(void) unpack_filename(new_path, new_path);
my_rename(old_path, new_path, MYF(0));
revision--;
}
}
return 0;
}
/*
Prepare frm to parse (read to memory)
......
......@@ -48,6 +48,9 @@ my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type,
gptr base, File_option *parameters, uint versions);
my_bool rename_in_schema_file(const char *schema, const char *old_name,
const char *new_name, ulonglong revision,
uint num_view_backups);
class File_parser: public Sql_alloc
{
......
......@@ -318,8 +318,8 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st)
str, len IN the beginning and the length of the input string
*/
static void
octet2hex(char *to, const uint8 *str, uint len)
void
octet2hex(char *to, const unsigned char *str, uint len)
{
const uint8 *str_end= str + len;
for (; str != str_end; ++str)
......
......@@ -5413,3 +5413,5 @@ ER_VIEW_OTHER_USER
eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
ER_NO_SUCH_USER
eng "There is not %-.64s@%-.64s registered"
ER_FORBID_SCHEMA_CHANGE
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
......@@ -133,11 +133,12 @@ static TABLE_LIST *
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
TABLE_LIST *ren_table,*new_table;
frm_type_enum frm_type;
DBUG_ENTER("rename_tables");
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
{
db_type table_type;
int rc= 1;
char name[FN_REFLEN];
const char *new_alias, *old_alias;
......@@ -164,19 +165,36 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
ren_table->db, old_alias,
reg_ext);
unpack_filename(name, name);
if ((table_type=get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
{
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
if (!skip_error)
DBUG_RETURN(ren_table);
}
else if (mysql_rename_table(table_type,
ren_table->db, old_alias,
new_table->db, new_alias))
frm_type= mysql_frm_type(name);
switch (frm_type)
{
if (!skip_error)
DBUG_RETURN(ren_table);
case FRMTYPE_TABLE:
{
db_type table_type;
if ((table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
else
rc= mysql_rename_table(table_type, ren_table->db, old_alias,
new_table->db, new_alias);
break;
}
case FRMTYPE_VIEW:
/* change of schema is not allowed */
if (strcmp(ren_table->db, new_table->db))
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
new_table->db);
else
rc= mysql_rename_view(thd, new_alias, ren_table);
break;
default:
DBUG_ASSERT(0); // should never happen
case FRMTYPE_ERROR:
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
break;
}
if (rc && !skip_error)
DBUG_RETURN(ren_table);
}
DBUG_RETURN(0);
}
......@@ -479,8 +479,12 @@ bool mysql_create_view(THD *thd,
/* index of revision number in following table */
static const int revision_number_position= 8;
/* index of source */
static const int source_number_position= 11;
/* index of last required parameter for making view */
static const int required_view_parameters= 10;
/* number of backups */
static const int num_view_backups= 3;
/*
table of VIEW .frm field descriptors
......@@ -708,7 +712,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
}
if (sql_create_definition_file(&dir, &file, view_file_type,
(gptr)view, view_parameters, 3))
(gptr)view, view_parameters, num_view_backups))
{
DBUG_RETURN(thd->net.report_error? -1 : 1);
}
......@@ -1165,7 +1169,7 @@ frm_type_enum mysql_frm_type(char *path)
int length;
DBUG_ENTER("mysql_frm_type");
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
{
DBUG_RETURN(FRMTYPE_ERROR);
}
......@@ -1369,3 +1373,77 @@ int view_checksum(THD *thd, TABLE_LIST *view)
HA_ADMIN_WRONG_CHECKSUM :
HA_ADMIN_OK);
}
/*
rename view
Synopsis:
renames a view
Parameters:
thd thread handler
new_name new name of view
view view
Return values:
FALSE Ok
TRUE Error
*/
bool
mysql_rename_view(THD *thd,
const char *new_name,
TABLE_LIST *view)
{
LEX_STRING pathstr, file;
File_parser *parser;
char view_path[FN_REFLEN];
DBUG_ENTER("mysql_rename_view");
strxnmov(view_path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
view->table_name, reg_ext, NullS);
(void) unpack_filename(view_path, view_path);
pathstr.str= (char *)view_path;
pathstr.length= strlen(view_path);
if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) &&
is_equal(&view_type, parser->type())) {
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
/* get view definition and source */
if (mysql_make_view(parser, view) ||
parser->parse((gptr)view, thd->mem_root,
view_parameters + source_number_position, 1))
DBUG_RETURN(1);
/* rename view and it's backups */
if (rename_in_schema_file(view->db, view->table_name, new_name,
view->revision - 1, num_view_backups))
DBUG_RETURN(1);
strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS);
(void) unpack_filename(dir_buff, dir_buff);
pathstr.str= (char*)dir_buff;
pathstr.length= strlen(dir_buff);
file.str= file_buff;
file.length= (strxnmov(file_buff, FN_REFLEN, new_name, reg_ext, NullS)
- file_buff);
if (sql_create_definition_file(&pathstr, &file, view_file_type,
(gptr)view, view_parameters, num_view_backups)) {
/* restore renamed view in case of error */
rename_in_schema_file(view->db, new_name, view->table_name,
view->revision - 1, num_view_backups);
DBUG_RETURN(1);
}
} else
DBUG_RETURN(1);
/* remove cache entries */
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
DBUG_RETURN(0);
}
......@@ -34,6 +34,7 @@ int view_checksum(THD *thd, TABLE_LIST *view);
extern TYPELIB updatable_views_with_limit_typelib;
bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names);
bool mysql_rename_view(THD *thd, const char *new_name, TABLE_LIST *view);
#define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL)
......@@ -287,8 +287,6 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
keynames=(char*) key_part;
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
share->reclength = uint2korr((head+16));
if (*(head+26) == 1)
share->system= 1; /* one-record-database */
......@@ -459,6 +457,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
{
outparam->null_flags=null_pos=(uchar*) record+1;
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
/* null_bytes below is only correct under the condition that
there are no bit fields. Correct values is set below after the
table struct is initialized */
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
}
else
......@@ -871,6 +872,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
}
/* the correct null_bytes can now be set, since bitfields have been taken into account */
share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
/* The table struct is now initialized; Open the table */
error=2;
if (db_stat)
......
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