mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge mleich@bk-internal.mysql.com:/home/bk/mysql-4.1
into three.local.lan:/home/matthias/Arbeit/mysql-4.1/src
This commit is contained in:
commit
fdffe61f6e
31 changed files with 637 additions and 279 deletions
|
@ -6,9 +6,10 @@ HELP Print help text
|
|||
HELP SHOW Help for SHOW command
|
||||
HELP DEBUG Help for debug compiled version
|
||||
SHOW Print information about cluster
|
||||
START BACKUP Start backup
|
||||
START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]
|
||||
Start backup (default WAIT COMPLETED)
|
||||
ABORT BACKUP <backup id> Abort backup
|
||||
SHUTDOWN Shutdown all processes in cluster and quit
|
||||
SHUTDOWN Shutdown all processes in cluster
|
||||
CLUSTERLOG ON [<severity>] ... Enable Cluster logging
|
||||
CLUSTERLOG OFF [<severity>] ... Disable Cluster logging
|
||||
CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off
|
||||
|
|
|
@ -105,3 +105,65 @@ a b
|
|||
8 28
|
||||
9 29
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
||||
INSERT t1 VALUES (1,2,10), (3,4,20);
|
||||
INSERT t1 SELECT 5,6,30 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10
|
||||
3 4 20
|
||||
5 6 30
|
||||
INSERT t1 SELECT 5,7,40 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10
|
||||
3 4 20
|
||||
5 6 130
|
||||
INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10
|
||||
3 4 1020
|
||||
5 6 130
|
||||
INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10010
|
||||
3 4 1020
|
||||
5 6 130
|
||||
INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4;
|
||||
ERROR 23000: Duplicate entry '4' for key 2
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10010
|
||||
3 4 1020
|
||||
5 6 130
|
||||
TRUNCATE TABLE t1;
|
||||
INSERT t1 VALUES (1,2,10), (3,4,20);
|
||||
CREATE TABLE t2 (x INT, y INT, z INT, d INT);
|
||||
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
||||
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
||||
INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10
|
||||
3 4 120
|
||||
5 6 30
|
||||
8 9 60
|
||||
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 2 10
|
||||
3 4 120
|
||||
5 0 30
|
||||
8 9 60
|
||||
INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||
SELECT *, VALUES(a) FROM t1;
|
||||
a b c VALUES(a)
|
||||
1 2 10 NULL
|
||||
3 4 127 NULL
|
||||
5 0 30 NULL
|
||||
8 9 60 NULL
|
||||
2 1 11 NULL
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
|
|
@ -1490,9 +1490,6 @@ Warnings:
|
|||
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < (select max(test.t2.b) from test.t2)))
|
||||
select * from t3 where a >= some (select b from t2);
|
||||
a
|
||||
6
|
||||
7
|
||||
3
|
||||
explain extended select * from t3 where a >= some (select b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
|
@ -1512,9 +1509,6 @@ Warnings:
|
|||
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < <max>(select test.t2.b AS `b` from test.t2 group by test.t2.b)))
|
||||
select * from t3 where a >= some (select b from t2 group by 1);
|
||||
a
|
||||
6
|
||||
7
|
||||
3
|
||||
explain extended select * from t3 where a >= some (select b from t2 group by 1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
|
@ -2105,3 +2099,31 @@ s1 s1 < all (select s1 from t1)
|
|||
1 0
|
||||
NULL NULL
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
Code char(3) NOT NULL default '',
|
||||
Name char(52) NOT NULL default '',
|
||||
Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
|
||||
Region char(26) NOT NULL default '',
|
||||
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||
IndepYear smallint(6) default NULL,
|
||||
Population int(11) NOT NULL default '0',
|
||||
LifeExpectancy float(3,1) default NULL,
|
||||
GNP float(10,2) default NULL,
|
||||
GNPOld float(10,2) default NULL,
|
||||
LocalName char(45) NOT NULL default '',
|
||||
GovernmentForm char(45) NOT NULL default '',
|
||||
HeadOfState char(60) default NULL,
|
||||
Capital int(11) default NULL,
|
||||
Code2 char(2) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
Warnings:
|
||||
Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
|
||||
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
|
||||
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
|
||||
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
|
||||
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
|
||||
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
c
|
||||
Oceania
|
||||
drop table t1;
|
||||
|
|
|
@ -48,3 +48,34 @@ disable_info;
|
|||
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
# WorkLog #2274 - enable INSERT .. SELECT .. UPDATE syntax
|
||||
# Same tests as beginning of this test except that insert source
|
||||
# is a result from a select statement
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
||||
INSERT t1 VALUES (1,2,10), (3,4,20);
|
||||
INSERT t1 SELECT 5,6,30 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SELECT 5,7,40 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000;
|
||||
SELECT * FROM t1;
|
||||
-- error 1062
|
||||
INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4;
|
||||
SELECT * FROM t1;
|
||||
TRUNCATE TABLE t1;
|
||||
INSERT t1 VALUES (1,2,10), (3,4,20);
|
||||
CREATE TABLE t2 (x INT, y INT, z INT, d INT);
|
||||
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
||||
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
||||
INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
|
||||
SELECT * FROM t1;
|
||||
INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||
SELECT *, VALUES(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
|
|
@ -1358,3 +1358,31 @@ insert into t1 values (1),(null);
|
|||
select * from t1 where s1 < all (select s1 from t1);
|
||||
select s1, s1 < all (select s1 from t1) from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# reference on changable fields from subquery
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
Code char(3) NOT NULL default '',
|
||||
Name char(52) NOT NULL default '',
|
||||
Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
|
||||
Region char(26) NOT NULL default '',
|
||||
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||
IndepYear smallint(6) default NULL,
|
||||
Population int(11) NOT NULL default '0',
|
||||
LifeExpectancy float(3,1) default NULL,
|
||||
GNP float(10,2) default NULL,
|
||||
GNPOld float(10,2) default NULL,
|
||||
LocalName char(45) NOT NULL default '',
|
||||
GovernmentForm char(45) NOT NULL default '',
|
||||
HeadOfState char(60) default NULL,
|
||||
Capital int(11) default NULL,
|
||||
Code2 char(2) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
|
||||
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
|
||||
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
|
||||
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
|
||||
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
drop table t1;
|
||||
|
|
|
@ -48,11 +48,10 @@ public:
|
|||
|
||||
static const EventRepLogLevelMatrix matrix[];
|
||||
static const Uint32 matrixSize;
|
||||
static int
|
||||
EventLoggerBase::event_lookup(int eventType,
|
||||
LogLevel::EventCategory &cat,
|
||||
Uint32 &threshold,
|
||||
Logger::LoggerLevel &severity);
|
||||
static int event_lookup(int eventType,
|
||||
LogLevel::EventCategory &cat,
|
||||
Uint32 &threshold,
|
||||
Logger::LoggerLevel &severity);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -666,11 +666,15 @@ extern "C" {
|
|||
* Start backup
|
||||
*
|
||||
* @param handle NDB management handle.
|
||||
* @param wait_completed 0=don't wait for confirmation
|
||||
1=wait for backup started
|
||||
2=wait for backup completed
|
||||
* @param backup_id Backup id is returned from function.
|
||||
* @param reply Reply message.
|
||||
* @return -1 on error.
|
||||
*/
|
||||
int ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* backup_id,
|
||||
int ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
|
||||
unsigned int* backup_id,
|
||||
struct ndb_mgm_reply* reply);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1280,10 +1280,10 @@ EventLogger::getText(char * m_text, size_t m_text_len,
|
|||
case EventReport::BackupCompleted:
|
||||
BaseString::snprintf(m_text,
|
||||
m_text_len,
|
||||
"%sBackup %d started from node %d completed\n"
|
||||
" StartGCP: %d StopGCP: %d\n"
|
||||
" #Records: %d #LogRecords: %d\n"
|
||||
" Data: %d bytes Log: %d bytes",
|
||||
"%sBackup %u started from node %u completed\n"
|
||||
" StartGCP: %u StopGCP: %u\n"
|
||||
" #Records: %u #LogRecords: %u\n"
|
||||
" Data: %u bytes Log: %u bytes",
|
||||
theNodeId, theData[2], refToNode(theData[1]),
|
||||
theData[3], theData[4], theData[6], theData[8],
|
||||
theData[5], theData[7]);
|
||||
|
|
|
@ -44,7 +44,8 @@ Backup::Backup(const Configuration & conf) :
|
|||
Uint32 noBackups = 0, noTables = 0, noAttribs = 0;
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless));
|
||||
ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups);
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables));
|
||||
// ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables));
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &noTables));
|
||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs));
|
||||
|
||||
noAttribs++; //RT 527 bug fix
|
||||
|
|
|
@ -609,8 +609,9 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
|
|||
|
||||
Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
|
||||
noOfUniqueHashIndexes;
|
||||
if (noOfMetaTables > MAX_TABLES)
|
||||
noOfMetaTables= MAX_TABLES;
|
||||
Uint32 noOfMetaTablesDict= noOfMetaTables;
|
||||
if (noOfMetaTablesDict > MAX_TABLES)
|
||||
noOfMetaTablesDict= MAX_TABLES;
|
||||
|
||||
{
|
||||
/**
|
||||
|
@ -619,8 +620,8 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){
|
|||
cfg.put(CFG_DICT_ATTRIBUTE,
|
||||
noOfAttributes);
|
||||
|
||||
cfg.put(CFG_DICT_TABLE,
|
||||
noOfMetaTables);
|
||||
cfg.put(CFG_DICT_TABLE,
|
||||
noOfMetaTablesDict);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1545,7 +1545,8 @@ ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
|
|||
*****************************************************************************/
|
||||
extern "C"
|
||||
int
|
||||
ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* _backup_id,
|
||||
ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
|
||||
unsigned int* _backup_id,
|
||||
struct ndb_mgm_reply* /*reply*/)
|
||||
{
|
||||
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_backup");
|
||||
|
@ -1559,8 +1560,17 @@ ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* _backup_id,
|
|||
CHECK_CONNECTED(handle, -1);
|
||||
|
||||
Properties args;
|
||||
args.put("completed", wait_completed);
|
||||
const Properties *reply;
|
||||
reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
|
||||
{ // start backup can take some time, set timeout high
|
||||
Uint64 old_timeout= handle->read_timeout;
|
||||
if (wait_completed == 2)
|
||||
handle->read_timeout= 30*60*1000; // 30 minutes
|
||||
else if (wait_completed == 1)
|
||||
handle->read_timeout= 5*60*1000; // 5 minutes
|
||||
reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
|
||||
handle->read_timeout= old_timeout;
|
||||
}
|
||||
CHECK_REPLY(reply, -1);
|
||||
|
||||
BaseString result;
|
||||
|
|
|
@ -154,7 +154,8 @@ private:
|
|||
const char * param);
|
||||
|
||||
NdbMgmHandle m_mgmsrv;
|
||||
bool connected;
|
||||
NdbMgmHandle m_mgmsrv2;
|
||||
bool m_connected;
|
||||
int m_verbose;
|
||||
int try_reconnect;
|
||||
int m_error;
|
||||
|
@ -163,6 +164,7 @@ private:
|
|||
const char *rep_host;
|
||||
bool rep_connected;
|
||||
#endif
|
||||
struct NdbThread* m_event_thread;
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,9 +263,10 @@ static const char* helpText =
|
|||
"SHOW CONFIG Print configuration\n"
|
||||
"SHOW PARAMETERS Print configuration parameters\n"
|
||||
#endif
|
||||
"START BACKUP Start backup\n"
|
||||
"START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
|
||||
" Start backup (default WAIT COMPLETED)\n"
|
||||
"ABORT BACKUP <backup id> Abort backup\n"
|
||||
"SHUTDOWN Shutdown all processes in cluster and quit\n"
|
||||
"SHUTDOWN Shutdown all processes in cluster\n"
|
||||
"CLUSTERLOG ON [<severity>] ... Enable Cluster logging\n"
|
||||
"CLUSTERLOG OFF [<severity>] ... Disable Cluster logging\n"
|
||||
"CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off\n"
|
||||
|
@ -386,13 +389,19 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
|
|||
ndbout_c("Cannot create handle to management server.");
|
||||
exit(-1);
|
||||
}
|
||||
m_mgmsrv2 = ndb_mgm_create_handle();
|
||||
if(m_mgmsrv2 == NULL) {
|
||||
ndbout_c("Cannot create handle to management server.");
|
||||
exit(-1);
|
||||
}
|
||||
if (ndb_mgm_set_connectstring(m_mgmsrv, _host))
|
||||
{
|
||||
printError();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
connected = false;
|
||||
m_connected= false;
|
||||
m_event_thread= 0;
|
||||
try_reconnect = 0;
|
||||
#ifdef HAVE_GLOBAL_REPLICATION
|
||||
rep_host = NULL;
|
||||
|
@ -406,8 +415,9 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
|
|||
*/
|
||||
CommandInterpreter::~CommandInterpreter()
|
||||
{
|
||||
connected = false;
|
||||
disconnect();
|
||||
ndb_mgm_destroy_handle(&m_mgmsrv);
|
||||
ndb_mgm_destroy_handle(&m_mgmsrv2);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -430,7 +440,10 @@ void
|
|||
CommandInterpreter::printError()
|
||||
{
|
||||
if (ndb_mgm_check_connection(m_mgmsrv))
|
||||
connected= false;
|
||||
{
|
||||
m_connected= false;
|
||||
disconnect();
|
||||
}
|
||||
ndbout_c("* %5d: %s",
|
||||
ndb_mgm_get_latest_error(m_mgmsrv),
|
||||
ndb_mgm_get_latest_error_msg(m_mgmsrv));
|
||||
|
@ -440,32 +453,109 @@ CommandInterpreter::printError()
|
|||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
|
||||
bool
|
||||
static int do_event_thread;
|
||||
static void*
|
||||
event_thread_run(void* m)
|
||||
{
|
||||
NdbMgmHandle handle= *(NdbMgmHandle*)m;
|
||||
|
||||
my_thread_init();
|
||||
|
||||
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 };
|
||||
int fd = ndb_mgm_listen_event(handle, filter);
|
||||
if (fd > 0)
|
||||
{
|
||||
do_event_thread= 1;
|
||||
char *tmp= 0;
|
||||
char buf[1024];
|
||||
SocketInputStream in(fd,10);
|
||||
do {
|
||||
if (tmp == 0) NdbSleep_MilliSleep(10);
|
||||
if((tmp = in.gets(buf, 1024)))
|
||||
ndbout << tmp;
|
||||
} while(do_event_thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_event_thread= -1;
|
||||
}
|
||||
|
||||
my_thread_end();
|
||||
NdbThread_Exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandInterpreter::connect()
|
||||
{
|
||||
if(!connected) {
|
||||
if(!m_connected)
|
||||
{
|
||||
if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
|
||||
{
|
||||
connected = true;
|
||||
const char *host= ndb_mgm_get_connected_host(m_mgmsrv);
|
||||
unsigned port= ndb_mgm_get_connected_port(m_mgmsrv);
|
||||
if(!ndb_mgm_set_connectstring(m_mgmsrv2,
|
||||
BaseString(host).appfmt(":%d",port).c_str())
|
||||
&&
|
||||
!ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1))
|
||||
{
|
||||
assert(m_event_thread == 0);
|
||||
assert(do_event_thread == 0);
|
||||
do_event_thread= 0;
|
||||
m_event_thread = NdbThread_Create(event_thread_run,
|
||||
(void**)&m_mgmsrv2,
|
||||
32768,
|
||||
"CommandInterpreted_event_thread",
|
||||
NDB_THREAD_PRIO_LOW);
|
||||
if (m_event_thread != 0)
|
||||
{
|
||||
int iter= 1000; // try for 30 seconds
|
||||
while(do_event_thread == 0 &&
|
||||
iter-- > 0)
|
||||
NdbSleep_MilliSleep(30);
|
||||
}
|
||||
if (m_event_thread == 0 ||
|
||||
do_event_thread == 0 ||
|
||||
do_event_thread == -1)
|
||||
{
|
||||
printf("Warning, event thread startup failed, degraded printouts as result\n");
|
||||
do_event_thread= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Warning, event connect failed, degraded printouts as result\n");
|
||||
}
|
||||
m_connected= true;
|
||||
if (m_verbose)
|
||||
{
|
||||
printf("Connected to Management Server at: %s:%d\n",
|
||||
ndb_mgm_get_connected_host(m_mgmsrv),
|
||||
ndb_mgm_get_connected_port(m_mgmsrv));
|
||||
host, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
return connected;
|
||||
return m_connected;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandInterpreter::disconnect()
|
||||
{
|
||||
if (connected && (ndb_mgm_disconnect(m_mgmsrv) == -1)) {
|
||||
ndbout_c("Could not disconnect from management server");
|
||||
printError();
|
||||
if (m_event_thread) {
|
||||
void *res;
|
||||
do_event_thread= 0;
|
||||
NdbThread_WaitFor(m_event_thread, &res);
|
||||
NdbThread_Destroy(&m_event_thread);
|
||||
m_event_thread= 0;
|
||||
ndb_mgm_disconnect(m_mgmsrv2);
|
||||
}
|
||||
if (m_connected)
|
||||
{
|
||||
if (ndb_mgm_disconnect(m_mgmsrv) == -1) {
|
||||
ndbout_c("Could not disconnect from management server");
|
||||
printError();
|
||||
}
|
||||
m_connected= false;
|
||||
}
|
||||
connected = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -484,6 +574,13 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
invalid_command(const char *cmd)
|
||||
{
|
||||
ndbout << "Invalid command: " << cmd << endl;
|
||||
ndbout << "Type HELP for help." << endl << endl;
|
||||
}
|
||||
|
||||
int
|
||||
CommandInterpreter::execute_impl(const char *_line)
|
||||
{
|
||||
|
@ -493,17 +590,30 @@ CommandInterpreter::execute_impl(const char *_line)
|
|||
|
||||
char * line;
|
||||
if(_line == NULL) {
|
||||
// ndbout << endl;
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
line = my_strdup(_line,MYF(MY_WME));
|
||||
My_auto_ptr<char> ptr(line);
|
||||
|
||||
if (emptyString(line) ||
|
||||
line[0] == '#') {
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
|
||||
int do_continue;
|
||||
do {
|
||||
do_continue= 0;
|
||||
BaseString::trim(line," \t");
|
||||
if (line[0] == 0 ||
|
||||
line[0] == '#')
|
||||
{
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
// for mysql client compatability remove trailing ';'
|
||||
{
|
||||
unsigned last= strlen(line)-1;
|
||||
if (line[last] == ';')
|
||||
{
|
||||
line[last]= 0;
|
||||
do_continue= 1;
|
||||
}
|
||||
}
|
||||
} while (do_continue);
|
||||
// if there is anything in the line proceed
|
||||
char* firstToken = strtok(line, " ");
|
||||
char* allAfterFirstToken = strtok(NULL, "");
|
||||
|
@ -590,8 +700,7 @@ CommandInterpreter::execute_impl(const char *_line)
|
|||
int nodeId;
|
||||
|
||||
if (! convert(firstToken, nodeId)) {
|
||||
ndbout << "Invalid command: " << _line << endl;
|
||||
ndbout << "Type HELP for help." << endl << endl;
|
||||
invalid_command(_line);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
|
@ -640,12 +749,8 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
|
|||
char* allAfterFirstToken) {
|
||||
|
||||
if (emptyString(allAfterFirstToken)) {
|
||||
if (processId == -1) {
|
||||
ndbout << "Expected a command after ALL." << endl;
|
||||
}
|
||||
else {
|
||||
ndbout << "Expected a command after node ID." << endl;
|
||||
}
|
||||
ndbout << "Expected a command after "
|
||||
<< ((processId == -1) ? "ALL." : "node ID.") << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -664,8 +769,7 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
|
|||
}
|
||||
|
||||
if(fun == 0){
|
||||
ndbout << "Invalid command: " << secondToken << endl;
|
||||
ndbout << "Type HELP for help." << endl << endl;
|
||||
invalid_command(secondToken);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -846,8 +950,7 @@ CommandInterpreter::executeHelp(char* parameters)
|
|||
ndbout << helpTextDebug;
|
||||
#endif
|
||||
} else {
|
||||
ndbout << "Invalid argument: " << parameters << endl;
|
||||
ndbout << "Type HELP for help." << endl << endl;
|
||||
invalid_command(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -901,7 +1004,8 @@ CommandInterpreter::executeShutdown(char* parameters)
|
|||
return result;
|
||||
}
|
||||
|
||||
connected = false;
|
||||
m_connected= false;
|
||||
disconnect();
|
||||
ndbout << "NDB Cluster management server shutdown." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1869,21 +1973,68 @@ CommandInterpreter::executeEventReporting(int processId,
|
|||
* Backup
|
||||
*****************************************************************************/
|
||||
int
|
||||
CommandInterpreter::executeStartBackup(char* /*parameters*/)
|
||||
CommandInterpreter::executeStartBackup(char* parameters)
|
||||
{
|
||||
struct ndb_mgm_reply reply;
|
||||
unsigned int backupId;
|
||||
|
||||
#if 0
|
||||
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 };
|
||||
int fd = ndb_mgm_listen_event(m_mgmsrv, filter);
|
||||
int result = ndb_mgm_start_backup(m_mgmsrv, &backupId, &reply);
|
||||
if (fd < 0)
|
||||
{
|
||||
ndbout << "Initializing start of backup failed" << endl;
|
||||
printError();
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
Vector<BaseString> args;
|
||||
{
|
||||
BaseString(parameters).split(args);
|
||||
for (unsigned i= 0; i < args.size(); i++)
|
||||
if (args[i].length() == 0)
|
||||
args.erase(i--);
|
||||
else
|
||||
args[i].ndb_toupper();
|
||||
}
|
||||
int sz= args.size();
|
||||
|
||||
int result;
|
||||
if (sz == 2 &&
|
||||
args[1] == "NOWAIT")
|
||||
{
|
||||
result = ndb_mgm_start_backup(m_mgmsrv, 0, &backupId, &reply);
|
||||
}
|
||||
else if (sz == 1 ||
|
||||
(sz == 3 &&
|
||||
args[1] == "WAIT" &&
|
||||
args[2] == "COMPLETED"))
|
||||
{
|
||||
ndbout_c("Waiting for completed, this may take several minutes");
|
||||
result = ndb_mgm_start_backup(m_mgmsrv, 2, &backupId, &reply);
|
||||
}
|
||||
else if (sz == 3 &&
|
||||
args[1] == "WAIT" &&
|
||||
args[2] == "STARTED")
|
||||
{
|
||||
ndbout_c("Waiting for started, this may take several minutes");
|
||||
result = ndb_mgm_start_backup(m_mgmsrv, 1, &backupId, &reply);
|
||||
}
|
||||
else
|
||||
{
|
||||
invalid_command(parameters);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
ndbout << "Start of backup failed" << endl;
|
||||
printError();
|
||||
#if 0
|
||||
close(fd);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ndbout_c("Waiting for completed, this may take several minutes");
|
||||
char *tmp;
|
||||
char buf[1024];
|
||||
{
|
||||
|
@ -1910,29 +2061,39 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
|
|||
ndbout << tmp;
|
||||
}
|
||||
} while(tmp && tmp[0] != 0);
|
||||
|
||||
|
||||
close(fd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::executeAbortBackup(char* parameters)
|
||||
{
|
||||
strtok(parameters, " ");
|
||||
struct ndb_mgm_reply reply;
|
||||
char* id = strtok(NULL, "\0");
|
||||
int bid = -1;
|
||||
if(id == 0 || sscanf(id, "%d", &bid) != 1){
|
||||
ndbout << "Invalid arguments: expected <BackupId>" << endl;
|
||||
return;
|
||||
struct ndb_mgm_reply reply;
|
||||
if (emptyString(parameters))
|
||||
goto executeAbortBackupError1;
|
||||
|
||||
{
|
||||
strtok(parameters, " ");
|
||||
char* id = strtok(NULL, "\0");
|
||||
if(id == 0 || sscanf(id, "%d", &bid) != 1)
|
||||
goto executeAbortBackupError1;
|
||||
}
|
||||
int result = ndb_mgm_abort_backup(m_mgmsrv, bid, &reply);
|
||||
if (result != 0) {
|
||||
ndbout << "Abort of backup " << bid << " failed" << endl;
|
||||
printError();
|
||||
} else {
|
||||
ndbout << "Abort of backup " << bid << " ordered" << endl;
|
||||
{
|
||||
int result= ndb_mgm_abort_backup(m_mgmsrv, bid, &reply);
|
||||
if (result != 0) {
|
||||
ndbout << "Abort of backup " << bid << " failed" << endl;
|
||||
printError();
|
||||
} else {
|
||||
ndbout << "Abort of backup " << bid << " ordered" << endl;
|
||||
}
|
||||
}
|
||||
return;
|
||||
executeAbortBackupError1:
|
||||
ndbout << "Invalid arguments: expected <BackupId>" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLOBAL_REPLICATION
|
||||
|
|
|
@ -2397,7 +2397,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
|
|||
* Backup
|
||||
***************************************************************************/
|
||||
int
|
||||
MgmtSrvr::startBackup(Uint32& backupId, bool waitCompleted)
|
||||
MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
|
||||
{
|
||||
bool next;
|
||||
NodeId nodeId = 0;
|
||||
|
@ -2419,11 +2419,16 @@ MgmtSrvr::startBackup(Uint32& backupId, bool waitCompleted)
|
|||
req->backupDataLen = 0;
|
||||
|
||||
int result;
|
||||
if (waitCompleted) {
|
||||
result = sendRecSignal(nodeId, WAIT_BACKUP_COMPLETED, signal, true);
|
||||
if (waitCompleted == 2) {
|
||||
result = sendRecSignal(nodeId, WAIT_BACKUP_COMPLETED,
|
||||
signal, true, 30*60*1000 /*30 secs*/);
|
||||
}
|
||||
else if (waitCompleted == 1) {
|
||||
result = sendRecSignal(nodeId, WAIT_BACKUP_STARTED,
|
||||
signal, true, 5*60*1000 /*5 mins*/);
|
||||
}
|
||||
else {
|
||||
result = sendRecSignal(nodeId, WAIT_BACKUP_STARTED, signal, true);
|
||||
result = sendRecSignal(nodeId, NO_WAIT, signal, true);
|
||||
}
|
||||
if (result == -1) {
|
||||
return SEND_OR_RECEIVE_FAILED;
|
||||
|
@ -2502,18 +2507,31 @@ MgmtSrvr::abortBackup(Uint32 backupId)
|
|||
void
|
||||
MgmtSrvr::backupCallback(BackupEvent & event)
|
||||
{
|
||||
DBUG_ENTER("MgmtSrvr::backupCallback");
|
||||
m_lastBackupEvent = event;
|
||||
switch(event.Event){
|
||||
case BackupEvent::BackupFailedToStart:
|
||||
DBUG_PRINT("info",("BackupEvent::BackupFailedToStart"));
|
||||
theWaitState = NO_WAIT;
|
||||
break;
|
||||
case BackupEvent::BackupAborted:
|
||||
DBUG_PRINT("info",("BackupEvent::BackupAborted"));
|
||||
theWaitState = NO_WAIT;
|
||||
break;
|
||||
case BackupEvent::BackupCompleted:
|
||||
DBUG_PRINT("info",("BackupEvent::BackupCompleted"));
|
||||
theWaitState = NO_WAIT;
|
||||
break;
|
||||
case BackupEvent::BackupStarted:
|
||||
if(theWaitState == WAIT_BACKUP_STARTED)
|
||||
{
|
||||
DBUG_PRINT("info",("BackupEvent::BackupStarted NO_WAIT"));
|
||||
theWaitState = NO_WAIT;
|
||||
} else {
|
||||
DBUG_PRINT("info",("BackupEvent::BackupStarted"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
}
|
||||
|
||||
void add_listener(const Event_listener&);
|
||||
void update_max_log_level(const LogLevel&);
|
||||
void update_log_level(const LogLevel&);
|
||||
|
||||
void log(int eventType, const Uint32* theData, NodeId nodeId);
|
||||
|
||||
|
@ -67,6 +69,8 @@ public:
|
|||
|
||||
Event_listener& operator[](unsigned i) { return m_clients[i]; }
|
||||
const Event_listener& operator[](unsigned i) const { return m_clients[i]; }
|
||||
void lock() { m_clients.lock(); }
|
||||
void unlock(){ m_clients.unlock(); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -360,7 +364,7 @@ public:
|
|||
/**
|
||||
* Backup functionallity
|
||||
*/
|
||||
int startBackup(Uint32& backupId, bool waitCompleted = false);
|
||||
int startBackup(Uint32& backupId, int waitCompleted= 2);
|
||||
int abortBackup(Uint32 backupId);
|
||||
int performBackup(Uint32* backupId);
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ ParserRow<MgmApiSession> commands[] = {
|
|||
MGM_ARG("args", String, Mandatory, "Args(space separated int's)"),
|
||||
|
||||
MGM_CMD("start backup", &MgmApiSession::startBackup, ""),
|
||||
MGM_ARG("completed", Int, Optional ,"Wait until completed"),
|
||||
|
||||
MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""),
|
||||
MGM_ARG("id", Int, Mandatory, "Backup id"),
|
||||
|
@ -629,85 +630,30 @@ MgmApiSession::getVersion(Parser<MgmApiSession>::Context &,
|
|||
m_output->println("string: %s", NDB_VERSION_STRING);
|
||||
m_output->println("");
|
||||
}
|
||||
#if 0
|
||||
|
||||
/*****************************************************************************
|
||||
* BACKUP
|
||||
*****************************************************************************/
|
||||
|
||||
int completed;
|
||||
MgmtSrvr::BackupEvent globalEvent;
|
||||
|
||||
static void
|
||||
completedCallback(const MgmtSrvr::BackupEvent & event){
|
||||
|
||||
ndbout << "WaitCallback" << endl;
|
||||
// Save event in the latestEvent var
|
||||
|
||||
switch(event.Event){
|
||||
case MgmtSrvr::BackupEvent::BackupCompleted:
|
||||
case MgmtSrvr::BackupEvent::BackupFailedToStart:
|
||||
globalEvent = event;
|
||||
completed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
|
||||
Properties const &) {
|
||||
Properties const &args) {
|
||||
DBUG_ENTER("MgmApiSession::startBackup");
|
||||
unsigned backupId;
|
||||
Uint32 completed= 2;
|
||||
int result;
|
||||
|
||||
MgmtSrvr::BackupCallback prevCallback;
|
||||
prevCallback = m_mgmsrv.setCallback(completedCallback);
|
||||
completed = 0;
|
||||
result = m_mgmsrv.startBackup(backupId);
|
||||
if (result == 0){
|
||||
args.get("completed", &completed);
|
||||
|
||||
// Wait for the callback to call our condition
|
||||
// waitFor();
|
||||
while (completed == 0)
|
||||
NdbSleep_SecSleep(0);
|
||||
|
||||
if (globalEvent.Event == MgmtSrvr::BackupEvent::BackupFailedToStart)
|
||||
result = globalEvent.FailedToStart.ErrorCode;
|
||||
else
|
||||
backupId = globalEvent.Completed.BackupId;
|
||||
}
|
||||
|
||||
// restore old callback
|
||||
m_mgmsrv.setCallback(prevCallback);
|
||||
|
||||
m_output->println("start backup reply");
|
||||
if(result != 0)
|
||||
m_output->println("result: %s(%d)", get_error_text(result), result);
|
||||
else{
|
||||
m_output->println("result: Ok");
|
||||
m_output->println("id: %d", backupId);
|
||||
}
|
||||
m_output->println("");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
|
||||
Properties const &) {
|
||||
unsigned backupId;
|
||||
int result;
|
||||
|
||||
result = m_mgmsrv.startBackup(backupId, true);
|
||||
result = m_mgmsrv.startBackup(backupId, completed);
|
||||
|
||||
m_output->println("start backup reply");
|
||||
if(result != 0)
|
||||
{
|
||||
m_output->println("result: %s", get_error_text(result));
|
||||
}
|
||||
else{
|
||||
m_output->println("result: Ok");
|
||||
m_output->println("id: %d", backupId);
|
||||
}
|
||||
m_output->println("");
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -804,19 +750,22 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
|
|||
LogLevel::EventCategory category=
|
||||
(LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
|
||||
|
||||
m_mgmsrv.m_event_listner.lock();
|
||||
if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level))
|
||||
{
|
||||
m_output->println(reply);
|
||||
m_output->println("result: Invalid category %d", category);
|
||||
m_output->println("");
|
||||
m_mgmsrv.m_event_listner.unlock();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
m_mgmsrv.m_event_listner.unlock();
|
||||
|
||||
EventSubscribeReq req;
|
||||
req.blockRef = 0;
|
||||
req.noOfEntries = 1;
|
||||
req.theData[0] = (category << 16) | level;
|
||||
m_mgmsrv.m_log_level_requests.push_back(req);
|
||||
{
|
||||
LogLevel ll;
|
||||
ll.setLogLevel(category,level);
|
||||
m_mgmsrv.m_event_listner.update_max_log_level(ll);
|
||||
}
|
||||
|
||||
m_output->println(reply);
|
||||
m_output->println("result: Ok");
|
||||
|
@ -827,13 +776,13 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
|
|||
void
|
||||
MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
|
||||
Properties const &args) {
|
||||
Uint32 node = 0, level = 0, category;
|
||||
Uint32 node = 0, level = 0, cat;
|
||||
BaseString errorString;
|
||||
SetLogLevelOrd logLevel;
|
||||
int result;
|
||||
logLevel.clear();
|
||||
args.get("node", &node);
|
||||
args.get("category", &category);
|
||||
args.get("category", &cat);
|
||||
args.get("level", &level);
|
||||
|
||||
/* XXX should use constants for this value */
|
||||
|
@ -844,12 +793,15 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
|
|||
return;
|
||||
}
|
||||
|
||||
EventSubscribeReq req;
|
||||
req.blockRef = node;
|
||||
req.noOfEntries = 1;
|
||||
req.theData[0] = (category << 16) | level;
|
||||
m_mgmsrv.m_log_level_requests.push_back(req);
|
||||
|
||||
LogLevel::EventCategory category=
|
||||
(LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
|
||||
|
||||
{
|
||||
LogLevel ll;
|
||||
ll.setLogLevel(category,level);
|
||||
m_mgmsrv.m_event_listner.update_max_log_level(ll);
|
||||
}
|
||||
|
||||
m_output->println("set loglevel reply");
|
||||
m_output->println("result: Ok");
|
||||
m_output->println("");
|
||||
|
@ -1319,24 +1271,22 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId)
|
|||
tmp.set_max(m_clients[i].m_logLevel);
|
||||
}
|
||||
m_clients.unlock();
|
||||
|
||||
if(!(tmp == m_logLevel)){
|
||||
m_logLevel = tmp;
|
||||
EventSubscribeReq req;
|
||||
req = tmp;
|
||||
req.blockRef = 0;
|
||||
m_mgmsrv->m_log_level_requests.push_back(req);
|
||||
}
|
||||
update_log_level(tmp);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void
|
||||
Ndb_mgmd_event_service::add_listener(const Event_listener& client){
|
||||
m_clients.push_back(client);
|
||||
LogLevel tmp = m_logLevel;
|
||||
tmp.set_max(client.m_logLevel);
|
||||
|
||||
Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level)
|
||||
{
|
||||
LogLevel tmp= m_logLevel;
|
||||
tmp.set_max(log_level);
|
||||
update_log_level(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp)
|
||||
{
|
||||
if(!(tmp == m_logLevel)){
|
||||
m_logLevel = tmp;
|
||||
EventSubscribeReq req;
|
||||
|
@ -1346,14 +1296,22 @@ Ndb_mgmd_event_service::add_listener(const Event_listener& client){
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ndb_mgmd_event_service::add_listener(const Event_listener& client){
|
||||
m_clients.push_back(client);
|
||||
update_max_log_level(client.m_logLevel);
|
||||
}
|
||||
|
||||
void
|
||||
Ndb_mgmd_event_service::stop_sessions(){
|
||||
m_clients.lock();
|
||||
for(int i = m_clients.size() - 1; i >= 0; i--){
|
||||
if(m_clients[i].m_socket >= 0){
|
||||
NDB_CLOSE_SOCKET(m_clients[i].m_socket);
|
||||
m_clients.erase(i);
|
||||
}
|
||||
}
|
||||
m_clients.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -46,7 +46,8 @@ NdbBackup::start(unsigned int & _backup_id){
|
|||
ndb_mgm_reply reply;
|
||||
reply.return_code = 0;
|
||||
|
||||
if (ndb_mgm_start_backup(handle,
|
||||
if (ndb_mgm_start_backup(handle,
|
||||
2, // wait until completed
|
||||
&_backup_id,
|
||||
&reply) == -1) {
|
||||
g_err << "Could not start backup " << endl;
|
||||
|
|
|
@ -3,14 +3,14 @@ CREATE DATABASE test;
|
|||
|
||||
USE mysql;
|
||||
|
||||
CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
|
||||
CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges';
|
||||
|
||||
INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
|
||||
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
|
||||
|
||||
CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
|
||||
CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
|
||||
|
||||
CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
|
||||
CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
|
||||
|
||||
INSERT INTO user VALUES ('localhost','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 ('','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);
|
||||
|
@ -18,21 +18,21 @@ INSERT INTO user VALUES ('','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y
|
|||
INSERT INTO user (host,user) values ('localhost','');
|
||||
INSERT INTO user (host,user) values ('','');
|
||||
|
||||
CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
|
||||
CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions';
|
||||
|
||||
CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
|
||||
CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges';
|
||||
|
||||
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
|
||||
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges';
|
||||
|
||||
CREATE TABLE help_topic (help_topic_id int unsigned NOT NULL, name varchar(64) NOT NULL, help_category_id smallint unsigned NOT NULL, description text NOT NULL, example text NOT NULL, url varchar(128) NOT NULL, primary key (help_topic_id), unique index (name))comment='help topics';
|
||||
CREATE TABLE help_category (help_category_id smallint unsigned NOT NULL, name varchar(64) NOT NULL, parent_category_id smallint unsigned null, url varchar(128) NOT NULL, primary key (help_category_id), unique index (name)) comment='help categories';
|
||||
CREATE TABLE help_keyword (help_keyword_id int unsigned NOT NULL, name varchar(64) NOT NULL, primary key (help_keyword_id), unique index (name)) comment='help keywords';
|
||||
CREATE TABLE help_relation (help_topic_id int unsigned NOT NULL references help_topic, help_keyword_id int unsigned NOT NULL references help_keyword, primary key (help_keyword_id, help_topic_id)) comment='keyword-topic relation';
|
||||
CREATE TABLE help_topic (help_topic_id int unsigned NOT NULL, name varchar(64) NOT NULL, help_category_id smallint unsigned NOT NULL, description text NOT NULL, example text NOT NULL, url varchar(128) NOT NULL, primary key (help_topic_id), unique index (name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='help topics';
|
||||
CREATE TABLE help_category (help_category_id smallint unsigned NOT NULL, name varchar(64) NOT NULL, parent_category_id smallint unsigned null, url varchar(128) NOT NULL, primary key (help_category_id), unique index (name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='help categories';
|
||||
CREATE TABLE help_keyword (help_keyword_id int unsigned NOT NULL, name varchar(64) NOT NULL, primary key (help_keyword_id), unique index (name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='help keywords';
|
||||
CREATE TABLE help_relation (help_topic_id int unsigned NOT NULL references help_topic, help_keyword_id int unsigned NOT NULL references help_keyword, primary key (help_keyword_id, help_topic_id)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='keyword-topic relation';
|
||||
|
||||
CREATE TABLE time_zone_name (Name char(64) NOT NULL,Time_zone_id int unsigned NOT NULL,PRIMARY KEY Name (Name)) DEFAULT CHARACTER SET latin1 comment='Time zone names';
|
||||
CREATE TABLE time_zone_name (Name char(64) NOT NULL,Time_zone_id int unsigned NOT NULL,PRIMARY KEY Name (Name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Time zone names';
|
||||
|
||||
CREATE TABLE time_zone (Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL,PRIMARY KEY TzId (Time_zone_id)) DEFAULT CHARACTER SET latin1 comment='Time zones';
|
||||
CREATE TABLE time_zone_transition (Time_zone_id int unsigned NOT NULL,Transition_time bigint signed NOT NULL,Transition_type_id int unsigned NOT NULL,PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)) DEFAULT CHARACTER SET latin1 comment='Time zone transitions';
|
||||
CREATE TABLE time_zone (Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL,PRIMARY KEY TzId (Time_zone_id)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Time zones';
|
||||
CREATE TABLE time_zone_transition (Time_zone_id int unsigned NOT NULL,Transition_time bigint signed NOT NULL,Transition_type_id int unsigned NOT NULL,PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Time zone transitions';
|
||||
|
||||
CREATE TABLE time_zone_transition_type (Time_zone_id int unsigned NOT NULL,Transition_type_id int unsigned NOT NULL,Offset int signed DEFAULT 0 NOT NULL,Is_DST tinyint unsigned DEFAULT 0 NOT NULL,Abbreviation char(8) DEFAULT '' NOT NULL,PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)) DEFAULT CHARACTER SET latin1 comment='Time zone transition types';
|
||||
CREATE TABLE time_zone_leap_second (Transition_time bigint signed NOT NULL,Correction int signed NOT NULL,PRIMARY KEY TranTime (Transition_time)) DEFAULT CHARACTER SET latin1 comment='Leap seconds information for time zones';
|
||||
CREATE TABLE time_zone_transition_type (Time_zone_id int unsigned NOT NULL,Transition_type_id int unsigned NOT NULL,Offset int signed DEFAULT 0 NOT NULL,Is_DST tinyint unsigned DEFAULT 0 NOT NULL,Abbreviation char(8) DEFAULT '' NOT NULL,PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Time zone transition types';
|
||||
CREATE TABLE time_zone_leap_second (Transition_time bigint signed NOT NULL,Correction int signed NOT NULL,PRIMARY KEY TranTime (Transition_time)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Leap seconds information for time zones';
|
||||
|
|
|
@ -206,7 +206,7 @@ unique index (name) \
|
|||
print "Filling online help tables with contents...\n";
|
||||
# Generate the path for "fill_help_tables.sql" file which is in different folder.
|
||||
$fill_help_table=$0;
|
||||
$fill_help_table =~ s/scripts[\\\/]mysql_fix_privilege_tables.pl/support-files\\fill_help_tables.sql/;
|
||||
$fill_help_table =~ s/scripts[\\\/]mysql_fix_privilege_tables.pl/share\\fill_help_tables.sql/;
|
||||
|
||||
#read all content from the sql file which contains recordsfor help tables.
|
||||
open(fileIN,$fill_help_table) or die("Cannot open $fill_help_table: $!");
|
||||
|
|
34
sql/item.cc
34
sql/item.cc
|
@ -69,7 +69,7 @@ Item::Item():
|
|||
}
|
||||
|
||||
/*
|
||||
Constructor used by Item_field, Item_ref & agregate (sum) functions.
|
||||
Constructor used by Item_field, Item_*_ref & agregate (sum) functions.
|
||||
Used for duplicating lists in processing queries with temporary
|
||||
tables
|
||||
*/
|
||||
|
@ -114,7 +114,7 @@ Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
|||
name = (char*) field_name_par;
|
||||
}
|
||||
|
||||
// Constructor used by Item_field & Item_ref (see Item comment)
|
||||
// Constructor used by Item_field & Item_*_ref (see Item comment)
|
||||
Item_ident::Item_ident(THD *thd, Item_ident *item)
|
||||
:Item(thd, item),
|
||||
orig_db_name(item->orig_db_name),
|
||||
|
@ -1372,6 +1372,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
|
|||
|
||||
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
enum_parsing_place place= NO_MATTER;
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
if (!field) // If field is not checked
|
||||
{
|
||||
|
@ -1419,8 +1420,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
}
|
||||
|
||||
Item_subselect *prev_subselect_item= prev_unit->item;
|
||||
enum_parsing_place place=
|
||||
prev_subselect_item->parsing_place;
|
||||
place= prev_subselect_item->parsing_place;
|
||||
/*
|
||||
check table fields only if subquery used somewhere out of HAVING
|
||||
or outer SELECT do not use groupping (i.e. tables are
|
||||
|
@ -1489,8 +1489,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
return -1;
|
||||
}
|
||||
|
||||
Item_ref *rf= new Item_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name, (char *)field_name);
|
||||
Item_ref *rf= (place == IN_HAVING ?
|
||||
new Item_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name) :
|
||||
new Item_direct_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name));
|
||||
if (!rf)
|
||||
return 1;
|
||||
thd->change_item_tree(ref, rf);
|
||||
|
@ -2039,6 +2044,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
uint counter;
|
||||
enum_parsing_place place= NO_MATTER;
|
||||
bool not_used;
|
||||
if (!ref)
|
||||
{
|
||||
|
@ -2097,8 +2103,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||
// it is primary INSERT st_select_lex => skip first table resolving
|
||||
table_list= table_list->next;
|
||||
}
|
||||
enum_parsing_place place=
|
||||
prev_subselect_item->parsing_place;
|
||||
place= prev_subselect_item->parsing_place;
|
||||
/*
|
||||
check table fields only if subquery used somewhere out of HAVING
|
||||
or SELECT list or outer SELECT do not use groupping (i.e. tables
|
||||
|
@ -2168,6 +2173,19 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||
}
|
||||
mark_as_dependent(thd, last, thd->lex->current_select,
|
||||
this);
|
||||
if (place == IN_HAVING)
|
||||
{
|
||||
Item_ref *rf;
|
||||
if (!(rf= new Item_direct_ref(last->ref_pointer_array + counter,
|
||||
(char *)table_name,
|
||||
(char *)field_name)))
|
||||
return 1;
|
||||
ref= 0; // Safety
|
||||
if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1))
|
||||
return 1;
|
||||
thd->change_item_tree(reference, rf);
|
||||
return 0;
|
||||
}
|
||||
ref= last->ref_pointer_array + counter;
|
||||
}
|
||||
else if (!ref)
|
||||
|
|
43
sql/item.h
43
sql/item.h
|
@ -889,6 +889,49 @@ public:
|
|||
void print(String *str);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
The same as Item_ref, but get value from val_* family of method to get
|
||||
value of item on which it referred instead of result* family.
|
||||
*/
|
||||
class Item_direct_ref :public Item_ref
|
||||
{
|
||||
public:
|
||||
Item_direct_ref(Item **item, const char *table_name_par,
|
||||
const char *field_name_par)
|
||||
:Item_ref(item, table_name_par, field_name_par) {}
|
||||
/* Constructor need to process subselect with temporary tables (see Item) */
|
||||
Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
|
||||
double val()
|
||||
{
|
||||
double tmp=(*ref)->val();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
longlong tmp=(*ref)->val_int();
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
String *val_str(String* tmp)
|
||||
{
|
||||
tmp=(*ref)->val_str(tmp);
|
||||
null_value=(*ref)->null_value;
|
||||
return tmp;
|
||||
}
|
||||
bool is_null()
|
||||
{
|
||||
(void) (*ref)->val_int();
|
||||
return (*ref)->null_value;
|
||||
}
|
||||
bool get_date(TIME *ltime,uint fuzzydate)
|
||||
{
|
||||
return (null_value=(*ref)->get_date(ltime,fuzzydate));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_in_subselect;
|
||||
class Item_ref_null_helper: public Item_ref
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ longlong Item_func_not_all::val_int()
|
|||
|
||||
/*
|
||||
return TRUE if there was records in underlaying select in max/min
|
||||
optimisation
|
||||
optimisation (ALL subquery)
|
||||
*/
|
||||
if (empty_underlying_subquery())
|
||||
return 1;
|
||||
|
@ -157,11 +157,11 @@ longlong Item_func_nop_all::val_int()
|
|||
double value= args[0]->val();
|
||||
|
||||
/*
|
||||
return TRUE if there was records in underlaying select in max/min
|
||||
optimisation
|
||||
return FALSE if there was records in underlaying select in max/min
|
||||
optimisation (SAME/ANY subquery)
|
||||
*/
|
||||
if (empty_underlying_subquery())
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
null_value= args[0]->null_value;
|
||||
return (null_value || value == 0) ? 0 : 1;
|
||||
|
|
|
@ -797,9 +797,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
we can use same item for all selects.
|
||||
*/
|
||||
expr= new Item_ref((Item**)optimizer->get_cache(),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name);
|
||||
expr= new Item_direct_ref((Item**)optimizer->get_cache(),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name);
|
||||
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
}
|
||||
|
@ -993,9 +993,10 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
|||
(char *) "<no matter>",
|
||||
(char *) "<list ref>");
|
||||
func=
|
||||
eq_creator.create(new Item_ref((*optimizer->get_cache())->addr(i),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
eq_creator.create(new Item_direct_ref((*optimizer->get_cache())->
|
||||
addr(i),
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
func);
|
||||
item= and_items(item, func);
|
||||
}
|
||||
|
|
|
@ -362,7 +362,6 @@ bool check_merge_table_access(THD *thd, char *db,
|
|||
TABLE_LIST *table_list);
|
||||
int multi_update_precheck(THD *thd, TABLE_LIST *tables);
|
||||
int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
|
||||
int insert_select_precheck(THD *thd, TABLE_LIST *tables);
|
||||
int update_precheck(THD *thd, TABLE_LIST *tables);
|
||||
int delete_precheck(THD *thd, TABLE_LIST *tables);
|
||||
int insert_precheck(THD *thd, TABLE_LIST *tables);
|
||||
|
|
|
@ -1238,6 +1238,16 @@ class select_insert :public select_result_interceptor {
|
|||
bzero((char*) &info,sizeof(info));
|
||||
info.handle_duplicates=duplic;
|
||||
}
|
||||
select_insert(TABLE *table_par, List<Item> *fields_par,
|
||||
List<Item> *update_fields, List<Item> *update_values,
|
||||
enum_duplicates duplic)
|
||||
:table(table_par), fields(fields_par), last_insert_id(0)
|
||||
{
|
||||
bzero((char*) &info,sizeof(info));
|
||||
info.handle_duplicates=duplic;
|
||||
info.update_fields= update_fields;
|
||||
info.update_values= update_values;
|
||||
}
|
||||
~select_insert();
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
bool send_data(List<Item> &items);
|
||||
|
|
|
@ -197,15 +197,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
thd->used_tables=0;
|
||||
values= its++;
|
||||
|
||||
if (duplic == DUP_UPDATE && !table->insert_values)
|
||||
{
|
||||
/* it should be allocated before Item::fix_fields() */
|
||||
table->insert_values=
|
||||
(byte *)alloc_root(thd->mem_root, table->rec_buff_length);
|
||||
if (!table->insert_values)
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (mysql_prepare_insert(thd, table_list, insert_table_list, table,
|
||||
fields, values, update_fields,
|
||||
update_values, duplic))
|
||||
|
@ -448,14 +439,24 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||
enum_duplicates duplic)
|
||||
{
|
||||
DBUG_ENTER("mysql_prepare_insert");
|
||||
if (check_insert_fields(thd, table, fields, *values, 1) ||
|
||||
if (duplic == DUP_UPDATE && !table->insert_values)
|
||||
{
|
||||
/* it should be allocated before Item::fix_fields() */
|
||||
table->insert_values=
|
||||
(byte *)alloc_root(thd->mem_root, table->rec_buff_length);
|
||||
if (!table->insert_values)
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if ((values && check_insert_fields(thd, table, fields, *values, 1)) ||
|
||||
setup_tables(insert_table_list) ||
|
||||
setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
|
||||
(values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) ||
|
||||
(duplic == DUP_UPDATE &&
|
||||
(setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0) ||
|
||||
setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0))))
|
||||
DBUG_RETURN(-1);
|
||||
if (find_real_table_in_list(table_list->next,
|
||||
if ((thd->lex->sql_command==SQLCOM_INSERT ||
|
||||
thd->lex->sql_command==SQLCOM_REPLACE) &&
|
||||
find_real_table_in_list(table_list->next,
|
||||
table_list->db, table_list->real_name))
|
||||
{
|
||||
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
|
||||
|
@ -550,8 +551,10 @@ int write_record(TABLE *table,COPY_INFO *info)
|
|||
that matches, is updated. If update causes a conflict again,
|
||||
an error is returned
|
||||
*/
|
||||
DBUG_ASSERT(table->insert_values != NULL);
|
||||
store_record(table,insert_values);
|
||||
restore_record(table,record[1]);
|
||||
DBUG_ASSERT(info->update_fields->elements==info->update_values->elements);
|
||||
if (fill_record(*info->update_fields, *info->update_values, 0))
|
||||
goto err;
|
||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||
|
|
|
@ -123,6 +123,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
|
|||
lex->unit.thd= thd;
|
||||
lex->select_lex.init_query();
|
||||
lex->value_list.empty();
|
||||
lex->update_list.empty();
|
||||
lex->param_list.empty();
|
||||
lex->unit.next= lex->unit.master=
|
||||
lex->unit.link_next= lex->unit.return_to= 0;
|
||||
|
|
|
@ -587,7 +587,7 @@ typedef struct st_lex
|
|||
List<LEX_COLUMN> columns;
|
||||
List<Key> key_list;
|
||||
List<create_field> create_list;
|
||||
List<Item> *insert_list,field_list,value_list;
|
||||
List<Item> *insert_list,field_list,value_list,update_list;
|
||||
List<List_item> many_values;
|
||||
List<set_var_base> var_list;
|
||||
List<Item_param> param_list;
|
||||
|
|
|
@ -2717,7 +2717,7 @@ unsent_create_error:
|
|||
if ((res= insert_precheck(thd, tables)))
|
||||
break;
|
||||
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
|
||||
select_lex->item_list, lex->value_list,
|
||||
lex->update_list, lex->value_list,
|
||||
lex->duplicates);
|
||||
if (thd->net.report_error)
|
||||
res= -1;
|
||||
|
@ -2727,7 +2727,7 @@ unsent_create_error:
|
|||
case SQLCOM_INSERT_SELECT:
|
||||
{
|
||||
TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first;
|
||||
if ((res= insert_select_precheck(thd, tables)))
|
||||
if ((res= insert_precheck(thd, tables)))
|
||||
break;
|
||||
|
||||
/* Fix lock for first table */
|
||||
|
@ -2749,11 +2749,16 @@ unsent_create_error:
|
|||
select_lex->options |= OPTION_BUFFER_RESULT;
|
||||
}
|
||||
|
||||
|
||||
if (!(res= open_and_lock_tables(thd, tables)) &&
|
||||
!(res= mysql_prepare_insert(thd, tables, first_local_table,
|
||||
tables->table, lex->field_list, 0,
|
||||
lex->update_list, lex->value_list,
|
||||
lex->duplicates)) &&
|
||||
(result= new select_insert(tables->table, &lex->field_list,
|
||||
&lex->update_list, &lex->value_list,
|
||||
lex->duplicates)))
|
||||
{
|
||||
TABLE *table= tables->table;
|
||||
/* Skip first table, which is the table we are inserting in */
|
||||
lex->select_lex.table_list.first= (byte*) first_local_table->next;
|
||||
/*
|
||||
|
@ -2766,6 +2771,7 @@ unsent_create_error:
|
|||
lex->select_lex.table_list.first= (byte*) first_local_table;
|
||||
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
||||
delete result;
|
||||
table->insert_values= 0;
|
||||
if (thd->net.report_error)
|
||||
res= -1;
|
||||
}
|
||||
|
@ -5304,33 +5310,6 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
INSERT ... SELECT query pre-check
|
||||
|
||||
SYNOPSIS
|
||||
insert_delete_precheck()
|
||||
thd Thread handler
|
||||
tables Global table list
|
||||
|
||||
RETURN VALUE
|
||||
0 OK
|
||||
1 Error (message is sent to user)
|
||||
-1 Error (message is not sent to user)
|
||||
*/
|
||||
|
||||
int insert_select_precheck(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
DBUG_ENTER("insert_select_precheck");
|
||||
/*
|
||||
Check that we have modify privileges for the first table and
|
||||
select privileges for the rest
|
||||
*/
|
||||
ulong privilege= (thd->lex->duplicates == DUP_REPLACE ?
|
||||
INSERT_ACL | DELETE_ACL : INSERT_ACL);
|
||||
DBUG_RETURN(check_one_table_access(thd, privilege, tables) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
simple UPDATE query pre-check
|
||||
|
||||
|
@ -5402,6 +5381,10 @@ int insert_precheck(THD *thd, TABLE_LIST *tables)
|
|||
LEX *lex= thd->lex;
|
||||
DBUG_ENTER("insert_precheck");
|
||||
|
||||
/*
|
||||
Check that we have modify privileges for the first table and
|
||||
select privileges for the rest
|
||||
*/
|
||||
ulong privilege= INSERT_ACL |
|
||||
(lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
|
||||
(lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0);
|
||||
|
@ -5409,7 +5392,7 @@ int insert_precheck(THD *thd, TABLE_LIST *tables)
|
|||
if (check_one_table_access(thd, privilege, tables))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (lex->select_lex.item_list.elements != lex->value_list.elements)
|
||||
if (lex->update_list.elements != lex->value_list.elements)
|
||||
{
|
||||
my_error(ER_WRONG_VALUE_COUNT, MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
|
|
|
@ -1343,7 +1343,7 @@ static int mysql_test_insert_select(Prepared_statement *stmt,
|
|||
{
|
||||
int res;
|
||||
LEX *lex= stmt->lex;
|
||||
if ((res= insert_select_precheck(stmt->thd, tables)))
|
||||
if ((res= insert_precheck(stmt->thd, tables)))
|
||||
return res;
|
||||
TABLE_LIST *first_local_table=
|
||||
(TABLE_LIST *)lex->select_lex.table_list.first;
|
||||
|
|
|
@ -1418,7 +1418,7 @@ JOIN::exec()
|
|||
WHERE clause for any tables after the sorted one.
|
||||
*/
|
||||
JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
|
||||
JOIN_TAB *end_table= &curr_join->join_tab[tables];
|
||||
JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
|
||||
for (; curr_table < end_table ; curr_table++)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -4161,21 +4161,8 @@ expr_or_default:
|
|||
|
||||
opt_insert_update:
|
||||
/* empty */
|
||||
| ON DUPLICATE_SYM
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
/*
|
||||
For simplicity, let's forget about INSERT ... SELECT ... UPDATE
|
||||
for a moment.
|
||||
*/
|
||||
if (lex->sql_command != SQLCOM_INSERT)
|
||||
{
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
lex->duplicates= DUP_UPDATE;
|
||||
}
|
||||
KEY_SYM UPDATE_SYM update_list
|
||||
| ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
|
||||
KEY_SYM UPDATE_SYM insert_update_list
|
||||
;
|
||||
|
||||
/* Update rows in a table */
|
||||
|
@ -4211,16 +4198,28 @@ update:
|
|||
;
|
||||
|
||||
update_list:
|
||||
update_list ',' simple_ident equal expr_or_default
|
||||
update_list ',' update_elem
|
||||
| update_elem;
|
||||
|
||||
update_elem:
|
||||
simple_ident equal expr_or_default
|
||||
{
|
||||
if (add_item_to_list(YYTHD, $3) || add_value_to_list(YYTHD, $5))
|
||||
if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
|
||||
YYABORT;
|
||||
}
|
||||
| simple_ident equal expr_or_default
|
||||
{
|
||||
if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
|
||||
YYABORT;
|
||||
};
|
||||
};
|
||||
|
||||
insert_update_list:
|
||||
insert_update_list ',' insert_update_elem
|
||||
| insert_update_elem;
|
||||
|
||||
insert_update_elem:
|
||||
simple_ident equal expr_or_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->update_list.push_back($1) ||
|
||||
lex->value_list.push_back($3))
|
||||
YYABORT;
|
||||
};
|
||||
|
||||
opt_low_priority:
|
||||
/* empty */ { $$= YYTHD->update_lock_default; }
|
||||
|
|
Loading…
Reference in a new issue