Allow one to use MERGE tables with tables from different databases
Added command 'replace_column' to mysqltest
This commit is contained in:
parent
fff60e3a86
commit
dfac0fc90a
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#define MTEST_VERSION "1.28"
|
#define MTEST_VERSION "1.29"
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include <mysql_embed.h>
|
#include <mysql_embed.h>
|
||||||
@ -63,9 +63,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <violite.h>
|
#include <violite.h>
|
||||||
|
|
||||||
#define MAX_QUERY 65536
|
#define MAX_QUERY 65536
|
||||||
|
#define MAX_COLUMNS 256
|
||||||
#define PAD_SIZE 128
|
#define PAD_SIZE 128
|
||||||
#define MAX_CONS 1024
|
#define MAX_CONS 128
|
||||||
#define MAX_INCLUDE_DEPTH 16
|
#define MAX_INCLUDE_DEPTH 16
|
||||||
#define LAZY_GUESS_BUF_SIZE 8192
|
#define LAZY_GUESS_BUF_SIZE 8192
|
||||||
#define INIT_Q_LINES 1024
|
#define INIT_Q_LINES 1024
|
||||||
@ -192,7 +193,7 @@ Q_SYNC_WITH_MASTER,
|
|||||||
Q_SYNC_SLAVE_WITH_MASTER,
|
Q_SYNC_SLAVE_WITH_MASTER,
|
||||||
Q_ERROR,
|
Q_ERROR,
|
||||||
Q_SEND, Q_REAP,
|
Q_SEND, Q_REAP,
|
||||||
Q_DIRTY_CLOSE, Q_REPLACE,
|
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
|
||||||
Q_PING, Q_EVAL,
|
Q_PING, Q_EVAL,
|
||||||
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
||||||
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
||||||
@ -246,6 +247,7 @@ const char *command_names[]=
|
|||||||
"reap",
|
"reap",
|
||||||
"dirty_close",
|
"dirty_close",
|
||||||
"replace_result",
|
"replace_result",
|
||||||
|
"replace_column",
|
||||||
"ping",
|
"ping",
|
||||||
"eval",
|
"eval",
|
||||||
"rpl_probe",
|
"rpl_probe",
|
||||||
@ -290,7 +292,7 @@ VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
|
|||||||
int eval_expr(VAR* v, const char *p, const char** p_end);
|
int eval_expr(VAR* v, const char *p, const char** p_end);
|
||||||
static int read_server_arguments(const char *name);
|
static int read_server_arguments(const char *name);
|
||||||
|
|
||||||
/* Definitions for replace */
|
/* Definitions for replace result */
|
||||||
|
|
||||||
typedef struct st_pointer_array { /* when using array-strings */
|
typedef struct st_pointer_array { /* when using array-strings */
|
||||||
TYPELIB typelib; /* Pointer to strings */
|
TYPELIB typelib; /* Pointer to strings */
|
||||||
@ -318,6 +320,13 @@ static char *out_buff;
|
|||||||
static uint out_length;
|
static uint out_length;
|
||||||
static int eval_result = 0;
|
static int eval_result = 0;
|
||||||
|
|
||||||
|
/* For column replace */
|
||||||
|
char *replace_column[MAX_COLUMNS];
|
||||||
|
uint max_replace_column= 0;
|
||||||
|
|
||||||
|
static void get_replace_column(struct st_query *q);
|
||||||
|
static void free_replace_column();
|
||||||
|
|
||||||
/* Disable functions that only exist in MySQL 4.0 */
|
/* Disable functions that only exist in MySQL 4.0 */
|
||||||
#if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY)
|
#if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY)
|
||||||
void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
|
void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
|
||||||
@ -338,7 +347,6 @@ static const char *embedded_server_groups[] = {
|
|||||||
NullS
|
NullS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
|
static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
|
||||||
{
|
{
|
||||||
const char* p;
|
const char* p;
|
||||||
@ -433,6 +441,7 @@ static void free_used_memory()
|
|||||||
delete_dynamic(&q_lines);
|
delete_dynamic(&q_lines);
|
||||||
dynstr_free(&ds_res);
|
dynstr_free(&ds_res);
|
||||||
free_replace();
|
free_replace();
|
||||||
|
free_replace_column();
|
||||||
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
free_defaults(default_argv);
|
free_defaults(default_argv);
|
||||||
mysql_server_end();
|
mysql_server_end();
|
||||||
@ -2048,27 +2057,35 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
|
|||||||
dynstr_append_mem(ds, val, len);
|
dynstr_append_mem(ds, val, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Append all results to the dynamic string separated with '\t'
|
Append all results to the dynamic string separated with '\t'
|
||||||
|
Values may be converted with 'replace_column'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
|
static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
|
||||||
{
|
{
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
int num_fields= mysql_num_fields(res);
|
uint num_fields= mysql_num_fields(res);
|
||||||
unsigned long *lengths;
|
unsigned long *lengths;
|
||||||
while ((row = mysql_fetch_row(res)))
|
while ((row = mysql_fetch_row(res)))
|
||||||
{
|
{
|
||||||
int i;
|
uint i;
|
||||||
lengths = mysql_fetch_lengths(res);
|
lengths = mysql_fetch_lengths(res);
|
||||||
for (i = 0; i < num_fields; i++)
|
for (i = 0; i < num_fields; i++)
|
||||||
{
|
{
|
||||||
const char *val= row[i];
|
const char *val= row[i];
|
||||||
ulonglong len= lengths[i];
|
ulonglong len= lengths[i];
|
||||||
|
|
||||||
|
if (i < max_replace_column && replace_column[i])
|
||||||
|
{
|
||||||
|
val= replace_column[i];
|
||||||
|
len= strlen(val);
|
||||||
|
}
|
||||||
if (!val)
|
if (!val)
|
||||||
{
|
{
|
||||||
val = "NULL";
|
val= "NULL";
|
||||||
len = 4;
|
len= 4;
|
||||||
}
|
}
|
||||||
if (i)
|
if (i)
|
||||||
dynstr_append_mem(ds, "\t", 1);
|
dynstr_append_mem(ds, "\t", 1);
|
||||||
@ -2076,6 +2093,7 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
|
|||||||
}
|
}
|
||||||
dynstr_append_mem(ds, "\n", 1);
|
dynstr_append_mem(ds, "\n", 1);
|
||||||
}
|
}
|
||||||
|
free_replace_column();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2539,6 +2557,9 @@ int main(int argc, char **argv)
|
|||||||
case Q_REPLACE:
|
case Q_REPLACE:
|
||||||
get_replace(q);
|
get_replace(q);
|
||||||
break;
|
break;
|
||||||
|
case Q_REPLACE_COLUMN:
|
||||||
|
get_replace_column(q);
|
||||||
|
break;
|
||||||
case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
|
case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
|
||||||
case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
|
case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
|
||||||
case Q_SYNC_SLAVE_WITH_MASTER:
|
case Q_SYNC_SLAVE_WITH_MASTER:
|
||||||
@ -3357,3 +3378,60 @@ static void free_replace_buffer(void)
|
|||||||
{
|
{
|
||||||
my_free(out_buff,MYF(MY_WME));
|
my_free(out_buff,MYF(MY_WME));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Replace results for a column
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static void free_replace_column()
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
for (i=0 ; i < max_replace_column ; i++)
|
||||||
|
{
|
||||||
|
if (replace_column[i])
|
||||||
|
{
|
||||||
|
my_free(replace_column[i], 0);
|
||||||
|
replace_column[i]= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
max_replace_column= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get arguments for replace_columns. The syntax is:
|
||||||
|
replace-column column_number to_string [column_number to_string ...]
|
||||||
|
Where each argument may be quoted with ' or "
|
||||||
|
A argument may also be a variable, in which case the value of the
|
||||||
|
variable is replaced.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void get_replace_column(struct st_query *q)
|
||||||
|
{
|
||||||
|
char *from=q->first_argument;
|
||||||
|
char *buff,*start;
|
||||||
|
DBUG_ENTER("get_replace_columns");
|
||||||
|
|
||||||
|
free_replace_column();
|
||||||
|
if (!*from)
|
||||||
|
die("Missing argument in %s\n", q->query);
|
||||||
|
|
||||||
|
/* Allocate a buffer for results */
|
||||||
|
start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
|
||||||
|
while (*from)
|
||||||
|
{
|
||||||
|
char *to;
|
||||||
|
uint column_number;
|
||||||
|
|
||||||
|
to= get_string(&buff, &from, q);
|
||||||
|
if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
|
||||||
|
die("Wrong column number to replace_columns in %s\n", q->query);
|
||||||
|
if (!*from)
|
||||||
|
die("Wrong number of arguments to replace in %s\n", q->query);
|
||||||
|
to= get_string(&buff, &from, q);
|
||||||
|
my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
|
||||||
|
replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
|
||||||
|
set_if_bigger(max_replace_column, column_number);
|
||||||
|
}
|
||||||
|
my_free(start, MYF(0));
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
drop table if exists t1,t2,t3,t4,t5,t6;
|
drop table if exists t1,t2,t3,t4,t5,t6;
|
||||||
|
drop database if exists mysqltest;
|
||||||
create table t1 (a int not null primary key auto_increment, message char(20));
|
create table t1 (a int not null primary key auto_increment, message char(20));
|
||||||
create table t2 (a int not null primary key auto_increment, message char(20));
|
create table t2 (a int not null primary key auto_increment, message char(20));
|
||||||
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
|
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
|
||||||
@ -174,15 +175,26 @@ t3 CREATE TABLE `t3` (
|
|||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` char(20) default NULL,
|
`b` char(20) default NULL,
|
||||||
KEY `a` (`a`)
|
KEY `a` (`a`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||||
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
||||||
select * from t4;
|
select * from t4;
|
||||||
ERROR HY000: Can't open file: 't4.MRG'. (errno: 143)
|
ERROR HY000: Can't open file: 't4.MRG'. (errno: 143)
|
||||||
create table t5 (a int not null, b char(10), key(a)) type=MERGE UNION=(test.t1,test_2.t2);
|
alter table t4 add column c int;
|
||||||
ERROR HY000: Incorrect table definition; All MERGE tables must be in the same database
|
ERROR HY000: Can't open file: 't4.MRG'. (errno: 143)
|
||||||
drop table if exists t5,t4,t3,t1,t2;
|
create database mysqltest;
|
||||||
Warnings:
|
create table mysqltest.t6 (a int not null primary key auto_increment, message char(20));
|
||||||
Note 1051 Unknown table 't5'
|
create table t5 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,mysqltest.t6);
|
||||||
|
show create table t5;
|
||||||
|
Table Create Table
|
||||||
|
t5 CREATE TABLE `t5` (
|
||||||
|
`a` int(11) NOT NULL default '0',
|
||||||
|
`b` char(20) default NULL,
|
||||||
|
KEY `a` (`a`)
|
||||||
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`mysqltest`.`t6`)
|
||||||
|
alter table t5 type=myisam;
|
||||||
|
drop table t5, mysqltest.t6;
|
||||||
|
drop database mysqltest;
|
||||||
|
drop table if exists t4,t3,t1,t2;
|
||||||
create table t1 (c char(10)) type=myisam;
|
create table t1 (c char(10)) type=myisam;
|
||||||
create table t2 (c char(10)) type=myisam;
|
create table t2 (c char(10)) type=myisam;
|
||||||
create table t3 (c char(10)) union=(t1,t2) type=merge;
|
create table t3 (c char(10)) union=(t1,t2) type=merge;
|
||||||
@ -251,14 +263,14 @@ t3 CREATE TABLE `t3` (
|
|||||||
`incr` int(11) NOT NULL default '0',
|
`incr` int(11) NOT NULL default '0',
|
||||||
`othr` int(11) NOT NULL default '0',
|
`othr` int(11) NOT NULL default '0',
|
||||||
PRIMARY KEY (`incr`)
|
PRIMARY KEY (`incr`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||||
alter table t3 drop primary key;
|
alter table t3 drop primary key;
|
||||||
show create table t3;
|
show create table t3;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t3 CREATE TABLE `t3` (
|
t3 CREATE TABLE `t3` (
|
||||||
`incr` int(11) NOT NULL default '0',
|
`incr` int(11) NOT NULL default '0',
|
||||||
`othr` int(11) NOT NULL default '0'
|
`othr` int(11) NOT NULL default '0'
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||||
drop table t3,t2,t1;
|
drop table t3,t2,t1;
|
||||||
create table t1 (a int not null, key(a)) type=merge;
|
create table t1 (a int not null, key(a)) type=merge;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
@ -294,21 +306,21 @@ t4 CREATE TABLE `t4` (
|
|||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) NOT NULL default '0',
|
`b` int(11) NOT NULL default '0',
|
||||||
KEY `a` (`a`,`b`)
|
KEY `a` (`a`,`b`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||||
show create table t5;
|
show create table t5;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t5 CREATE TABLE `t5` (
|
t5 CREATE TABLE `t5` (
|
||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) NOT NULL auto_increment,
|
`b` int(11) NOT NULL auto_increment,
|
||||||
PRIMARY KEY (`a`,`b`)
|
PRIMARY KEY (`a`,`b`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`)
|
||||||
show create table t6;
|
show create table t6;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t6 CREATE TABLE `t6` (
|
t6 CREATE TABLE `t6` (
|
||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) NOT NULL auto_increment,
|
`b` int(11) NOT NULL auto_increment,
|
||||||
PRIMARY KEY (`a`,`b`)
|
PRIMARY KEY (`a`,`b`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1,t2)
|
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
|
||||||
insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
|
insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
|
||||||
insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
|
insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
|
||||||
select * from t3 order by b,a limit 3;
|
select * from t3 order by b,a limit 3;
|
||||||
@ -373,7 +385,7 @@ t4 CREATE TABLE `t4` (
|
|||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) NOT NULL default '0',
|
`b` int(11) NOT NULL default '0',
|
||||||
KEY `a` (`a`,`b`)
|
KEY `a` (`a`,`b`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2,t3)
|
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`,`t3`)
|
||||||
select * from t4 order by a,b;
|
select * from t4 order by a,b;
|
||||||
a b
|
a b
|
||||||
1 1
|
1 1
|
||||||
@ -399,7 +411,7 @@ t4 CREATE TABLE `t4` (
|
|||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) NOT NULL default '0',
|
`b` int(11) NOT NULL default '0',
|
||||||
KEY `a` (`a`,`b`)
|
KEY `a` (`a`,`b`)
|
||||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(t1,t2,t3)
|
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`,`t3`)
|
||||||
insert into t4 values (4,1),(4,2);
|
insert into t4 values (4,1),(4,2);
|
||||||
select * from t1 order by a,b;
|
select * from t1 order by a,b;
|
||||||
a b
|
a b
|
||||||
|
@ -22,7 +22,7 @@ drop table t1;
|
|||||||
|
|
||||||
#
|
#
|
||||||
# A bit bigger test
|
# A bit bigger test
|
||||||
# The 'replace_result' statements are needed because the cardinality calculated
|
# The 'replace_column' statements are needed because the cardinality calculated
|
||||||
# by innodb is not always the same between runs
|
# by innodb is not always the same between runs
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ select * from t1 where parent_id=102;
|
|||||||
select level,id from t1 where level=1;
|
select level,id from t1 where level=1;
|
||||||
select level,id,parent_id from t1 where level=1;
|
select level,id,parent_id from t1 where level=1;
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
--replace_result 87 # 50 # 48 # 43 # 25 # 24 # 6 # 3 #
|
--replace_column 7 #
|
||||||
show keys from t1;
|
show keys from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6;
|
drop table if exists t1,t2,t3,t4,t5,t6;
|
||||||
|
drop database if exists mysqltest;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
create table t1 (a int not null primary key auto_increment, message char(20));
|
create table t1 (a int not null primary key auto_increment, message char(20));
|
||||||
@ -48,13 +49,23 @@ show create table t3;
|
|||||||
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
||||||
--error 1016
|
--error 1016
|
||||||
select * from t4;
|
select * from t4;
|
||||||
--error 1212
|
--error 1016
|
||||||
create table t5 (a int not null, b char(10), key(a)) type=MERGE UNION=(test.t1,test_2.t2);
|
alter table t4 add column c int;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test tables in different databases
|
||||||
|
#
|
||||||
|
create database mysqltest;
|
||||||
|
create table mysqltest.t6 (a int not null primary key auto_increment, message char(20));
|
||||||
|
create table t5 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,mysqltest.t6);
|
||||||
|
show create table t5;
|
||||||
|
alter table t5 type=myisam;
|
||||||
|
drop table t5, mysqltest.t6;
|
||||||
|
drop database mysqltest;
|
||||||
|
|
||||||
# Because of windows, it's important that we drop the merge tables first!
|
# Because of windows, it's important that we drop the merge tables first!
|
||||||
# This should give a warning on table t5
|
drop table if exists t4,t3,t1,t2;
|
||||||
drop table if exists t5,t4,t3,t1,t2;
|
|
||||||
|
|
||||||
create table t1 (c char(10)) type=myisam;
|
create table t1 (c char(10)) type=myisam;
|
||||||
create table t2 (c char(10)) type=myisam;
|
create table t2 (c char(10)) type=myisam;
|
||||||
create table t3 (c char(10)) union=(t1,t2) type=merge;
|
create table t3 (c char(10)) union=(t1,t2) type=merge;
|
||||||
|
@ -153,8 +153,8 @@ then
|
|||||||
then
|
then
|
||||||
i_u="$i_u
|
i_u="$i_u
|
||||||
INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
|
INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
|
||||||
INSERT INTO user (host,user) values ('$hostname','');"
|
INSERT INTO user (host,user) values ('$hostname','');
|
||||||
INSERT INTO user (host,user) values ('localhost','');
|
INSERT INTO user (host,user) values ('localhost','');"
|
||||||
else
|
else
|
||||||
i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);"
|
i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);"
|
||||||
fi
|
fi
|
||||||
|
@ -303,14 +303,40 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
|
|||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Find out database name and table name from a filename */
|
||||||
|
|
||||||
|
static void split_file_name(const char *file_name,
|
||||||
|
LEX_STRING *db, LEX_STRING *name)
|
||||||
|
{
|
||||||
|
uint name_length, dir_length, prefix_length;
|
||||||
|
char buff[FN_REFLEN];
|
||||||
|
|
||||||
|
db->length= 0;
|
||||||
|
name_length= (uint) (strmake(buff, file_name, sizeof(buff)-1) - buff);
|
||||||
|
dir_length= dirname_length(buff);
|
||||||
|
if (dir_length > 1)
|
||||||
|
{
|
||||||
|
/* Get database */
|
||||||
|
buff[dir_length-1]= 0; // Remove end '/'
|
||||||
|
prefix_length= dirname_length(buff);
|
||||||
|
db->str= (char*) file_name+ prefix_length;
|
||||||
|
db->length= dir_length - prefix_length -1;
|
||||||
|
}
|
||||||
|
name->str= (char*) file_name+ dir_length;
|
||||||
|
name->length= (uint) (fn_ext(name->str) - name->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
|
void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
|
||||||
{
|
{
|
||||||
// [phi] auto_increment stuff is missing (but currently not needed)
|
|
||||||
DBUG_ENTER("ha_myisammrg::update_create_info");
|
DBUG_ENTER("ha_myisammrg::update_create_info");
|
||||||
|
|
||||||
if (!(create_info->used_fields & HA_CREATE_USED_UNION))
|
if (!(create_info->used_fields & HA_CREATE_USED_UNION))
|
||||||
{
|
{
|
||||||
MYRG_TABLE *open_table;
|
MYRG_TABLE *open_table;
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
|
|
||||||
create_info->merge_list.next= &create_info->merge_list.first;
|
create_info->merge_list.next= &create_info->merge_list.first;
|
||||||
create_info->merge_list.elements=0;
|
create_info->merge_list.elements=0;
|
||||||
|
|
||||||
@ -318,14 +344,17 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
|
|||||||
open_table != file->end_table ;
|
open_table != file->end_table ;
|
||||||
open_table++)
|
open_table++)
|
||||||
{
|
{
|
||||||
char *name=open_table->table->filename;
|
|
||||||
char buff[FN_REFLEN];
|
|
||||||
TABLE_LIST *ptr;
|
TABLE_LIST *ptr;
|
||||||
|
LEX_STRING db, name;
|
||||||
|
|
||||||
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
||||||
goto err;
|
goto err;
|
||||||
fn_format(buff,name,"","",3);
|
split_file_name(open_table->table->filename, &db, &name);
|
||||||
if (!(ptr->real_name=thd->strdup(buff)))
|
if (!(ptr->real_name= thd->strmake(name.str, name.length)))
|
||||||
goto err;
|
goto err;
|
||||||
|
if (db.length && !(ptr->db= thd->strmake(db.str, db.length)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
create_info->merge_list.elements++;
|
create_info->merge_list.elements++;
|
||||||
(*create_info->merge_list.next) = (byte*) ptr;
|
(*create_info->merge_list.next) = (byte*) ptr;
|
||||||
create_info->merge_list.next= (byte**) &ptr->next;
|
create_info->merge_list.next= (byte**) &ptr->next;
|
||||||
@ -344,37 +373,34 @@ err:
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ha_myisammrg::create(const char *name, register TABLE *form,
|
int ha_myisammrg::create(const char *name, register TABLE *form,
|
||||||
HA_CREATE_INFO *create_info)
|
HA_CREATE_INFO *create_info)
|
||||||
{
|
{
|
||||||
char buff[FN_REFLEN],**table_names,**pos;
|
char buff[FN_REFLEN],**table_names,**pos;
|
||||||
TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
|
TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
|
||||||
|
THD *thd= current_thd;
|
||||||
DBUG_ENTER("ha_myisammrg::create");
|
DBUG_ENTER("ha_myisammrg::create");
|
||||||
|
|
||||||
if (!(table_names= (char**) sql_alloc((create_info->merge_list.elements+1)*
|
if (!(table_names= (char**) thd->alloc((create_info->merge_list.elements+1)*
|
||||||
sizeof(char*))))
|
sizeof(char*))))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
for (pos=table_names ; tables ; tables=tables->next)
|
for (pos=table_names ; tables ; tables=tables->next)
|
||||||
{
|
{
|
||||||
char *table_name;
|
char *table_name;
|
||||||
|
TABLE **tbl= 0;
|
||||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||||
|
tbl= find_temporary_table(thd, tables->db, tables->real_name);
|
||||||
|
if (!tbl)
|
||||||
{
|
{
|
||||||
TABLE **tbl=find_temporary_table(current_thd,
|
uint length= my_snprintf(buff,FN_REFLEN,"%s%s/%s",
|
||||||
tables->db, tables->real_name);
|
mysql_real_data_home,
|
||||||
if (!tbl)
|
tables->db, tables->real_name);
|
||||||
{
|
if (!(table_name= thd->strmake(buff, length)))
|
||||||
table_name=sql_alloc(1+
|
DBUG_RETURN(1);
|
||||||
my_snprintf(buff,FN_REFLEN,"%s/%s/%s",mysql_real_data_home,
|
|
||||||
tables->db, tables->real_name));
|
|
||||||
if (!table_name)
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
strcpy(table_name, buff);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
table_name=(*tbl)->path;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
table_name=tables->real_name;
|
table_name=(*tbl)->path;
|
||||||
*pos++= table_name;
|
*pos++= table_name;
|
||||||
}
|
}
|
||||||
*pos=0;
|
*pos=0;
|
||||||
@ -384,9 +410,13 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
|
|||||||
(my_bool) 0));
|
(my_bool) 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ha_myisammrg::append_create_info(String *packet)
|
void ha_myisammrg::append_create_info(String *packet)
|
||||||
{
|
{
|
||||||
char buff[FN_REFLEN];
|
const char *current_db;
|
||||||
|
uint db_length;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
if (file->merge_insert_method != MERGE_INSERT_DISABLED)
|
if (file->merge_insert_method != MERGE_INSERT_DISABLED)
|
||||||
{
|
{
|
||||||
packet->append(" INSERT_METHOD=",15);
|
packet->append(" INSERT_METHOD=",15);
|
||||||
@ -395,15 +425,26 @@ void ha_myisammrg::append_create_info(String *packet)
|
|||||||
packet->append(" UNION=(",8);
|
packet->append(" UNION=(",8);
|
||||||
MYRG_TABLE *open_table,*first;
|
MYRG_TABLE *open_table,*first;
|
||||||
|
|
||||||
|
current_db= table->table_cache_key;
|
||||||
|
db_length= strlen(current_db);
|
||||||
|
|
||||||
for (first=open_table=file->open_tables ;
|
for (first=open_table=file->open_tables ;
|
||||||
open_table != file->end_table ;
|
open_table != file->end_table ;
|
||||||
open_table++)
|
open_table++)
|
||||||
{
|
{
|
||||||
char *name= open_table->table->filename;
|
LEX_STRING db, name;
|
||||||
fn_format(buff,name,"","",3);
|
split_file_name(open_table->table->filename, &db, &name);
|
||||||
if (open_table != first)
|
if (open_table != first)
|
||||||
packet->append(',');
|
packet->append(',');
|
||||||
packet->append(buff,(uint) strlen(buff));
|
/* Report database for mapped table if it isn't in current database */
|
||||||
|
if (db.length &&
|
||||||
|
(db_length != db.length ||
|
||||||
|
strncmp(current_db, db.str, db.length)))
|
||||||
|
{
|
||||||
|
append_identifier(thd, packet, db.str, db.length);
|
||||||
|
packet->append('.');
|
||||||
|
}
|
||||||
|
append_identifier(thd, packet, name.str, name.length);
|
||||||
}
|
}
|
||||||
packet->append(')');
|
packet->append(')');
|
||||||
}
|
}
|
||||||
|
@ -532,6 +532,8 @@ int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild,
|
|||||||
bool verbose);
|
bool verbose);
|
||||||
int mysqld_show_keys(THD *thd, TABLE_LIST *table);
|
int mysqld_show_keys(THD *thd, TABLE_LIST *table);
|
||||||
int mysqld_show_logs(THD *thd);
|
int mysqld_show_logs(THD *thd);
|
||||||
|
void append_identifier(THD *thd, String *packet, const char *name,
|
||||||
|
uint length);
|
||||||
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
||||||
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
||||||
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
||||||
|
@ -3388,11 +3388,6 @@ static bool check_merge_table_access(THD *thd, char *db,
|
|||||||
{
|
{
|
||||||
if (!tmp->db || !tmp->db[0])
|
if (!tmp->db || !tmp->db[0])
|
||||||
tmp->db=db;
|
tmp->db=db;
|
||||||
else if (strcmp(tmp->db,db))
|
|
||||||
{
|
|
||||||
send_error(thd,ER_UNION_TABLES_IN_DIFFERENT_DIR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
|
error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
|
||||||
table_list);
|
table_list);
|
||||||
@ -4425,6 +4420,7 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if the select is a simple select (not an union)
|
Check if the select is a simple select (not an union)
|
||||||
|
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
#include "ha_berkeley.h" // For berkeley_show_logs
|
#include "ha_berkeley.h" // For berkeley_show_logs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* extern "C" pthread_mutex_t THR_LOCK_keycache; */
|
|
||||||
|
|
||||||
static const char *grant_names[]={
|
static const char *grant_names[]={
|
||||||
"select","insert","update","delete","create","drop","reload","shutdown",
|
"select","insert","update","delete","create","drop","reload","shutdown",
|
||||||
"process","file","grant","references","index","alter"};
|
"process","file","grant","references","index","alter"};
|
||||||
@ -43,15 +41,11 @@ static int mysql_find_files(THD *thd,List<char> *files, const char *db,
|
|||||||
static int
|
static int
|
||||||
store_create_info(THD *thd, TABLE *table, String *packet);
|
store_create_info(THD *thd, TABLE *table, String *packet);
|
||||||
|
|
||||||
static void
|
|
||||||
append_identifier(THD *thd, String *packet, const char *name);
|
|
||||||
|
|
||||||
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
|
/*
|
||||||
|
Report list of databases
|
||||||
/****************************************************************************
|
A database is a directory in the mysql_data_home directory
|
||||||
** Send list of databases
|
*/
|
||||||
** A database is a directory in the mysql_data_home directory
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mysqld_show_dbs(THD *thd,const char *wild)
|
mysqld_show_dbs(THD *thd,const char *wild)
|
||||||
@ -1002,8 +996,8 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
append_identifier(THD *thd, String *packet, const char *name)
|
append_identifier(THD *thd, String *packet, const char *name, uint length)
|
||||||
{
|
{
|
||||||
char qtype;
|
char qtype;
|
||||||
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
|
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
|
||||||
@ -1014,12 +1008,12 @@ append_identifier(THD *thd, String *packet, const char *name)
|
|||||||
if (thd->options & OPTION_QUOTE_SHOW_CREATE)
|
if (thd->options & OPTION_QUOTE_SHOW_CREATE)
|
||||||
{
|
{
|
||||||
packet->append(&qtype, 1);
|
packet->append(&qtype, 1);
|
||||||
packet->append(name, 0, system_charset_info);
|
packet->append(name, length, system_charset_info);
|
||||||
packet->append(&qtype, 1);
|
packet->append(&qtype, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet->append(name, 0, system_charset_info);
|
packet->append(name, length, system_charset_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,7 +1044,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
packet->append("CREATE TEMPORARY TABLE ", 23);
|
packet->append("CREATE TEMPORARY TABLE ", 23);
|
||||||
else
|
else
|
||||||
packet->append("CREATE TABLE ", 13);
|
packet->append("CREATE TABLE ", 13);
|
||||||
append_identifier(thd,packet,table->real_name);
|
append_identifier(thd,packet, table->real_name, strlen(table->real_name));
|
||||||
packet->append(" (\n", 3);
|
packet->append(" (\n", 3);
|
||||||
|
|
||||||
Field **ptr,*field;
|
Field **ptr,*field;
|
||||||
@ -1061,7 +1055,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
|
|
||||||
uint flags = field->flags;
|
uint flags = field->flags;
|
||||||
packet->append(" ", 2);
|
packet->append(" ", 2);
|
||||||
append_identifier(thd,packet,field->field_name);
|
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
|
||||||
packet->append(' ');
|
packet->append(' ');
|
||||||
// check for surprises from the previous call to Field::sql_type()
|
// check for surprises from the previous call to Field::sql_type()
|
||||||
if (type.ptr() != tmp)
|
if (type.ptr() != tmp)
|
||||||
@ -1152,7 +1146,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
packet->append("KEY ", 4);
|
packet->append("KEY ", 4);
|
||||||
|
|
||||||
if (!found_primary)
|
if (!found_primary)
|
||||||
append_identifier(thd, packet, key_info->name);
|
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
|
||||||
|
|
||||||
if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
|
if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
|
||||||
!limited_mysql_mode && !foreign_db_mode)
|
!limited_mysql_mode && !foreign_db_mode)
|
||||||
@ -1174,7 +1168,8 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
packet->append(',');
|
packet->append(',');
|
||||||
|
|
||||||
if (key_part->field)
|
if (key_part->field)
|
||||||
append_identifier(thd,packet,key_part->field->field_name);
|
append_identifier(thd,packet,key_part->field->field_name,
|
||||||
|
strlen(key_part->field->field_name));
|
||||||
if (!key_part->field ||
|
if (!key_part->field ||
|
||||||
(key_part->length !=
|
(key_part->length !=
|
||||||
table->field[key_part->fieldnr-1]->key_length() &&
|
table->field[key_part->fieldnr-1]->key_length() &&
|
||||||
@ -1190,17 +1185,17 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
packet->append(')');
|
packet->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get possible foreign key definitions stored in InnoDB and append them
|
||||||
|
to the CREATE TABLE statement
|
||||||
|
*/
|
||||||
handler *file = table->file;
|
handler *file = table->file;
|
||||||
|
char* for_str= file->get_foreign_key_create_info();
|
||||||
|
|
||||||
/* Get possible foreign key definitions stored in InnoDB and append them
|
if (for_str)
|
||||||
to the CREATE TABLE statement */
|
{
|
||||||
|
packet->append(for_str, strlen(for_str));
|
||||||
char* for_str = file->get_foreign_key_create_info();
|
file->free_foreign_key_create_info(for_str);
|
||||||
|
|
||||||
if (for_str) {
|
|
||||||
packet->append(for_str, strlen(for_str));
|
|
||||||
|
|
||||||
file->free_foreign_key_create_info(for_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->append("\n)", 2);
|
packet->append("\n)", 2);
|
||||||
@ -1267,7 +1262,8 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
{
|
{
|
||||||
char buff[100];
|
char buff[100];
|
||||||
sprintf(buff," RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
|
sprintf(buff," RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
|
||||||
my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE);
|
my_raid_type(file->raid_type), file->raid_chunks,
|
||||||
|
file->raid_chunksize/RAID_BLOCK_SIZE);
|
||||||
packet->append(buff);
|
packet->append(buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user