Merge bk-internal.mysql.com:/data0/bk/mysql-5.0

into  bk-internal.mysql.com:/data0/bk/mysql-5.0-marvel
This commit is contained in:
jamppa@bk-internal.mysql.com 2007-04-17 15:52:03 +02:00
commit 82e4afb89f
63 changed files with 1657 additions and 498 deletions

View File

@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb # remember to also change ndb version below and update version.c in ndb
AM_INIT_AUTOMAKE(mysql, 5.0.40) AM_INIT_AUTOMAKE(mysql, 5.0.42)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version # ndb version
NDB_VERSION_MAJOR=5 NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0 NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=40 NDB_VERSION_BUILD=42
NDB_VERSION_STATUS="" NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ? # Set all version vars based on $VERSION. How do we do this more elegant ?

View File

@ -0,0 +1,35 @@
set autocommit=1;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; insert into bug16206 values(2)
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
f n Query 1 n use `test`; insert into bug16206 values(0)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(2)
f n Query 1 n use `test`; COMMIT
f n Query 1 n use `test`; insert into bug16206 values(3)
drop table bug16206;
set autocommit=0;
End of 5.0 tests

View File

@ -668,3 +668,17 @@ NULL
3 3
4 4
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES(1,1),(1,2),(1,3);
SELECT DISTINCT a, b FROM t1;
a b
1 1
1 2
1 3
SELECT DISTINCT a, a, b FROM t1;
a a b
1 1 1
1 1 2
1 1 3
DROP TABLE t1;
End of 5.0 tests

View File

@ -1,14 +1,14 @@
use test; use test;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c;
CREATE TABLE `t1` ( CREATE TABLE `t1_c` (
`capgoaledatta` smallint(5) unsigned NOT NULL auto_increment, `capgoaledatta` mediumint(5) unsigned NOT NULL auto_increment,
`goaledatta` char(2) NOT NULL default '', `goaledatta` char(2) NOT NULL default '',
`maturegarbagefa` varchar(32) NOT NULL default '', `maturegarbagefa` varchar(32) NOT NULL default '',
PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`) PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t1` VALUES (2,'3','q3plus.qt'),(4,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3,'20','threetrees.qt'); INSERT INTO `t1_c` VALUES (2,'3','q3plus.qt'),(400,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3000,'20','threetrees.qt');
CREATE TABLE `t2` ( CREATE TABLE `t2_c` (
`capgotod` smallint(5) unsigned NOT NULL auto_increment, `capgotod` smallint(5) unsigned NOT NULL auto_increment,
`gotod` smallint(5) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0',
`goaledatta` char(2) default NULL, `goaledatta` char(2) default NULL,
@ -16,16 +16,16 @@ CREATE TABLE `t2` (
`descrpooppo` varchar(64) default NULL, `descrpooppo` varchar(64) default NULL,
`svcutonsa` varchar(64) NOT NULL default '', `svcutonsa` varchar(64) NOT NULL default '',
PRIMARY KEY (`capgotod`), PRIMARY KEY (`capgotod`),
KEY `i_quadaddsvr` (`gotod`) KEY `i quadaddsvr` (`gotod`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t2` VALUES (5,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST');
CREATE TABLE `t3` ( CREATE TABLE `t3_c` (
`CapGoaledatta` smallint(5) unsigned NOT NULL default '0', `CapGoaledatta` smallint(5) unsigned NOT NULL default '0',
`capgotod` smallint(5) unsigned NOT NULL default '0', `capgotod` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`capgotod`,`CapGoaledatta`) PRIMARY KEY (`capgotod`,`CapGoaledatta`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t3` VALUES (5,3),(2,4),(5,4),(1,3); INSERT INTO `t3_c` VALUES (5,3),(2,4),(5,4),(1,3);
CREATE TABLE `t4` ( CREATE TABLE `t4_c` (
`capfa` bigint(20) unsigned NOT NULL auto_increment, `capfa` bigint(20) unsigned NOT NULL auto_increment,
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
`authpwchap` varchar(32) default NULL, `authpwchap` varchar(32) default NULL,
@ -35,34 +35,34 @@ CREATE TABLE `t4` (
PRIMARY KEY (`fa`,`realm`), PRIMARY KEY (`fa`,`realm`),
KEY `capfa` (`capfa`), KEY `capfa` (`capfa`),
KEY `i_quadentity` (`fa`,`realm`) KEY `i_quadentity` (`fa`,`realm`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t4` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(22,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(29,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); INSERT INTO `t4_c` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(2200,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32000,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(290000000,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL);
CREATE TABLE `t5` ( CREATE TABLE `t5_c` (
`capfa` bigint(20) unsigned NOT NULL default '0', `capfa` bigint(20) unsigned NOT NULL default '0',
`gotod` smallint(5) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0',
`orderutonsa` varchar(64) NOT NULL default '', `orderutonsa` varchar(64) NOT NULL default '',
PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`) PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t5` VALUES (21,2,''),(21,1,''),(22,4,''); INSERT INTO `t5_c` VALUES (21,2,''),(21,1,''),(22,4,'');
CREATE TABLE `t6` ( CREATE TABLE `t6_c` (
`capfa_parent` bigint(20) unsigned NOT NULL default '0', `capfa_parent` bigint(20) unsigned NOT NULL default '0',
`capfa_child` bigint(20) unsigned NOT NULL default '0', `capfa_child` bigint(20) unsigned NOT NULL default '0',
`relatta` smallint(5) unsigned NOT NULL default '0', `relatta` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`) PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t6` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); INSERT INTO `t6_c` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0);
CREATE TABLE `t7` ( CREATE TABLE `t7_c` (
`dardpo` char(15) NOT NULL default '', `dardpo` char(15) NOT NULL default '',
`dardtestard` tinyint(3) unsigned NOT NULL default '0', `dardtestard` tinyint(3) unsigned NOT NULL auto_increment,
`FastFA` char(5) NOT NULL default '', `FastFA` char(5) NOT NULL default '',
`FastCode` char(6) NOT NULL default '', `FastCode` char(6) NOT NULL default '',
`Fastca` char(1) NOT NULL default '', `Fastca` char(1) NOT NULL default '',
`Fastmag` char(1) NOT NULL default '', `Fastmag` char(1) NOT NULL default '',
`Beareratta` char(2) NOT NULL default '', `Beareratta` char(2) NOT NULL default '',
PRIMARY KEY (`dardpo`,`dardtestard`) PRIMARY KEY (`dardpo`,`dardtestard`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t7` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); INSERT INTO `t7_c` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3');
CREATE TABLE `t8` ( CREATE TABLE `t8_c` (
`kattjame` varchar(32) NOT NULL default '', `kattjame` varchar(32) NOT NULL default '',
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
`realm_entered` varchar(32) NOT NULL default '', `realm_entered` varchar(32) NOT NULL default '',
@ -88,9 +88,9 @@ CREATE TABLE `t8` (
`acctinputoctets` bigint(20) unsigned default NULL, `acctinputoctets` bigint(20) unsigned default NULL,
PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`), PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`),
KEY `squardporoot` (`squardporoot`) KEY `squardporoot` (`squardporoot`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t8` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); INSERT INTO `t8_c` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565);
CREATE TABLE `t9` ( CREATE TABLE `t9_c` (
`kattjame` varchar(32) NOT NULL default '', `kattjame` varchar(32) NOT NULL default '',
`kattjame_entered` varchar(32) NOT NULL default '', `kattjame_entered` varchar(32) NOT NULL default '',
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
@ -114,20 +114,21 @@ CREATE TABLE `t9` (
`actinputocctets` bigint(20) unsigned default NULL, `actinputocctets` bigint(20) unsigned default NULL,
`terminateraste` tinyint(3) unsigned default NULL, `terminateraste` tinyint(3) unsigned default NULL,
PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`) PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t9` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); INSERT INTO `t9_c` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3);
create table t10 (a int auto_increment key); create table t10_c (a int auto_increment key) ENGINE=ndbcluster;
insert into t10 values (1),(2),(3); insert into t10_c values (1),(2),(3);
create table t1_c engine=ndbcluster as select * from t1; insert into t10_c values (10000),(2000),(3000);
create table t2_c engine=ndbcluster as select * from t2; create table t1 engine=myisam as select * from t1_c;
create table t3_c engine=ndbcluster as select * from t3; create table t2 engine=myisam as select * from t2_c;
create table t4_c engine=ndbcluster as select * from t4; create table t3 engine=myisam as select * from t3_c;
create table t5_c engine=ndbcluster as select * from t5; create table t4 engine=myisam as select * from t4_c;
create table t6_c engine=ndbcluster as select * from t6; create table t5 engine=myisam as select * from t5_c;
create table t7_c engine=ndbcluster as select * from t7; create table t6 engine=myisam as select * from t6_c;
create table t8_c engine=ndbcluster as select * from t8; create table t7 engine=myisam as select * from t7_c;
create table t9_c engine=ndbcluster as select * from t9; create table t8 engine=myisam as select * from t8_c;
create table t10_c engine=ndbcluster as select * from t10; create table t9 engine=myisam as select * from t9_c;
create table t10 engine=myisam as select * from t10_c;
drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c; drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
show tables; show tables;
Tables_in_test Tables_in_test
@ -255,6 +256,24 @@ a
1 1
2 2
3 3
2000
3000
10000
show table status like 't1_c';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
X X X X X X X X X X 3001 X X X X X X X
show table status like 't2_c';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
X X X X X X X X X X 501 X X X X X X X
show table status like 't4_c';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
X X X X X X X X X X 290000001 X X X X X X X
show table status like 't7_c';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
X X X X X X X X X X 29 X X X X X X X
show table status like 't10_c';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
X X X X X X X X X X 10001 X X X X X X X
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
520093696,1 520093696,1

View File

@ -175,6 +175,24 @@ ROW(2,10) <=> ROW(3,4)
SELECT ROW(NULL,10) <=> ROW(3,NULL); SELECT ROW(NULL,10) <=> ROW(3,NULL);
ROW(NULL,10) <=> ROW(3,NULL) ROW(NULL,10) <=> ROW(3,NULL)
0 0
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
ERROR 21000: Operand should contain 3 column(s)
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
ERROR 21000: Operand should contain 2 column(s)
SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
ERROR 21000: Operand should contain 1 column(s)
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
ERROR 21000: Operand should contain 1 column(s)
SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ; SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
1 0 0 0 null 1 0 0 0 null
1 0 0 0 NULL 1 0 0 0 NULL

View File

@ -3986,4 +3986,13 @@ t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265);
faq_id faq_id
265 265
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
ON ( f1.b=f2.b AND f1.a<f2.a )
WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index
1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests

View File

@ -1386,4 +1386,9 @@ ERROR 01000: Data truncated for column 'a' at row 1
insert into t1 values ('2E3x'); insert into t1 values ('2E3x');
ERROR 01000: Data truncated for column 'a' at row 1 ERROR 01000: Data truncated for column 'a' at row 1
drop table t1; drop table t1;
set sql_mode='traditional';
create table t1 (f1 set('a','a'));
ERROR HY000: Column 'f1' has duplicated value 'a' in SET
create table t1 (f1 enum('a','a'));
ERROR HY000: Column 'f1' has duplicated value 'a' in ENUM
End of 5.0 tests End of 5.0 tests

View File

@ -48,7 +48,7 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1276 Field or reference 'a' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select '1' AS `a`) = 1) Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select '1' AS `a`) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
@ -330,7 +330,7 @@ patient_uq clinic_uq
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq); explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t6 ALL NULL NULL NULL NULL 4 Using where 1 PRIMARY t6 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 t6.clinic_uq 1 Using where; Using index 2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 Using index
Warnings: Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 AS `Not_used` from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)) Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 AS `Not_used` from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
@ -1741,7 +1741,7 @@ Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `tes
explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null); explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where 1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 tt.id 1 Using where; Using index 2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 Using where; Using index
Warnings: Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))) Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
@ -3924,6 +3924,71 @@ c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
3 3 4 3 3 4
1 4 2,2 1 4 2,2
DROP table t1,t2; DROP table t1,t2;
CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a;
a MAX(b) test
1 9 m
2 3 h
3 4 i
SELECT a x, MAX(b),
(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a;
x MAX(b) test
1 9 m
2 3 h
3 4 i
SELECT a, AVG(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
FROM t1 WHERE t1.d=0 GROUP BY a;
a AVG(b) test
1 4.0000 d
2 2.0000 g
3 2.5000 NULL
SELECT tt.a,
(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt;
a test
1 n
1 n
1 n
1 n
1 n
1 n
1 n
2 o
2 o
2 o
2 o
3 p
3 p
3 p
3 p
3 p
SELECT tt.a,
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt GROUP BY tt.a;
a test
1 n
2 o
3 p
SELECT tt.a, MAX(
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
FROM t1 as tt GROUP BY tt.a;
a test
1 n
2 o
3 p
DROP TABLE t1;
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22); INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a; SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;

View File

@ -432,7 +432,7 @@ alter table t1 add index idx(oref,ie);
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2; explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 7 1 PRIMARY t2 ALL NULL NULL NULL NULL 7
2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 t2.oref,func 4 Using where; Using index; Full scan on NULL key 2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 test.t2.oref,func 4 Using where; Using index; Full scan on NULL key
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2; select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
oref a Z oref a Z
ee NULL NULL ee NULL NULL
@ -457,7 +457,7 @@ group by grp having min(ie) > 1) Z
from t2; from t2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 7 1 PRIMARY t2 ALL NULL NULL NULL NULL 7
2 DEPENDENT SUBQUERY t1 ref idx idx 5 t2.oref 2 Using where; Using temporary; Using filesort 2 DEPENDENT SUBQUERY t1 ref idx idx 5 test.t2.oref 2 Using where; Using temporary; Using filesort
select oref, a, select oref, a,
a in (select min(ie) from t1 where oref=t2.oref a in (select min(ie) from t1 where oref=t2.oref
group by grp having min(ie) > 1) Z group by grp having min(ie) > 1) Z

View File

@ -53,3 +53,30 @@ a
3 3
4 4
drop table t1; drop table t1;
create table t1 (s1 int);
insert into t1 (s1) values (1), (2), (3), (4), (5);
create view v1 as select * from t1;
truncate table v1;
select count(*) from t1;
count(*)
0
insert into t1 (s1) values (1), (2), (3), (4), (5);
create view v2 as select * from t1 where s1 > 3;
truncate table v2;
select * from t1;
s1
1
2
3
select * from v2;
s1
delete from t1;
create table t2 (s1 int, s2 int);
create view v3 as select a.s1, b.s2 from t1 a join t2 b on a.s1 = b.s1 where a.s1 > 3;
truncate table v3;
ERROR HY000: Can not delete from join view 'test.v3'
create view v4 as select * from t1 limit 1,1;
truncate table v4;
ERROR HY000: The target table v4 of the TRUNCATE is not updatable
drop view v1, v2, v3, v4;
drop table t1, t2;

View File

@ -2395,6 +2395,16 @@ Table Op Msg_type Msg_text
test.v1 optimize error 'test.v1' is not BASE TABLE test.v1 optimize error 'test.v1' is not BASE TABLE
Warnings: Warnings:
Error 1347 'test.v1' is not BASE TABLE Error 1347 'test.v1' is not BASE TABLE
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
test.v1 analyze error 'test.v1' is not BASE TABLE
Warnings:
Error 1347 'test.v1' is not BASE TABLE
REPAIR TABLE v1;
Table Op Msg_type Msg_text
test.v1 repair error 'test.v1' is not BASE TABLE
Warnings:
Error 1347 'test.v1' is not BASE TABLE
DROP VIEW v1; DROP VIEW v1;
create definer = current_user() sql security invoker view v1 as select 1; create definer = current_user() sql security invoker view v1 as select 1;
show create view v1; show create view v1;

View File

@ -0,0 +1,38 @@
-- source include/not_embedded.inc
-- source include/have_bdb.inc
#
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
#
set autocommit=1;
let $VERSION=`select version()`;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
set autocommit=0;
--echo End of 5.0 tests

View File

@ -540,3 +540,16 @@ EXPLAIN SELECT a FROM t1 GROUP BY a;
SELECT a FROM t1 GROUP BY a; SELECT a FROM t1 GROUP BY a;
DROP TABLE t1; DROP TABLE t1;
#
#Bug #27659: SELECT DISTINCT returns incorrect result set when field is
#repeated
#
#
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES(1,1),(1,2),(1,3);
SELECT DISTINCT a, b FROM t1;
SELECT DISTINCT a, a, b FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests

View File

@ -8,15 +8,22 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c,t10_c;
--enable_warnings --enable_warnings
CREATE TABLE `t1` ( # Bug #27775 - mediumint auto inc not restored correctly
`capgoaledatta` smallint(5) unsigned NOT NULL auto_increment, # - check mediumint
CREATE TABLE `t1_c` (
`capgoaledatta` mediumint(5) unsigned NOT NULL auto_increment,
`goaledatta` char(2) NOT NULL default '', `goaledatta` char(2) NOT NULL default '',
`maturegarbagefa` varchar(32) NOT NULL default '', `maturegarbagefa` varchar(32) NOT NULL default '',
PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`) PRIMARY KEY (`capgoaledatta`,`goaledatta`,`maturegarbagefa`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t1` VALUES (2,'3','q3plus.qt'),(4,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3,'20','threetrees.qt'); INSERT INTO `t1_c` VALUES (2,'3','q3plus.qt'),(400,'4','q3plus.qt'),(1,'3','q3.net'),(3,'4','q3.net'),(3000,'20','threetrees.qt');
#
CREATE TABLE `t2` ( # Bug #27758 Restoring NDB backups makes table usable in SQL nodes
# - space in key made table unusable after restore
#
# Bug #27775 - mediumint auto inc not restored correctly
# - check smallint
CREATE TABLE `t2_c` (
`capgotod` smallint(5) unsigned NOT NULL auto_increment, `capgotod` smallint(5) unsigned NOT NULL auto_increment,
`gotod` smallint(5) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0',
`goaledatta` char(2) default NULL, `goaledatta` char(2) default NULL,
@ -24,18 +31,20 @@ CREATE TABLE `t2` (
`descrpooppo` varchar(64) default NULL, `descrpooppo` varchar(64) default NULL,
`svcutonsa` varchar(64) NOT NULL default '', `svcutonsa` varchar(64) NOT NULL default '',
PRIMARY KEY (`capgotod`), PRIMARY KEY (`capgotod`),
KEY `i_quadaddsvr` (`gotod`) KEY `i quadaddsvr` (`gotod`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t2` VALUES (5,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST'); INSERT INTO `t2_c` VALUES (500,4,'','q3.net','addavp:MK_CASELECTOR=1','postorod rattoaa'),(2,1,'4','','addavp:MK_BRANDTAD=345','REDS Brandtad'),(3,2,'4','q3.net','execorder','fixedRatediPO REDS'),(1,1,'3','','addavp:MK_BRANDTAD=123','TEST Brandtad'),(6,5,'','told.q3.net','addavp:MK_BRANDTAD=123','Brandtad Toldzone'),(4,3,'3','q3.net','addavp:MK_POOLHINT=2','ratedi PO TEST');
CREATE TABLE `t3` ( CREATE TABLE `t3_c` (
`CapGoaledatta` smallint(5) unsigned NOT NULL default '0', `CapGoaledatta` smallint(5) unsigned NOT NULL default '0',
`capgotod` smallint(5) unsigned NOT NULL default '0', `capgotod` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`capgotod`,`CapGoaledatta`) PRIMARY KEY (`capgotod`,`CapGoaledatta`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t3` VALUES (5,3),(2,4),(5,4),(1,3); INSERT INTO `t3_c` VALUES (5,3),(2,4),(5,4),(1,3);
CREATE TABLE `t4` ( # Bug #27775 - mediumint auto inc not restored correctly
# - check bigint
CREATE TABLE `t4_c` (
`capfa` bigint(20) unsigned NOT NULL auto_increment, `capfa` bigint(20) unsigned NOT NULL auto_increment,
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
`authpwchap` varchar(32) default NULL, `authpwchap` varchar(32) default NULL,
@ -45,38 +54,40 @@ CREATE TABLE `t4` (
PRIMARY KEY (`fa`,`realm`), PRIMARY KEY (`fa`,`realm`),
KEY `capfa` (`capfa`), KEY `capfa` (`capfa`),
KEY `i_quadentity` (`fa`,`realm`) KEY `i_quadentity` (`fa`,`realm`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t4` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(22,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(29,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL); INSERT INTO `t4_c` VALUES (18,'john.smith','q3.net','dessjohn.smith',0,NULL),(21,'quad_katt_with_brandtad','q3.net','acne',0,NULL),(2200,'quad_katt_carattoaa','q3.net','acne',0,NULL),(26,'436462612809','sqasdt.q3.net','N/A',0,'6'),(19,'john','smith.qt','dessjohn',0,NULL),(33,'436643196120','sqasdt.q3.net','N/A',1,'6'),(28,'436642900019','sqasdt.q3.net','N/A',0,'6'),(30,'436462900209','sqasdt.q3.net','N/A',0,'6'),(16,'436640006666','sqasdt.q3.net','',0,NULL),(19,'dette','el-redun.com','dessdette',0,NULL),(12,'quad_kattPP','q3.net','acne',2,NULL),(14,'436640008888','sqasdt.q3.net','',0,NULL),(29,'463624900028','sqasdt.q3.net','N/A',0,'6'),(15,'436640099099','sqasdt.q3.net','',0,NULL),(13,'pap','q3plus.qt','acne',1,NULL),(19,'436642612091','sqasdt.q3.net','N/A',0,'6'),(12,'quad_katt','q3.net','acne',0,NULL),(11,'quad_kattVK','q3.net','acne',1,NULL),(32000,'463641969502','sqasdt.q3.net','N/A',1,'6'),(20,'joe','q3.net','joedesswd',0,NULL),(290000000,'436642900034','sqasdt.q3.net','N/A',0,'6'),(25,'contind','armerde.qt','acne',1,NULL);
CREATE TABLE `t5` ( CREATE TABLE `t5_c` (
`capfa` bigint(20) unsigned NOT NULL default '0', `capfa` bigint(20) unsigned NOT NULL default '0',
`gotod` smallint(5) unsigned NOT NULL default '0', `gotod` smallint(5) unsigned NOT NULL default '0',
`orderutonsa` varchar(64) NOT NULL default '', `orderutonsa` varchar(64) NOT NULL default '',
PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`) PRIMARY KEY (`capfa`,`gotod`,`orderutonsa`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t5` VALUES (21,2,''),(21,1,''),(22,4,''); INSERT INTO `t5_c` VALUES (21,2,''),(21,1,''),(22,4,'');
CREATE TABLE `t6` ( CREATE TABLE `t6_c` (
`capfa_parent` bigint(20) unsigned NOT NULL default '0', `capfa_parent` bigint(20) unsigned NOT NULL default '0',
`capfa_child` bigint(20) unsigned NOT NULL default '0', `capfa_child` bigint(20) unsigned NOT NULL default '0',
`relatta` smallint(5) unsigned NOT NULL default '0', `relatta` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`) PRIMARY KEY (`capfa_child`,`capfa_parent`,`relatta`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t6` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0); INSERT INTO `t6_c` VALUES (15,16,0),(19,20,0),(18326932092909551615,30,0),(26,29,0),(18326932092909551615,29,0),(19,18,0),(26,28,0),(12,14,0);
CREATE TABLE `t7` ( # Bug #27775 - mediumint auto inc not restored correctly
# - check tinyint
CREATE TABLE `t7_c` (
`dardpo` char(15) NOT NULL default '', `dardpo` char(15) NOT NULL default '',
`dardtestard` tinyint(3) unsigned NOT NULL default '0', `dardtestard` tinyint(3) unsigned NOT NULL auto_increment,
`FastFA` char(5) NOT NULL default '', `FastFA` char(5) NOT NULL default '',
`FastCode` char(6) NOT NULL default '', `FastCode` char(6) NOT NULL default '',
`Fastca` char(1) NOT NULL default '', `Fastca` char(1) NOT NULL default '',
`Fastmag` char(1) NOT NULL default '', `Fastmag` char(1) NOT NULL default '',
`Beareratta` char(2) NOT NULL default '', `Beareratta` char(2) NOT NULL default '',
PRIMARY KEY (`dardpo`,`dardtestard`) PRIMARY KEY (`dardpo`,`dardtestard`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t7` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3'); INSERT INTO `t7_c` VALUES ('2.6.2.4',24,'CECHP','54545','0','0','5'),('2.2.5.4',26,'CANFA','33223','1','1','4'),('4.3.2.4',28,'ITALD','54222','1','0','5'),('129..0.0.eins',28,'G','99999','1','1','5'),('1.1.1.1',24,'AUTPT','32323','0','1','3');
CREATE TABLE `t8` ( CREATE TABLE `t8_c` (
`kattjame` varchar(32) NOT NULL default '', `kattjame` varchar(32) NOT NULL default '',
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
`realm_entered` varchar(32) NOT NULL default '', `realm_entered` varchar(32) NOT NULL default '',
@ -102,10 +113,10 @@ CREATE TABLE `t8` (
`acctinputoctets` bigint(20) unsigned default NULL, `acctinputoctets` bigint(20) unsigned default NULL,
PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`), PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`),
KEY `squardporoot` (`squardporoot`) KEY `squardporoot` (`squardporoot`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t8` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565); INSERT INTO `t8_c` VALUES ('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643196120','436643196929','8956234534568968','5524595699','uxasmt21.net.acne.qt/481889229462692422','','1.1.1.1','2.2.4.6','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565),('4545435545','john','q3.net','q3.net','acne.li','436643196120','436643196929','45345234568968','995696699','uxasmt21.net.acne.qt/481889229462692423','','1.1.1.1','2.2.9.8','2','86989','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8821923,169,3565),('versteckter_q3net_katt','joe','q3.net','elredun.com','q3.net','436643196120','436643196939','91341234568968','695595699','uxasmt21.net.acne.qt/481889229462692421','','1.1.1.1','2.5.2.5','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',1923123,9569,6565);
CREATE TABLE `t9` ( CREATE TABLE `t9_c` (
`kattjame` varchar(32) NOT NULL default '', `kattjame` varchar(32) NOT NULL default '',
`kattjame_entered` varchar(32) NOT NULL default '', `kattjame_entered` varchar(32) NOT NULL default '',
`realm` varchar(32) NOT NULL default '', `realm` varchar(32) NOT NULL default '',
@ -129,26 +140,29 @@ CREATE TABLE `t9` (
`actinputocctets` bigint(20) unsigned default NULL, `actinputocctets` bigint(20) unsigned default NULL,
`terminateraste` tinyint(3) unsigned default NULL, `terminateraste` tinyint(3) unsigned default NULL,
PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`) PRIMARY KEY (`kattjame`,`hunderaaarbagefa`,`hassetistart`,`hassetino`)
) ENGINE=myisam DEFAULT CHARSET=latin1; ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
INSERT INTO `t9` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3); INSERT INTO `t9_c` VALUES ('3g4jh8gar2t','joe','q3.net','elredun.com','q3.net','436643316120','436643316939','91341234568968','695595699','1.1.1.1','2.2.6.2','3','86989','34','x','x','2012-03-12 18:35:04','2012-12-05 12:35:04',3123123,9569,6565,1),('4tt45345235','pap','q3plus.qt','q3plus.qt','q3.net','436643316120','436643316939','8956234534568968','5254595969','1.1.1.1','8.6.2.2','4','86989','34','x','x','2012-03-12 12:55:34','2012-12-05 11:20:04',3223433,3369,9565,2),('4545435545','john','q3.net','q3.net','acne.li','436643316120','436643316939','45345234568968','995696699','1.1.1.1','2.9.9.2','2','86998','34','x','x','2012-03-12 11:35:03','2012-12-05 08:50:04',8823123,169,3565,3);
# Bug #20820 # Bug #20820
# auto inc table not handled correctly when restored from cluster backup # auto inc table not handled correctly when restored from cluster backup
# - before fix ndb_restore would not set auto inc value correct, # - before fix ndb_restore would not set auto inc value correct,
# seen by select below # seen by select below
create table t10 (a int auto_increment key); create table t10_c (a int auto_increment key) ENGINE=ndbcluster;
insert into t10 values (1),(2),(3); insert into t10_c values (1),(2),(3);
# Bug #27775 - mediumint auto inc not restored correctly
# - check int
insert into t10_c values (10000),(2000),(3000);
create table t1_c engine=ndbcluster as select * from t1; create table t1 engine=myisam as select * from t1_c;
create table t2_c engine=ndbcluster as select * from t2; create table t2 engine=myisam as select * from t2_c;
create table t3_c engine=ndbcluster as select * from t3; create table t3 engine=myisam as select * from t3_c;
create table t4_c engine=ndbcluster as select * from t4; create table t4 engine=myisam as select * from t4_c;
create table t5_c engine=ndbcluster as select * from t5; create table t5 engine=myisam as select * from t5_c;
create table t6_c engine=ndbcluster as select * from t6; create table t6 engine=myisam as select * from t6_c;
create table t7_c engine=ndbcluster as select * from t7; create table t7 engine=myisam as select * from t7_c;
create table t8_c engine=ndbcluster as select * from t8; create table t8 engine=myisam as select * from t8_c;
create table t9_c engine=ndbcluster as select * from t9; create table t9 engine=myisam as select * from t9_c;
create table t10_c engine=ndbcluster as select * from t10; create table t10 engine=myisam as select * from t10_c;
--exec $NDB_MGM --no-defaults -e "start backup" >> $NDB_TOOLS_OUTPUT --exec $NDB_MGM --no-defaults -e "start backup" >> $NDB_TOOLS_OUTPUT
@ -215,6 +229,18 @@ select count(*)
# Bug #20820 cont'd # Bug #20820 cont'd
select * from t10_c order by a; select * from t10_c order by a;
# Bug #27775 cont'd
# - auto inc info should be correct
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
show table status like 't1_c';
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
show table status like 't2_c';
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
show table status like 't4_c';
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
show table status like 't7_c';
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
show table status like 't10_c';
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;

View File

@ -85,6 +85,31 @@ drop table t1;
SELECT ROW(2,10) <=> ROW(3,4); SELECT ROW(2,10) <=> ROW(3,4);
SELECT ROW(NULL,10) <=> ROW(3,NULL); SELECT ROW(NULL,10) <=> ROW(3,NULL);
#
# Bug #27484: nested row expressions in IN predicate
#
--error 1241
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
--error 1241
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
--error 1241
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
--error 1241
SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
--error 1241
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
--error 1241
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
--error 1241
SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
--error 1241
SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
--error 1241
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
# End of 4.1 tests # End of 4.1 tests
# #

View File

@ -3357,4 +3357,17 @@ SELECT t2.faq_id
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #19372: Optimizer does not use index anymore when WHERE index NOT IN
# () is added
#
CREATE TABLE t1 (a INT, b INT, KEY inx (b,a));
INSERT INTO t1 VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1, 6), (1,7);
EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
ON ( f1.b=f2.b AND f1.a<f2.a )
WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests

View File

@ -1249,4 +1249,13 @@ insert into t1 values ('2000a');
insert into t1 values ('2E3x'); insert into t1 values ('2E3x');
drop table t1; drop table t1;
#
# Bug#27069 set with identical elements are created
#
set sql_mode='traditional';
--error 1291
create table t1 (f1 set('a','a'));
--error 1291
create table t1 (f1 enum('a','a'));
--echo End of 5.0 tests --echo End of 5.0 tests

View File

@ -2783,6 +2783,42 @@ SELECT COUNT(*) c, a,
DROP table t1,t2; DROP table t1,t2;
#
# Bug#27321: Wrong subquery result in a grouping select
#
CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a;
SELECT a x, MAX(b),
(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a;
SELECT a, AVG(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
FROM t1 WHERE t1.d=0 GROUP BY a;
SELECT tt.a,
(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt;
SELECT tt.a,
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt GROUP BY tt.a;
SELECT tt.a, MAX(
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
FROM t1 as tt GROUP BY tt.a;
DROP TABLE t1;
# #
# Bug #27348: SET FUNCTION used in a subquery from WHERE condition # Bug #27348: SET FUNCTION used in a subquery from WHERE condition
# #

View File

@ -507,9 +507,6 @@ SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
SELECT * FROM t1 GROUP by t1.a SELECT * FROM t1 GROUP by t1.a
HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
HAVING MAX(t2.b+t1.a) < 10)); HAVING MAX(t2.b+t1.a) < 10));
#FIXME: Enable this test after fixing bug #27321
#SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
# AS test FROM t1 GROUP BY a;
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c; SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;

View File

@ -52,3 +52,35 @@ SELECT * from t1;
drop table t1; drop table t1;
# End of 4.1 tests # End of 4.1 tests
# Test for Bug#5507 "TRUNCATE should work with views"
create table t1 (s1 int);
insert into t1 (s1) values (1), (2), (3), (4), (5);
create view v1 as select * from t1;
truncate table v1;
select count(*) from t1;
insert into t1 (s1) values (1), (2), (3), (4), (5);
create view v2 as select * from t1 where s1 > 3;
truncate table v2;
select * from t1;
select * from v2;
delete from t1;
# The following should fail
create table t2 (s1 int, s2 int);
create view v3 as select a.s1, b.s2 from t1 a join t2 b on a.s1 = b.s1 where a.s1 > 3;
--error 1395
truncate table v3;
# The following should fail
create view v4 as select * from t1 limit 1,1;
--error 1288
truncate table v4;
drop view v1, v2, v3, v4;
drop table t1, t2;
# End of 5.0 tests

View File

@ -2228,6 +2228,8 @@ REPAIR TABLE v1;
DROP TABLE t1; DROP TABLE t1;
OPTIMIZE TABLE v1; OPTIMIZE TABLE v1;
ANALYZE TABLE v1;
REPAIR TABLE v1;
DROP VIEW v1; DROP VIEW v1;

View File

@ -1051,6 +1051,18 @@ class Ndb
friend class NdbDictionaryImpl; friend class NdbDictionaryImpl;
friend class NdbDictInterface; friend class NdbDictInterface;
friend class NdbBlob; friend class NdbBlob;
friend class Ndb_free_list_t<NdbRecAttr>;
friend class Ndb_free_list_t<NdbApiSignal>;
friend class Ndb_free_list_t<NdbLabel>;
friend class Ndb_free_list_t<NdbBranch>;
friend class Ndb_free_list_t<NdbSubroutine>;
friend class Ndb_free_list_t<NdbCall>;
friend class Ndb_free_list_t<NdbBlob>;
friend class Ndb_free_list_t<NdbReceiver>;
friend class Ndb_free_list_t<NdbIndexScanOperation>;
friend class Ndb_free_list_t<NdbOperation>;
friend class Ndb_free_list_t<NdbIndexOperation>;
friend class Ndb_free_list_t<NdbTransaction>;
#endif #endif
public: public:
@ -1091,7 +1103,7 @@ public:
* *
* @param aCatalogName is the new name of the current catalog * @param aCatalogName is the new name of the current catalog
*/ */
void setCatalogName(const char * aCatalogName); int setCatalogName(const char * aCatalogName);
/** /**
* The current schema name can be fetched by getSchemaName. * The current schema name can be fetched by getSchemaName.
@ -1105,7 +1117,7 @@ public:
* *
* @param aSchemaName is the new name of the current schema * @param aSchemaName is the new name of the current schema
*/ */
void setSchemaName(const char * aSchemaName); int setSchemaName(const char * aSchemaName);
#endif #endif
/** /**
@ -1120,7 +1132,7 @@ public:
* *
* @param aDatabaseName is the new name of the current database * @param aDatabaseName is the new name of the current database
*/ */
void setDatabaseName(const char * aDatabaseName); int setDatabaseName(const char * aDatabaseName);
/** /**
* The current database schema name can be fetched by getDatabaseSchemaName. * The current database schema name can be fetched by getDatabaseSchemaName.
@ -1134,7 +1146,7 @@ public:
* *
* @param aDatabaseSchemaName is the new name of the current database schema * @param aDatabaseSchemaName is the new name of the current database schema
*/ */
void setDatabaseSchemaName(const char * aDatabaseSchemaName); int setDatabaseSchemaName(const char * aDatabaseSchemaName);
/** /**
* Initializes the Ndb object * Initializes the Ndb object

View File

@ -358,7 +358,7 @@ public:
* Set name of column * Set name of column
* @param name Name of the column * @param name Name of the column
*/ */
void setName(const char * name); int setName(const char * name);
/** /**
* Set whether column is nullable or not * Set whether column is nullable or not
@ -446,7 +446,7 @@ public:
void setAutoIncrement(bool); void setAutoIncrement(bool);
bool getAutoIncrement() const; bool getAutoIncrement() const;
void setAutoIncrementInitialValue(Uint64 val); void setAutoIncrementInitialValue(Uint64 val);
void setDefaultValue(const char*); int setDefaultValue(const char*);
const char* getDefaultValue() const; const char* getDefaultValue() const;
static const Column * FRAGMENT; static const Column * FRAGMENT;
@ -661,13 +661,13 @@ public:
* Name of table * Name of table
* @param name Name of table * @param name Name of table
*/ */
void setName(const char * name); int setName(const char * name);
/** /**
* Add a column definition to a table * Add a column definition to a table
* @note creates a copy * @note creates a copy
*/ */
void addColumn(const Column &); int addColumn(const Column &);
/** /**
* @see NdbDictionary::Table::getLogging. * @see NdbDictionary::Table::getLogging.
@ -723,7 +723,7 @@ public:
/** /**
* Set frm file to store with this table * Set frm file to store with this table
*/ */
void setFrm(const void* data, Uint32 len); int setFrm(const void* data, Uint32 len);
/** /**
* Set table object type * Set table object type
@ -875,26 +875,26 @@ public:
/** /**
* Set the name of an index * Set the name of an index
*/ */
void setName(const char * name); int setName(const char * name);
/** /**
* Define the name of the table to be indexed * Define the name of the table to be indexed
*/ */
void setTable(const char * name); int setTable(const char * name);
/** /**
* Add a column to the index definition * Add a column to the index definition
* Note that the order of columns will be in * Note that the order of columns will be in
* the order they are added (only matters for ordered indexes). * the order they are added (only matters for ordered indexes).
*/ */
void addColumn(const Column & c); int addColumn(const Column & c);
/** /**
* Add a column name to the index definition * Add a column name to the index definition
* Note that the order of indexes will be in * Note that the order of indexes will be in
* the order they are added (only matters for ordered indexes). * the order they are added (only matters for ordered indexes).
*/ */
void addColumnName(const char * name); int addColumnName(const char * name);
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
/** /**
@ -903,7 +903,7 @@ public:
* the order they are added (only matters for ordered indexes). * the order they are added (only matters for ordered indexes).
* Depricated, use addColumnName instead. * Depricated, use addColumnName instead.
*/ */
void addIndexColumn(const char * name); int addIndexColumn(const char * name);
#endif #endif
/** /**
@ -911,7 +911,7 @@ public:
* Note that the order of indexes will be in * Note that the order of indexes will be in
* the order they are added (only matters for ordered indexes). * the order they are added (only matters for ordered indexes).
*/ */
void addColumnNames(unsigned noOfNames, const char ** names); int addColumnNames(unsigned noOfNames, const char ** names);
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
/** /**
@ -920,7 +920,7 @@ public:
* the order they are added (only matters for ordered indexes). * the order they are added (only matters for ordered indexes).
* Depricated, use addColumnNames instead. * Depricated, use addColumnNames instead.
*/ */
void addIndexColumns(int noOfNames, const char ** names); int addIndexColumns(int noOfNames, const char ** names);
#endif #endif
/** /**

View File

@ -332,13 +332,6 @@ NdbRecAttr::int32_value() const
return *(Int32*)theRef; return *(Int32*)theRef;
} }
inline
Int32
NdbRecAttr::medium_value() const
{
return sint3korr((unsigned char *)theRef);
}
inline inline
short short
NdbRecAttr::short_value() const NdbRecAttr::short_value() const
@ -360,13 +353,6 @@ NdbRecAttr::u_32_value() const
return *(Uint32*)theRef; return *(Uint32*)theRef;
} }
inline
Uint32
NdbRecAttr::u_medium_value() const
{
return uint3korr((unsigned char*)theRef);
}
inline inline
Uint16 Uint16
NdbRecAttr::u_short_value() const NdbRecAttr::u_short_value() const

View File

@ -38,7 +38,7 @@ public:
}; };
NdbReceiver(Ndb *aNdb); NdbReceiver(Ndb *aNdb);
void init(ReceiverType type, void* owner); int init(ReceiverType type, void* owner);
void release(); void release();
~NdbReceiver(); ~NdbReceiver();
@ -75,7 +75,7 @@ private:
* At setup * At setup
*/ */
class NdbRecAttr * getValue(const class NdbColumnImpl*, char * user_dst_ptr); class NdbRecAttr * getValue(const class NdbColumnImpl*, char * user_dst_ptr);
void do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size, Uint32 range); int do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size, Uint32 range);
void prepareSend(); void prepareSend();
void calculate_batch_size(Uint32, Uint32, Uint32&, Uint32&, Uint32&); void calculate_batch_size(Uint32, Uint32, Uint32&, Uint32&, Uint32&);

View File

@ -585,7 +585,7 @@ private:
NdbTransaction(Ndb* aNdb); NdbTransaction(Ndb* aNdb);
~NdbTransaction(); ~NdbTransaction();
void init(); // Initialize connection object for new transaction int init(); // Initialize connection object for new transaction
int executeNoBlobs(ExecType execType, int executeNoBlobs(ExecType execType,
AbortOption abortOption = AbortOnError, AbortOption abortOption = AbortOnError,

View File

@ -185,6 +185,7 @@ public:
private: private:
char* m_chr; char* m_chr;
unsigned m_len; unsigned m_len;
friend bool operator!(const BaseString& str);
}; };
inline const char* inline const char*
@ -249,6 +250,12 @@ BaseString::operator!=(const char *str) const
return strcmp(m_chr, str) != 0; return strcmp(m_chr, str) != 0;
} }
inline bool
operator!(const BaseString& str)
{
return str.m_chr == NULL;
}
inline BaseString& inline BaseString&
BaseString::assign(const BaseString& str) BaseString::assign(const BaseString& str)
{ {

View File

@ -29,14 +29,14 @@ public:
const T& operator[](unsigned i) const; const T& operator[](unsigned i) const;
unsigned size() const { return m_size; }; unsigned size() const { return m_size; };
void push_back(const T &); int push_back(const T &);
T& back(); T& back();
void erase(unsigned index); void erase(unsigned index);
void clear(); void clear();
void fill(unsigned new_size, T & obj); int fill(unsigned new_size, T & obj);
Vector<T>& operator=(const Vector<T>&); Vector<T>& operator=(const Vector<T>&);
@ -52,6 +52,14 @@ private:
template<class T> template<class T>
Vector<T>::Vector(int i){ Vector<T>::Vector(int i){
m_items = new T[i]; m_items = new T[i];
if (m_items == NULL)
{
errno = ENOMEM;
m_size = 0;
m_arraySize = 0;
m_incSize = 0;
return;
}
m_size = 0; m_size = 0;
m_arraySize = i; m_arraySize = i;
m_incSize = 50; m_incSize = 50;
@ -89,12 +97,15 @@ Vector<T>::back(){
} }
template<class T> template<class T>
void int
Vector<T>::push_back(const T & t){ Vector<T>::push_back(const T & t){
if(m_size == m_arraySize){ if(m_size == m_arraySize){
T * tmp = new T [m_arraySize + m_incSize]; T * tmp = new T [m_arraySize + m_incSize];
if(!tmp) if(tmp == NULL)
abort(); {
errno = ENOMEM;
return -1;
}
for (unsigned k = 0; k < m_size; k++) for (unsigned k = 0; k < m_size; k++)
tmp[k] = m_items[k]; tmp[k] = m_items[k];
delete[] m_items; delete[] m_items;
@ -103,6 +114,8 @@ Vector<T>::push_back(const T & t){
} }
m_items[m_size] = t; m_items[m_size] = t;
m_size++; m_size++;
return 0;
} }
template<class T> template<class T>
@ -123,10 +136,12 @@ Vector<T>::clear(){
} }
template<class T> template<class T>
void int
Vector<T>::fill(unsigned new_size, T & obj){ Vector<T>::fill(unsigned new_size, T & obj){
while(m_size <= new_size) while(m_size <= new_size)
push_back(obj); if (push_back(obj))
return -1;
return 0;
} }
template<class T> template<class T>
@ -150,8 +165,8 @@ struct MutexVector : public NdbLockable {
const T& operator[](unsigned i) const; const T& operator[](unsigned i) const;
unsigned size() const { return m_size; }; unsigned size() const { return m_size; };
void push_back(const T &); int push_back(const T &);
void push_back(const T &, bool lockMutex); int push_back(const T &, bool lockMutex);
T& back(); T& back();
void erase(unsigned index); void erase(unsigned index);
@ -160,7 +175,7 @@ struct MutexVector : public NdbLockable {
void clear(); void clear();
void clear(bool lockMutex); void clear(bool lockMutex);
void fill(unsigned new_size, T & obj); int fill(unsigned new_size, T & obj);
private: private:
T * m_items; T * m_items;
unsigned m_size; unsigned m_size;
@ -171,6 +186,14 @@ private:
template<class T> template<class T>
MutexVector<T>::MutexVector(int i){ MutexVector<T>::MutexVector(int i){
m_items = new T[i]; m_items = new T[i];
if (m_items == NULL)
{
errno = ENOMEM;
m_size = 0;
m_arraySize = 0;
m_incSize = 0;
return;
}
m_size = 0; m_size = 0;
m_arraySize = i; m_arraySize = i;
m_incSize = 50; m_incSize = 50;
@ -208,11 +231,17 @@ MutexVector<T>::back(){
} }
template<class T> template<class T>
void int
MutexVector<T>::push_back(const T & t){ MutexVector<T>::push_back(const T & t){
lock(); lock();
if(m_size == m_arraySize){ if(m_size == m_arraySize){
T * tmp = new T [m_arraySize + m_incSize]; T * tmp = new T [m_arraySize + m_incSize];
if (tmp == NULL)
{
errno = ENOMEM;
unlock();
return -1;
}
for (unsigned k = 0; k < m_size; k++) for (unsigned k = 0; k < m_size; k++)
tmp[k] = m_items[k]; tmp[k] = m_items[k];
delete[] m_items; delete[] m_items;
@ -222,15 +251,23 @@ MutexVector<T>::push_back(const T & t){
m_items[m_size] = t; m_items[m_size] = t;
m_size++; m_size++;
unlock(); unlock();
return 0;
} }
template<class T> template<class T>
void int
MutexVector<T>::push_back(const T & t, bool lockMutex){ MutexVector<T>::push_back(const T & t, bool lockMutex){
if(lockMutex) if(lockMutex)
lock(); lock();
if(m_size == m_arraySize){ if(m_size == m_arraySize){
T * tmp = new T [m_arraySize + m_incSize]; T * tmp = new T [m_arraySize + m_incSize];
if (tmp == NULL)
{
errno = ENOMEM;
if(lockMutex)
unlock();
return -1;
}
for (unsigned k = 0; k < m_size; k++) for (unsigned k = 0; k < m_size; k++)
tmp[k] = m_items[k]; tmp[k] = m_items[k];
delete[] m_items; delete[] m_items;
@ -241,6 +278,7 @@ MutexVector<T>::push_back(const T & t, bool lockMutex){
m_size++; m_size++;
if(lockMutex) if(lockMutex)
unlock(); unlock();
return 0;
} }
template<class T> template<class T>
@ -288,10 +326,12 @@ MutexVector<T>::clear(bool l){
} }
template<class T> template<class T>
void int
MutexVector<T>::fill(unsigned new_size, T & obj){ MutexVector<T>::fill(unsigned new_size, T & obj){
while(m_size <= new_size) while(m_size <= new_size)
push_back(obj); if (push_back(obj))
return -1;
return 0;
} }
#endif #endif

View File

@ -16,19 +16,36 @@
/* -*- c-basic-offset: 4; -*- */ /* -*- c-basic-offset: 4; -*- */
#include <ndb_global.h> #include <ndb_global.h>
#include <BaseString.hpp> #include <BaseString.hpp>
#include <basestring_vsnprintf.h> #include "basestring_vsnprintf.h"
BaseString::BaseString() BaseString::BaseString()
{ {
m_chr = new char[1]; m_chr = new char[1];
if (m_chr == NULL)
{
errno = ENOMEM;
m_len = 0;
return;
}
m_chr[0] = 0; m_chr[0] = 0;
m_len = 0; m_len = 0;
} }
BaseString::BaseString(const char* s) BaseString::BaseString(const char* s)
{ {
if (s == NULL)
{
m_chr = NULL;
m_len = 0;
}
const size_t n = strlen(s); const size_t n = strlen(s);
m_chr = new char[n + 1]; m_chr = new char[n + 1];
if (m_chr == NULL)
{
errno = ENOMEM;
m_len = 0;
return;
}
memcpy(m_chr, s, n + 1); memcpy(m_chr, s, n + 1);
m_len = n; m_len = n;
} }
@ -37,7 +54,20 @@ BaseString::BaseString(const BaseString& str)
{ {
const char* const s = str.m_chr; const char* const s = str.m_chr;
const size_t n = str.m_len; const size_t n = str.m_len;
if (s == NULL)
{
m_chr = NULL;
m_len = 0;
return;
}
char* t = new char[n + 1]; char* t = new char[n + 1];
if (t == NULL)
{
errno = ENOMEM;
m_chr = NULL;
m_len = 0;
return;
}
memcpy(t, s, n + 1); memcpy(t, s, n + 1);
m_chr = t; m_chr = t;
m_len = n; m_len = n;
@ -51,9 +81,23 @@ BaseString::~BaseString()
BaseString& BaseString&
BaseString::assign(const char* s) BaseString::assign(const char* s)
{ {
const size_t n = strlen(s); if (s == NULL)
{
m_chr = NULL;
m_len = 0;
return *this;
}
size_t n = strlen(s);
char* t = new char[n + 1]; char* t = new char[n + 1];
if (t)
{
memcpy(t, s, n + 1); memcpy(t, s, n + 1);
}
else
{
errno = ENOMEM;
n = 0;
}
delete[] m_chr; delete[] m_chr;
m_chr = t; m_chr = t;
m_len = n; m_len = n;
@ -64,8 +108,16 @@ BaseString&
BaseString::assign(const char* s, size_t n) BaseString::assign(const char* s, size_t n)
{ {
char* t = new char[n + 1]; char* t = new char[n + 1];
if (t)
{
memcpy(t, s, n); memcpy(t, s, n);
t[n] = 0; t[n] = 0;
}
else
{
errno = ENOMEM;
n = 0;
}
delete[] m_chr; delete[] m_chr;
m_chr = t; m_chr = t;
m_len = n; m_len = n;
@ -83,10 +135,19 @@ BaseString::assign(const BaseString& str, size_t n)
BaseString& BaseString&
BaseString::append(const char* s) BaseString::append(const char* s)
{ {
const size_t n = strlen(s); size_t n = strlen(s);
char* t = new char[m_len + n + 1]; char* t = new char[m_len + n + 1];
if (t)
{
memcpy(t, m_chr, m_len); memcpy(t, m_chr, m_len);
memcpy(t + m_len, s, n + 1); memcpy(t + m_len, s, n + 1);
}
else
{
errno = ENOMEM;
m_len = 0;
n = 0;
}
delete[] m_chr; delete[] m_chr;
m_chr = t; m_chr = t;
m_len += n; m_len += n;
@ -130,8 +191,14 @@ BaseString::assfmt(const char *fmt, ...)
l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
va_end(ap); va_end(ap);
if(l > (int)m_len) { if(l > (int)m_len) {
char *t = new char[l];
if (t == NULL)
{
errno = ENOMEM;
return *this;
}
delete[] m_chr; delete[] m_chr;
m_chr = new char[l]; m_chr = t;
} }
va_start(ap, fmt); va_start(ap, fmt);
basestring_vsnprintf(m_chr, l, fmt, ap); basestring_vsnprintf(m_chr, l, fmt, ap);
@ -155,6 +222,11 @@ BaseString::appfmt(const char *fmt, ...)
l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
va_end(ap); va_end(ap);
char *tmp = new char[l]; char *tmp = new char[l];
if (tmp == NULL)
{
errno = ENOMEM;
return *this;
}
va_start(ap, fmt); va_start(ap, fmt);
basestring_vsnprintf(tmp, l, fmt, ap); basestring_vsnprintf(tmp, l, fmt, ap);
va_end(ap); va_end(ap);
@ -242,9 +314,28 @@ BaseString::argify(const char *argv0, const char *src) {
Vector<char *> vargv; Vector<char *> vargv;
if(argv0 != NULL) if(argv0 != NULL)
vargv.push_back(strdup(argv0)); {
char *t = strdup(argv0);
if (t == NULL)
{
errno = ENOMEM;
return NULL;
}
if (vargv.push_back(t))
{
free(t);
return NULL;
}
}
char *tmp = new char[strlen(src)+1]; char *tmp = new char[strlen(src)+1];
if (tmp == NULL)
{
for(size_t i = 0; i < vargv.size(); i++)
free(vargv[i]);
errno = ENOMEM;
return NULL;
}
char *dst = tmp; char *dst = tmp;
const char *end = src + strlen(src); const char *end = src + strlen(src);
/* Copy characters from src to destination, while compacting them /* Copy characters from src to destination, while compacting them
@ -288,19 +379,47 @@ BaseString::argify(const char *argv0, const char *src) {
*dst++ = '\0'; *dst++ = '\0';
src++; src++;
vargv.push_back(strdup(begin)); {
char *t = strdup(begin);
if (t == NULL)
{
delete[] tmp;
for(size_t i = 0; i < vargv.size(); i++)
free(vargv[i]);
errno = ENOMEM;
return NULL;
}
if (vargv.push_back(t))
{
free(t);
delete[] tmp;
for(size_t i = 0; i < vargv.size(); i++)
free(vargv[i]);
return NULL;
}
}
} }
end: end:
delete[] tmp; delete[] tmp;
vargv.push_back(NULL); if (vargv.push_back(NULL))
{
for(size_t i = 0; i < vargv.size(); i++)
free(vargv[i]);
return NULL;
}
/* Convert the C++ Vector into a C-vector of strings, suitable for /* Convert the C++ Vector into a C-vector of strings, suitable for
* calling execv(). * calling execv().
*/ */
char **argv = (char **)malloc(sizeof(*argv) * (vargv.size())); char **argv = (char **)malloc(sizeof(*argv) * (vargv.size()));
if(argv == NULL) if(argv == NULL)
{
for(size_t i = 0; i < vargv.size(); i++)
free(vargv[i]);
errno = ENOMEM;
return NULL; return NULL;
}
for(size_t i = 0; i < vargv.size(); i++){ for(size_t i = 0; i < vargv.size(); i++){
argv[i] = vargv[i]; argv[i] = vargv[i];

View File

@ -389,6 +389,7 @@ Dbtup::commitRecord(Signal* signal,
fragptr.p = regFragPtr; fragptr.p = regFragPtr;
tabptr.p = regTabPtr; tabptr.p = regTabPtr;
Uint32 hashValue = firstOpPtr.p->hashValue;
if (opType == ZINSERT_DELETE) { if (opType == ZINSERT_DELETE) {
ljam(); ljam();
@ -411,6 +412,7 @@ Dbtup::commitRecord(Signal* signal,
//-------------------------------------------------------------------- //--------------------------------------------------------------------
Uint32 saveOpType = regOperPtr->optype; Uint32 saveOpType = regOperPtr->optype;
regOperPtr->optype = ZINSERT; regOperPtr->optype = ZINSERT;
regOperPtr->hashValue = hashValue;
operPtr.p = regOperPtr; operPtr.p = regOperPtr;
checkDetachedTriggers(signal, checkDetachedTriggers(signal,
@ -443,6 +445,8 @@ Dbtup::commitRecord(Signal* signal,
befOpPtr.p->changeMask.clear(); befOpPtr.p->changeMask.clear();
befOpPtr.p->changeMask.bitOR(attributeMask); befOpPtr.p->changeMask.bitOR(attributeMask);
befOpPtr.p->gci = regOperPtr->gci; befOpPtr.p->gci = regOperPtr->gci;
befOpPtr.p->optype = ZUPDATE;
befOpPtr.p->hashValue = hashValue;
befOpPtr.p->optype = opType; befOpPtr.p->optype = opType;
operPtr.p = befOpPtr.p; operPtr.p = befOpPtr.p;
@ -477,11 +481,13 @@ Dbtup::commitRecord(Signal* signal,
Uint32 fragPageId = befOpPtr.p->fragPageId; Uint32 fragPageId = befOpPtr.p->fragPageId;
Uint32 pageIndex = befOpPtr.p->pageIndex; Uint32 pageIndex = befOpPtr.p->pageIndex;
befOpPtr.p->optype = ZDELETE;
befOpPtr.p->realPageId = befOpPtr.p->realPageIdC; befOpPtr.p->realPageId = befOpPtr.p->realPageIdC;
befOpPtr.p->pageOffset = befOpPtr.p->pageOffsetC; befOpPtr.p->pageOffset = befOpPtr.p->pageOffsetC;
befOpPtr.p->fragPageId = befOpPtr.p->fragPageIdC; befOpPtr.p->fragPageId = befOpPtr.p->fragPageIdC;
befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC; befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC;
befOpPtr.p->gci = regOperPtr->gci; befOpPtr.p->gci = regOperPtr->gci;
befOpPtr.p->hashValue = hashValue;
befOpPtr.p->optype = opType; befOpPtr.p->optype = opType;
operPtr.p = befOpPtr.p; operPtr.p = befOpPtr.p;

View File

@ -141,7 +141,7 @@ void GlobalDictCache::printCache()
} }
NdbTableImpl * NdbTableImpl *
GlobalDictCache::get(const char * name) GlobalDictCache::get(const char * name, int *error)
{ {
DBUG_ENTER("GlobalDictCache::get"); DBUG_ENTER("GlobalDictCache::get");
DBUG_PRINT("enter", ("name: %s", name)); DBUG_PRINT("enter", ("name: %s", name));
@ -151,6 +151,11 @@ GlobalDictCache::get(const char * name)
versions = m_tableHash.getData(name, len); versions = m_tableHash.getData(name, len);
if(versions == 0){ if(versions == 0){
versions = new Vector<TableVersion>(2); versions = new Vector<TableVersion>(2);
if (versions == NULL)
{
*error = -1;
DBUG_RETURN(0);
}
m_tableHash.insertKey(name, len, 0, versions); m_tableHash.insertKey(name, len, 0, versions);
} }
@ -180,7 +185,11 @@ GlobalDictCache::get(const char * name)
tmp.m_impl = 0; tmp.m_impl = 0;
tmp.m_status = RETREIVING; tmp.m_status = RETREIVING;
tmp.m_refCount = 1; // The one retreiving it tmp.m_refCount = 1; // The one retreiving it
versions->push_back(tmp); if (versions->push_back(tmp))
{
*error = -1;
DBUG_RETURN(0);
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View File

@ -67,7 +67,7 @@ public:
GlobalDictCache(); GlobalDictCache();
~GlobalDictCache(); ~GlobalDictCache();
NdbTableImpl * get(const char * name); NdbTableImpl * get(const char * name, int *error);
NdbTableImpl* put(const char * name, NdbTableImpl *); NdbTableImpl* put(const char * name, NdbTableImpl *);
void drop(NdbTableImpl *); void drop(NdbTableImpl *);

View File

@ -48,7 +48,8 @@ libndbapi_la_SOURCES = \
DictCache.cpp \ DictCache.cpp \
ndb_cluster_connection.cpp \ ndb_cluster_connection.cpp \
NdbBlob.cpp \ NdbBlob.cpp \
SignalSender.cpp SignalSender.cpp \
ObjectMap.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmapi INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmapi

View File

@ -182,6 +182,7 @@ Ndb::NDB_connect(Uint32 tNode)
nodeSequence = tp->getNodeSequence(tNode); nodeSequence = tp->getNodeSequence(tNode);
bool node_is_alive = tp->get_node_alive(tNode); bool node_is_alive = tp->get_node_alive(tNode);
if (node_is_alive) { if (node_is_alive) {
DBUG_PRINT("info",("Sending signal to node %u", tNode));
tReturnCode = tp->sendSignal(tSignal, tNode); tReturnCode = tp->sendSignal(tSignal, tNode);
releaseSignal(tSignal); releaseSignal(tSignal);
if (tReturnCode != -1) { if (tReturnCode != -1) {
@ -449,7 +450,11 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId)
theRemainingStartTransactions--; theRemainingStartTransactions--;
NdbTransaction* tConNext = theTransactionList; NdbTransaction* tConNext = theTransactionList;
tConnection->init(); if (tConnection->init())
{
theError.code = tConnection->theError.code;
DBUG_RETURN(NULL);
}
theTransactionList = tConnection; // into a transaction list. theTransactionList = tConnection; // into a transaction list.
tConnection->next(tConNext); // Add the active connection object tConnection->next(tConNext); // Add the active connection object
tConnection->setTransactionId(tFirstTransId); tConnection->setTransactionId(tFirstTransId);
@ -1129,15 +1134,19 @@ const char * Ndb::getCatalogName() const
} }
void Ndb::setCatalogName(const char * a_catalog_name) int Ndb::setCatalogName(const char * a_catalog_name)
{ {
if (a_catalog_name) if (a_catalog_name)
{ {
theImpl->m_dbname.assign(a_catalog_name); if (!theImpl->m_dbname.assign(a_catalog_name) ||
theImpl->update_prefix(); theImpl->update_prefix())
{
theError.code = 4000;
return -1;
} }
} }
return 0;
}
const char * Ndb::getSchemaName() const const char * Ndb::getSchemaName() const
{ {
@ -1145,13 +1154,18 @@ const char * Ndb::getSchemaName() const
} }
void Ndb::setSchemaName(const char * a_schema_name) int Ndb::setSchemaName(const char * a_schema_name)
{ {
if (a_schema_name) { if (a_schema_name) {
theImpl->m_schemaname.assign(a_schema_name); if (!theImpl->m_schemaname.assign(a_schema_name) ||
theImpl->update_prefix(); theImpl->update_prefix())
{
theError.code = 4000;
return -1;
} }
} }
return 0;
}
/* /*
Deprecated functions Deprecated functions
@ -1161,9 +1175,9 @@ const char * Ndb::getDatabaseName() const
return getCatalogName(); return getCatalogName();
} }
void Ndb::setDatabaseName(const char * a_catalog_name) int Ndb::setDatabaseName(const char * a_catalog_name)
{ {
setCatalogName(a_catalog_name); return setCatalogName(a_catalog_name);
} }
const char * Ndb::getDatabaseSchemaName() const const char * Ndb::getDatabaseSchemaName() const
@ -1171,9 +1185,9 @@ const char * Ndb::getDatabaseSchemaName() const
return getSchemaName(); return getSchemaName();
} }
void Ndb::setDatabaseSchemaName(const char * a_schema_name) int Ndb::setDatabaseSchemaName(const char * a_schema_name)
{ {
setSchemaName(a_schema_name); return setSchemaName(a_schema_name);
} }
bool Ndb::usingFullyQualifiedNames() bool Ndb::usingFullyQualifiedNames()
@ -1287,6 +1301,11 @@ const BaseString
Ndb::getDatabaseFromInternalName(const char * internalName) Ndb::getDatabaseFromInternalName(const char * internalName)
{ {
char * databaseName = new char[strlen(internalName) + 1]; char * databaseName = new char[strlen(internalName) + 1];
if (databaseName == NULL)
{
errno = ENOMEM;
return BaseString(NULL);
}
strcpy(databaseName, internalName); strcpy(databaseName, internalName);
register char *ptr = databaseName; register char *ptr = databaseName;
@ -1303,6 +1322,11 @@ const BaseString
Ndb::getSchemaFromInternalName(const char * internalName) Ndb::getSchemaFromInternalName(const char * internalName)
{ {
char * schemaName = new char[strlen(internalName)]; char * schemaName = new char[strlen(internalName)];
if (schemaName == NULL)
{
errno = ENOMEM;
return BaseString(NULL);
}
register const char *ptr1 = internalName; register const char *ptr1 = internalName;
/* Scan name for the second table_name_separator */ /* Scan name for the second table_name_separator */

View File

@ -52,9 +52,9 @@ NdbDictionary::Column::operator=(const NdbDictionary::Column& column)
return *this; return *this;
} }
void int
NdbDictionary::Column::setName(const char * name){ NdbDictionary::Column::setName(const char * name){
m_impl.m_name.assign(name); return !m_impl.m_name.assign(name);
} }
const char* const char*
@ -208,10 +208,10 @@ NdbDictionary::Column::setAutoIncrementInitialValue(Uint64 val){
m_impl.m_autoIncrementInitialValue = val; m_impl.m_autoIncrementInitialValue = val;
} }
void int
NdbDictionary::Column::setDefaultValue(const char* defaultValue) NdbDictionary::Column::setDefaultValue(const char* defaultValue)
{ {
m_impl.m_defaultValue.assign(defaultValue); return !m_impl.m_defaultValue.assign(defaultValue);
} }
const char* const char*
@ -273,9 +273,9 @@ NdbDictionary::Table::operator=(const NdbDictionary::Table& table)
return *this; return *this;
} }
void int
NdbDictionary::Table::setName(const char * name){ NdbDictionary::Table::setName(const char * name){
m_impl.setName(name); return m_impl.setName(name);
} }
const char * const char *
@ -288,18 +288,30 @@ NdbDictionary::Table::getTableId() const {
return m_impl.m_tableId; return m_impl.m_tableId;
} }
void int
NdbDictionary::Table::addColumn(const Column & c){ NdbDictionary::Table::addColumn(const Column & c){
NdbColumnImpl* col = new NdbColumnImpl; NdbColumnImpl* col = new NdbColumnImpl;
if (col == NULL)
{
errno = ENOMEM;
return -1;
}
(* col) = NdbColumnImpl::getImpl(c); (* col) = NdbColumnImpl::getImpl(c);
m_impl.m_columns.push_back(col); if (m_impl.m_columns.push_back(col))
{
return -1;
}
if(c.getPrimaryKey()){ if(c.getPrimaryKey()){
m_impl.m_noOfKeys++; m_impl.m_noOfKeys++;
} }
if (col->getBlobType()) { if (col->getBlobType()) {
m_impl.m_noOfBlobs++; m_impl.m_noOfBlobs++;
} }
m_impl.buildColumnHash(); if (m_impl.buildColumnHash())
{
return -1;
}
return 0;
} }
const NdbDictionary::Column* const NdbDictionary::Column*
@ -442,9 +454,9 @@ NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMod
m_impl.m_single_user_mode = (Uint8)mode; m_impl.m_single_user_mode = (Uint8)mode;
} }
void int
NdbDictionary::Table::setFrm(const void* data, Uint32 len){ NdbDictionary::Table::setFrm(const void* data, Uint32 len){
m_impl.m_frm.assign(data, len); return m_impl.m_frm.assign(data, len);
} }
NdbDictionary::Object::Status NdbDictionary::Object::Status
@ -491,6 +503,7 @@ NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const {
/***************************************************************** /*****************************************************************
* Index facade * Index facade
*/ */
NdbDictionary::Index::Index(const char * name) NdbDictionary::Index::Index(const char * name)
: m_impl(* new NdbIndexImpl(* this)) : m_impl(* new NdbIndexImpl(* this))
{ {
@ -509,9 +522,9 @@ NdbDictionary::Index::~Index(){
} }
} }
void int
NdbDictionary::Index::setName(const char * name){ NdbDictionary::Index::setName(const char * name){
m_impl.setName(name); return m_impl.setName(name);
} }
const char * const char *
@ -519,9 +532,9 @@ NdbDictionary::Index::getName() const {
return m_impl.getName(); return m_impl.getName();
} }
void int
NdbDictionary::Index::setTable(const char * table){ NdbDictionary::Index::setTable(const char * table){
m_impl.setTable(table); return m_impl.setTable(table);
} }
const char * const char *
@ -556,40 +569,57 @@ NdbDictionary::Index::getIndexColumn(int no) const {
return NULL; return NULL;
} }
void int
NdbDictionary::Index::addColumn(const Column & c){ NdbDictionary::Index::addColumn(const Column & c){
NdbColumnImpl* col = new NdbColumnImpl; NdbColumnImpl* col = new NdbColumnImpl;
if (col == NULL)
{
errno = ENOMEM;
return -1;
}
(* col) = NdbColumnImpl::getImpl(c); (* col) = NdbColumnImpl::getImpl(c);
m_impl.m_columns.push_back(col); if (m_impl.m_columns.push_back(col))
{
return -1;
}
return 0;
} }
void int
NdbDictionary::Index::addColumnName(const char * name){ NdbDictionary::Index::addColumnName(const char * name){
const Column c(name); const Column c(name);
addColumn(c); return addColumn(c);
} }
void int
NdbDictionary::Index::addIndexColumn(const char * name){ NdbDictionary::Index::addIndexColumn(const char * name){
const Column c(name); const Column c(name);
addColumn(c); return addColumn(c);
} }
void int
NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){ NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){
for(unsigned i = 0; i < noOfNames; i++) { for(unsigned i = 0; i < noOfNames; i++) {
const Column c(names[i]); const Column c(names[i]);
addColumn(c); if (addColumn(c))
{
return -1;
} }
} }
return 0;
}
void int
NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){ NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){
for(int i = 0; i < noOfNames; i++) { for(int i = 0; i < noOfNames; i++) {
const Column c(names[i]); const Column c(names[i]);
addColumn(c); if (addColumn(c))
{
return -1;
} }
} }
return 0;
}
void void
NdbDictionary::Index::setType(NdbDictionary::Index::Type t){ NdbDictionary::Index::setType(NdbDictionary::Index::Type t){

View File

@ -390,22 +390,34 @@ NdbTableImpl::equal(const NdbTableImpl& obj) const
DBUG_RETURN(true); DBUG_RETURN(true);
} }
void int
NdbTableImpl::assign(const NdbTableImpl& org) NdbTableImpl::assign(const NdbTableImpl& org)
{ {
m_tableId = org.m_tableId; m_tableId = org.m_tableId;
m_internalName.assign(org.m_internalName); if (!m_internalName.assign(org.m_internalName) ||
m_externalName.assign(org.m_externalName); !m_externalName.assign(org.m_externalName) ||
m_newExternalName.assign(org.m_newExternalName); !m_newExternalName.assign(org.m_newExternalName) ||
m_frm.assign(org.m_frm.get_data(), org.m_frm.length()); m_frm.assign(org.m_frm.get_data(), org.m_frm.length()))
{
return -1;
}
m_fragmentType = org.m_fragmentType; m_fragmentType = org.m_fragmentType;
m_fragmentCount = org.m_fragmentCount; m_fragmentCount = org.m_fragmentCount;
for(unsigned i = 0; i<org.m_columns.size(); i++){ for(unsigned i = 0; i<org.m_columns.size(); i++){
NdbColumnImpl * col = new NdbColumnImpl(); NdbColumnImpl * col = new NdbColumnImpl();
if (col == NULL)
{
errno = ENOMEM;
return -1;
}
const NdbColumnImpl * iorg = org.m_columns[i]; const NdbColumnImpl * iorg = org.m_columns[i];
(* col) = (* iorg); (* col) = (* iorg);
m_columns.push_back(col); if (m_columns.push_back(col))
{
delete col;
return -1;
}
} }
m_logging = org.m_logging; m_logging = org.m_logging;
@ -428,11 +440,13 @@ NdbTableImpl::assign(const NdbTableImpl& org)
m_max_rows = org.m_max_rows; m_max_rows = org.m_max_rows;
m_min_rows = org.m_min_rows; m_min_rows = org.m_min_rows;
return 0;
} }
void NdbTableImpl::setName(const char * name) int NdbTableImpl::setName(const char * name)
{ {
m_newExternalName.assign(name); return !m_newExternalName.assign(name);
} }
const char * const char *
@ -445,7 +459,7 @@ NdbTableImpl::getName() const
} }
void int
NdbTableImpl::buildColumnHash(){ NdbTableImpl::buildColumnHash(){
const Uint32 size = m_columns.size(); const Uint32 size = m_columns.size();
@ -458,19 +472,29 @@ NdbTableImpl::buildColumnHash(){
} }
Vector<Uint32> hashValues; Vector<Uint32> hashValues;
Vector<Vector<Uint32> > chains; chains.fill(size, hashValues); Vector<Vector<Uint32> > chains;
if (chains.fill(size, hashValues))
{
return -1;
}
for(i = 0; i< (int) size; i++){ for(i = 0; i< (int) size; i++){
Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE; Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE;
Uint32 bucket = hv & m_columnHashMask; Uint32 bucket = hv & m_columnHashMask;
bucket = (bucket < size ? bucket : bucket - size); bucket = (bucket < size ? bucket : bucket - size);
assert(bucket < size); assert(bucket < size);
hashValues.push_back(hv); if (hashValues.push_back(hv) ||
chains[bucket].push_back(i); chains[bucket].push_back(i))
{
return -1;
}
} }
m_columnHash.clear(); m_columnHash.clear();
Uint32 tmp = 1; Uint32 tmp = 1;
m_columnHash.fill((unsigned)size-1, tmp); // Default no chaining if (m_columnHash.fill((unsigned)size-1, tmp)) // Default no chaining
{
return -1;
}
Uint32 pos = 0; // In overflow vector Uint32 pos = 0; // In overflow vector
for(i = 0; i< (int) size; i++){ for(i = 0; i< (int) size; i++){
@ -490,12 +514,18 @@ NdbTableImpl::buildColumnHash(){
for(size_t j = 0; j<sz; j++, pos++){ for(size_t j = 0; j<sz; j++, pos++){
Uint32 col = chains[i][j]; Uint32 col = chains[i][j];
Uint32 hv = hashValues[col]; Uint32 hv = hashValues[col];
m_columnHash.push_back((col << 16) | hv); if (m_columnHash.push_back((col << 16) | hv))
{
return -1;
}
} }
} }
} }
m_columnHash.push_back(0); // Overflow when looping in end of array if (m_columnHash.push_back(0)) // Overflow when looping in end of array
{
return -1;
}
#if 0 #if 0
for(size_t i = 0; i<m_columnHash.size(); i++){ for(size_t i = 0; i<m_columnHash.size(); i++){
@ -510,6 +540,7 @@ NdbTableImpl::buildColumnHash(){
i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]); i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]);
} }
#endif #endif
return 0;
} }
Uint32 Uint32
@ -563,9 +594,9 @@ NdbIndexImpl::~NdbIndexImpl(){
delete m_columns[i]; delete m_columns[i];
} }
void NdbIndexImpl::setName(const char * name) int NdbIndexImpl::setName(const char * name)
{ {
m_externalName.assign(name); return !m_externalName.assign(name);
} }
const char * const char *
@ -574,10 +605,10 @@ NdbIndexImpl::getName() const
return m_externalName.c_str(); return m_externalName.c_str();
} }
void int
NdbIndexImpl::setTable(const char * table) NdbIndexImpl::setTable(const char * table)
{ {
m_tableName.assign(table); return !m_tableName.assign(table);
} }
const char * const char *
@ -657,14 +688,18 @@ Ndb_local_table_info *
NdbDictionaryImpl::fetchGlobalTableImpl(const BaseString& internalTableName) NdbDictionaryImpl::fetchGlobalTableImpl(const BaseString& internalTableName)
{ {
NdbTableImpl *impl; NdbTableImpl *impl;
int error= 0;
m_globalHash->lock(); m_globalHash->lock();
impl = m_globalHash->get(internalTableName.c_str()); impl = m_globalHash->get(internalTableName.c_str(), &error);
m_globalHash->unlock(); m_globalHash->unlock();
if (impl == 0){ if (impl == 0){
if (error == 0)
impl = m_receiver.getTable(internalTableName, impl = m_receiver.getTable(internalTableName,
m_ndb.usingFullyQualifiedNames()); m_ndb.usingFullyQualifiedNames());
else
m_error.code = 4000;
m_globalHash->lock(); m_globalHash->lock();
m_globalHash->put(internalTableName.c_str(), impl); m_globalHash->put(internalTableName.c_str(), impl);
m_globalHash->unlock(); m_globalHash->unlock();
@ -998,12 +1033,20 @@ NdbDictInterface::getTable(const BaseString& name, bool fullyQualifiedNames)
// Copy name to m_buffer to get a word sized buffer // Copy name to m_buffer to get a word sized buffer
m_buffer.clear(); m_buffer.clear();
m_buffer.grow(namelen_words*4+4); if (m_buffer.grow(namelen_words*4+4) ||
m_buffer.append(name.c_str(), namelen); m_buffer.append(name.c_str(), namelen))
{
m_error.code= 4000;
return NULL;
}
#ifndef IGNORE_VALGRIND_WARNINGS #ifndef IGNORE_VALGRIND_WARNINGS
Uint32 pad = 0; Uint32 pad = 0;
m_buffer.append(&pad, 4); if (m_buffer.append(&pad, 4))
{
m_error.code= 4000;
return NULL;
}
#endif #endif
LinearSectionPtr ptr[1]; LinearSectionPtr ptr[1];
@ -1034,7 +1077,14 @@ NdbDictInterface::getTable(class NdbApiSignal * signal,
(Uint32*)m_buffer.get_data(), (Uint32*)m_buffer.get_data(),
m_buffer.length() / 4, fullyQualifiedNames); m_buffer.length() / 4, fullyQualifiedNames);
if (rt != 0) if (rt != 0)
rt->buildColumnHash(); {
if (rt->buildColumnHash())
{
m_error.code = 4000;
delete rt;
return NULL;
}
}
return rt; return rt;
} }
@ -1043,18 +1093,25 @@ NdbDictInterface::execGET_TABINFO_CONF(NdbApiSignal * signal,
LinearSectionPtr ptr[3]) LinearSectionPtr ptr[3])
{ {
const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr()); const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr());
const Uint32 i = GetTabInfoConf::DICT_TAB_INFO;
if(signal->isFirstFragment()){ if(signal->isFirstFragment()){
m_fragmentId = signal->getFragmentId(); m_fragmentId = signal->getFragmentId();
m_buffer.grow(4 * conf->totalLen); if (m_buffer.grow(4 * conf->totalLen))
{
m_error.code= 4000;
goto end;
}
} else { } else {
if(m_fragmentId != signal->getFragmentId()){ if(m_fragmentId != signal->getFragmentId()){
abort(); abort();
} }
} }
const Uint32 i = GetTabInfoConf::DICT_TAB_INFO; if (m_buffer.append(ptr[i].p, 4 * ptr[i].sz))
m_buffer.append(ptr[i].p, 4 * ptr[i].sz); {
m_error.code= 4000;
}
end:
if(!signal->isLastFragment()){ if(!signal->isLastFragment()){
return; return;
} }
@ -1185,10 +1242,12 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
impl->m_tableId = tableDesc.TableId; impl->m_tableId = tableDesc.TableId;
impl->m_version = tableDesc.TableVersion; impl->m_version = tableDesc.TableVersion;
impl->m_status = NdbDictionary::Object::Retrieved; impl->m_status = NdbDictionary::Object::Retrieved;
impl->m_internalName.assign(internalName); if (!impl->m_internalName.assign(internalName) ||
impl->m_externalName.assign(externalName); !impl->m_externalName.assign(externalName) ||
impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen))
impl->m_frm.assign(tableDesc.FrmData, tableDesc.FrmLen); {
DBUG_RETURN(4000);
}
impl->m_fragmentType = (NdbDictionary::Object::FragmentType) impl->m_fragmentType = (NdbDictionary::Object::FragmentType)
getApiConstant(tableDesc.FragmentType, getApiConstant(tableDesc.FragmentType,
@ -1216,7 +1275,10 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
} else { } else {
const char * externalPrimary = const char * externalPrimary =
Ndb::externalizeTableName(tableDesc.PrimaryTable, fullyQualifiedNames); Ndb::externalizeTableName(tableDesc.PrimaryTable, fullyQualifiedNames);
impl->m_primaryTable.assign(externalPrimary); if (!impl->m_primaryTable.assign(externalPrimary))
{
DBUG_RETURN(4000);
}
} }
Uint32 keyInfoPos = 0; Uint32 keyInfoPos = 0;
@ -1243,6 +1305,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
// check type and compute attribute size and array size // check type and compute attribute size and array size
if (! attrDesc.translateExtType()) { if (! attrDesc.translateExtType()) {
delete col;
delete impl; delete impl;
DBUG_RETURN(703); DBUG_RETURN(703);
} }
@ -1254,12 +1317,14 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16); unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16);
// charset is defined exactly for char types // charset is defined exactly for char types
if (col->getCharType() != (cs_number != 0)) { if (col->getCharType() != (cs_number != 0)) {
delete col;
delete impl; delete impl;
DBUG_RETURN(703); DBUG_RETURN(703);
} }
if (col->getCharType()) { if (col->getCharType()) {
col->m_cs = get_charset(cs_number, MYF(0)); col->m_cs = get_charset(cs_number, MYF(0));
if (col->m_cs == NULL) { if (col->m_cs == NULL) {
delete col;
delete impl; delete impl;
DBUG_RETURN(743); DBUG_RETURN(743);
} }
@ -1277,7 +1342,12 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
col->m_nullable = attrDesc.AttributeNullableFlag; col->m_nullable = attrDesc.AttributeNullableFlag;
col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false); col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false);
col->m_autoIncrementInitialValue = ~0; col->m_autoIncrementInitialValue = ~0;
col->m_defaultValue.assign(attrDesc.AttributeDefaultValue); if (!col->m_defaultValue.assign(attrDesc.AttributeDefaultValue))
{
delete col;
delete impl;
DBUG_RETURN(4000);
}
if(attrDesc.AttributeKeyFlag){ if(attrDesc.AttributeKeyFlag){
col->m_keyInfoPos = keyInfoPos + 1; col->m_keyInfoPos = keyInfoPos + 1;
@ -1317,7 +1387,11 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
for(i = 0; i<(fragCount*replicaCount); i++) for(i = 0; i<(fragCount*replicaCount); i++)
{ {
impl->m_fragments.push_back(tableDesc.FragmentData[i+2]); if (impl->m_fragments.push_back(tableDesc.FragmentData[i+2]))
{
delete impl;
DBUG_RETURN(4000);
}
} }
Uint32 topBit = (1 << 31); Uint32 topBit = (1 << 31);
@ -1481,7 +1555,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
} }
if (!impl.m_newExternalName.empty()) { if (!impl.m_newExternalName.empty()) {
impl.m_externalName.assign(impl.m_newExternalName); if (!impl.m_externalName.assign(impl.m_newExternalName))
{
m_error.code= 4000;
DBUG_RETURN(-1);
}
AlterTableReq::setNameFlag(impl.m_changeMask, true); AlterTableReq::setNameFlag(impl.m_changeMask, true);
} }
@ -1490,7 +1568,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
const BaseString internalName( const BaseString internalName(
ndb.internalize_table_name(impl.m_externalName.c_str())); ndb.internalize_table_name(impl.m_externalName.c_str()));
impl.m_internalName.assign(internalName); if (!impl.m_internalName.assign(internalName))
{
m_error.code= 4000;
DBUG_RETURN(-1);
}
UtilBufferWriter w(m_buffer); UtilBufferWriter w(m_buffer);
DictTabInfo::Table tmpTab; tmpTab.init(); DictTabInfo::Table tmpTab; tmpTab.init();
BaseString::snprintf(tmpTab.TableName, BaseString::snprintf(tmpTab.TableName,
@ -1967,13 +2049,19 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName,
NdbIndexImpl* idx; NdbIndexImpl* idx;
if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){ if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){
idx->m_table = tab; idx->m_table = tab;
idx->m_externalName.assign(externalName); if (!idx->m_externalName.assign(externalName) ||
idx->m_internalName.assign(internalName); !idx->m_internalName.assign(internalName))
{
delete idx;
m_error.code = 4000;
return 0;
}
// TODO Assign idx to tab->m_index // TODO Assign idx to tab->m_index
// Don't do it right now since assign can't asign a table with index // Don't do it right now since assign can't asign a table with index
// tab->m_index = idx; // tab->m_index = idx;
return idx; return idx;
} }
m_error.code = 4000;
return 0; return 0;
} }
@ -1982,11 +2070,21 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
NdbTableImpl* tab, NdbTableImpl* tab,
const NdbTableImpl* prim){ const NdbTableImpl* prim){
NdbIndexImpl *idx = new NdbIndexImpl(); NdbIndexImpl *idx = new NdbIndexImpl();
if (idx == NULL)
{
errno = ENOMEM;
return -1;
}
idx->m_version = tab->m_version; idx->m_version = tab->m_version;
idx->m_status = tab->m_status; idx->m_status = tab->m_status;
idx->m_indexId = tab->m_tableId; idx->m_indexId = tab->m_tableId;
idx->m_externalName.assign(tab->getName()); if (!idx->m_externalName.assign(tab->getName()) ||
idx->m_tableName.assign(prim->m_externalName); !idx->m_tableName.assign(prim->m_externalName))
{
delete idx;
errno = ENOMEM;
return -1;
}
NdbDictionary::Index::Type type = idx->m_type = tab->m_indexType; NdbDictionary::Index::Type type = idx->m_type = tab->m_indexType;
idx->m_logging = tab->m_logging; idx->m_logging = tab->m_logging;
// skip last attribute (NDB$PK or NDB$TNODE) // skip last attribute (NDB$PK or NDB$TNODE)
@ -1999,9 +2097,20 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
NdbColumnImpl* org = tab->m_columns[i]; NdbColumnImpl* org = tab->m_columns[i];
NdbColumnImpl* col = new NdbColumnImpl; NdbColumnImpl* col = new NdbColumnImpl;
if (col == NULL)
{
errno = ENOMEM;
delete idx;
return -1;
}
// Copy column definition // Copy column definition
*col = * org; *col = * org;
idx->m_columns.push_back(col); if (idx->m_columns.push_back(col))
{
delete col;
delete idx;
return -1;
}
/** /**
* reverse map * reverse map
@ -2067,7 +2176,11 @@ NdbDictInterface::createIndex(Ndb & ndb,
} }
const BaseString internalName( const BaseString internalName(
ndb.internalize_index_name(&table, impl.getName())); ndb.internalize_index_name(&table, impl.getName()));
impl.m_internalName.assign(internalName); if (!impl.m_internalName.assign(internalName))
{
m_error.code = 4000;
return -1;
}
w.add(DictTabInfo::TableName, internalName.c_str()); w.add(DictTabInfo::TableName, internalName.c_str());
w.add(DictTabInfo::TableLoggedFlag, impl.m_logging); w.add(DictTabInfo::TableLoggedFlag, impl.m_logging);
@ -2353,34 +2466,72 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
BaseString databaseName; BaseString databaseName;
BaseString schemaName; BaseString schemaName;
BaseString objectName; BaseString objectName;
if (!databaseName || !schemaName || !objectName)
{
m_error.code= 4000;
return -1;
}
if ((element.type == NdbDictionary::Object::UniqueHashIndex) || if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
(element.type == NdbDictionary::Object::OrderedIndex)) { (element.type == NdbDictionary::Object::OrderedIndex)) {
char * indexName = new char[n << 2]; char * indexName = new char[n << 2];
if (indexName == NULL)
{
m_error.code= 4000;
return -1;
}
memcpy(indexName, &data[pos], n << 2); memcpy(indexName, &data[pos], n << 2);
databaseName = Ndb::getDatabaseFromInternalName(indexName); if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) ||
schemaName = Ndb::getSchemaFromInternalName(indexName); !(schemaName = Ndb::getSchemaFromInternalName(indexName)))
{
delete [] indexName;
m_error.code= 4000;
return -1;
}
objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames)); objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames));
delete [] indexName; delete [] indexName;
} else if ((element.type == NdbDictionary::Object::SystemTable) || } else if ((element.type == NdbDictionary::Object::SystemTable) ||
(element.type == NdbDictionary::Object::UserTable)) { (element.type == NdbDictionary::Object::UserTable)) {
char * tableName = new char[n << 2]; char * tableName = new char[n << 2];
if (tableName == NULL)
{
m_error.code= 4000;
return -1;
}
memcpy(tableName, &data[pos], n << 2); memcpy(tableName, &data[pos], n << 2);
databaseName = Ndb::getDatabaseFromInternalName(tableName); if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) ||
schemaName = Ndb::getSchemaFromInternalName(tableName); !(schemaName = Ndb::getSchemaFromInternalName(tableName)))
{
delete [] tableName;
m_error.code= 4000;
return -1;
}
objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames)); objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames));
delete [] tableName; delete [] tableName;
} }
else { else {
char * otherName = new char[n << 2]; char * otherName = new char[n << 2];
if (otherName == NULL)
{
m_error.code= 4000;
return -1;
}
memcpy(otherName, &data[pos], n << 2); memcpy(otherName, &data[pos], n << 2);
objectName = BaseString(otherName); if (!(objectName = BaseString(otherName)))
{
m_error.code= 4000;
return -1;
}
delete [] otherName; delete [] otherName;
} }
element.database = new char[databaseName.length() + 1]; if (!(element.database = new char[databaseName.length() + 1]) ||
!(element.schema = new char[schemaName.length() + 1]) ||
!(element.name = new char[objectName.length() + 1]))
{
m_error.code= 4000;
return -1;
}
strcpy(element.database, databaseName.c_str()); strcpy(element.database, databaseName.c_str());
element.schema = new char[schemaName.length() + 1];
strcpy(element.schema, schemaName.c_str()); strcpy(element.schema, schemaName.c_str());
element.name = new char[objectName.length() + 1];
strcpy(element.name, objectName.c_str()); strcpy(element.name, objectName.c_str());
pos += n; pos += n;
count++; count++;
@ -2427,7 +2578,10 @@ NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal,
{ {
const unsigned off = ListTablesConf::HeaderLength; const unsigned off = ListTablesConf::HeaderLength;
const unsigned len = (signal->getLength() - off); const unsigned len = (signal->getLength() - off);
m_buffer.append(signal->getDataPtr() + off, len << 2); if (m_buffer.append(signal->getDataPtr() + off, len << 2))
{
m_error.code= 4000;
}
if (signal->getLength() < ListTablesConf::SignalLength) { if (signal->getLength() < ListTablesConf::SignalLength) {
// last signal has less than full length // last signal has less than full length
m_waiter.signal(NO_WAIT); m_waiter.signal(NO_WAIT);

View File

@ -103,7 +103,7 @@ public:
~NdbTableImpl(); ~NdbTableImpl();
void init(); void init();
void setName(const char * name); int setName(const char * name);
const char * getName() const; const char * getName() const;
Uint32 m_changeMask; Uint32 m_changeMask;
@ -120,7 +120,7 @@ public:
Uint32 m_columnHashMask; Uint32 m_columnHashMask;
Vector<Uint32> m_columnHash; Vector<Uint32> m_columnHash;
Vector<NdbColumnImpl *> m_columns; Vector<NdbColumnImpl *> m_columns;
void buildColumnHash(); int buildColumnHash();
/** /**
* Fragment info * Fragment info
@ -166,7 +166,7 @@ public:
* Equality/assign * Equality/assign
*/ */
bool equal(const NdbTableImpl&) const; bool equal(const NdbTableImpl&) const;
void assign(const NdbTableImpl&); int assign(const NdbTableImpl&);
static NdbTableImpl & getImpl(NdbDictionary::Table & t); static NdbTableImpl & getImpl(NdbDictionary::Table & t);
static NdbTableImpl & getImpl(const NdbDictionary::Table & t); static NdbTableImpl & getImpl(const NdbDictionary::Table & t);
@ -185,9 +185,9 @@ public:
~NdbIndexImpl(); ~NdbIndexImpl();
void init(); void init();
void setName(const char * name); int setName(const char * name);
const char * getName() const; const char * getName() const;
void setTable(const char * table); int setTable(const char * table);
const char * getTable() const; const char * getTable() const;
const NdbTableImpl * getIndexTable() const; const NdbTableImpl * getIndexTable() const;

View File

@ -37,7 +37,7 @@ struct Ndb_free_list_t
Ndb_free_list_t(); Ndb_free_list_t();
~Ndb_free_list_t(); ~Ndb_free_list_t();
void fill(Ndb*, Uint32 cnt); int fill(Ndb*, Uint32 cnt);
T* seize(Ndb*); T* seize(Ndb*);
void release(T*); void release(T*);
void clear(); void clear();
@ -79,10 +79,14 @@ public:
BaseString m_prefix; // Buffer for preformatted internal name <db>/<schema>/ BaseString m_prefix; // Buffer for preformatted internal name <db>/<schema>/
void update_prefix() int update_prefix()
{ {
m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator, if (!m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator,
m_schemaname.c_str(), table_name_separator); m_schemaname.c_str(), table_name_separator))
{
return -1;
}
return 0;
} }
/** /**
@ -194,7 +198,7 @@ Ndb_free_list_t<T>::~Ndb_free_list_t()
template<class T> template<class T>
inline inline
void int
Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt) Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
{ {
if (m_free_list == 0) if (m_free_list == 0)
@ -202,18 +206,28 @@ Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
m_free_cnt++; m_free_cnt++;
m_alloc_cnt++; m_alloc_cnt++;
m_free_list = new T(ndb); m_free_list = new T(ndb);
if (m_free_list == 0)
{
ndb->theError.code = 4000;
assert(false);
return -1;
}
} }
while(m_alloc_cnt < cnt) while(m_alloc_cnt < cnt)
{ {
T* obj= new T(ndb); T* obj= new T(ndb);
if(obj == 0) if(obj == 0)
return; {
ndb->theError.code = 4000;
assert(false);
return -1;
}
obj->next(m_free_list); obj->next(m_free_list);
m_free_cnt++; m_free_cnt++;
m_alloc_cnt++; m_alloc_cnt++;
m_free_list = obj; m_free_list = obj;
} }
return 0;
} }
template<class T> template<class T>
@ -234,7 +248,11 @@ Ndb_free_list_t<T>::seize(Ndb* ndb)
{ {
m_alloc_cnt++; m_alloc_cnt++;
} }
else
{
ndb->theError.code = 4000;
assert(false);
}
return tmp; return tmp;
} }

View File

@ -176,7 +176,11 @@ NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){
tcKeyReq->scanInfo = 0; tcKeyReq->scanInfo = 0;
theKEYINFOptr = &tcKeyReq->keyInfo[0]; theKEYINFOptr = &tcKeyReq->keyInfo[0];
theATTRINFOptr = &tcKeyReq->attrInfo[0]; theATTRINFOptr = &tcKeyReq->attrInfo[0];
theReceiver.init(NdbReceiver::NDB_OPERATION, this); if (theReceiver.init(NdbReceiver::NDB_OPERATION, this))
{
// theReceiver sets the error code of its owner
return -1;
}
return 0; return 0;
} }

View File

@ -83,6 +83,7 @@ NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue)
theRef = tRef; theRef = tRef;
return 0; return 0;
} }
errno = ENOMEM;
return -1; return -1;
} }
@ -102,7 +103,11 @@ NdbRecAttr::copyout()
NdbRecAttr * NdbRecAttr *
NdbRecAttr::clone() const { NdbRecAttr::clone() const {
NdbRecAttr * ret = new NdbRecAttr(0); NdbRecAttr * ret = new NdbRecAttr(0);
if (ret == NULL)
{
errno = ENOMEM;
return NULL;
}
ret->theAttrId = theAttrId; ret->theAttrId = theAttrId;
ret->theNULLind = theNULLind; ret->theNULLind = theNULLind;
ret->theAttrSize = theAttrSize; ret->theAttrSize = theAttrSize;
@ -116,6 +121,12 @@ NdbRecAttr::clone() const {
ret->theValue = 0; ret->theValue = 0;
} else { } else {
ret->theStorageX = new Uint64[((n + 7) >> 3)]; ret->theStorageX = new Uint64[((n + 7) >> 3)];
if (ret->theStorageX == NULL)
{
delete ret;
errno = ENOMEM;
return NULL;
}
ret->theRef = (char*)ret->theStorageX; ret->theRef = (char*)ret->theStorageX;
ret->theValue = 0; ret->theValue = 0;
} }
@ -508,3 +519,15 @@ NdbRecAttr::double_value() const
memcpy(&val,theRef,sizeof(val)); memcpy(&val,theRef,sizeof(val));
return val; return val;
} }
Int32
NdbRecAttr::medium_value() const
{
return sint3korr((unsigned char *)theRef);
}
Uint32
NdbRecAttr::u_medium_value() const
{
return uint3korr((unsigned char*)theRef);
}

View File

@ -32,7 +32,7 @@ NdbReceiver::NdbReceiver(Ndb *aNdb) :
{ {
theCurrentRecAttr = theFirstRecAttr = 0; theCurrentRecAttr = theFirstRecAttr = 0;
m_defined_rows = 0; m_defined_rows = 0;
m_rows = new NdbRecAttr*[0]; m_rows = NULL;
} }
NdbReceiver::~NdbReceiver() NdbReceiver::~NdbReceiver()
@ -45,19 +45,26 @@ NdbReceiver::~NdbReceiver()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void int
NdbReceiver::init(ReceiverType type, void* owner) NdbReceiver::init(ReceiverType type, void* owner)
{ {
theMagicNumber = 0x11223344; theMagicNumber = 0x11223344;
m_type = type; m_type = type;
m_owner = owner; m_owner = owner;
if (m_id == NdbObjectIdMap::InvalidId) {
if (m_ndb)
m_id = m_ndb->theImpl->theNdbObjectIdMap.map(this);
}
theFirstRecAttr = NULL; theFirstRecAttr = NULL;
theCurrentRecAttr = NULL; theCurrentRecAttr = NULL;
if (m_id == NdbObjectIdMap::InvalidId) {
if (m_ndb)
{
m_id = m_ndb->theImpl->theNdbObjectIdMap.map(this);
if (m_id == NdbObjectIdMap::InvalidId)
{
setErrorCode(4000);
return -1;
}
}
}
return 0;
} }
void void
@ -146,7 +153,7 @@ NdbReceiver::calculate_batch_size(Uint32 key_size,
return; return;
} }
void int
NdbReceiver::do_get_value(NdbReceiver * org, NdbReceiver::do_get_value(NdbReceiver * org,
Uint32 rows, Uint32 rows,
Uint32 key_size, Uint32 key_size,
@ -154,7 +161,11 @@ NdbReceiver::do_get_value(NdbReceiver * org,
if(rows > m_defined_rows){ if(rows > m_defined_rows){
delete[] m_rows; delete[] m_rows;
m_defined_rows = rows; m_defined_rows = rows;
m_rows = new NdbRecAttr*[rows + 1]; if ((m_rows = new NdbRecAttr*[rows + 1]) == NULL)
{
setErrorCode(4000);
return -1;
}
} }
m_rows[rows] = 0; m_rows[rows] = 0;
@ -174,7 +185,7 @@ NdbReceiver::do_get_value(NdbReceiver * org,
// Put key-recAttr fir on each row // Put key-recAttr fir on each row
if(key_size && !getValue(&key, (char*)0)){ if(key_size && !getValue(&key, (char*)0)){
abort(); abort();
return ; // -1 return -1;
} }
if(range_no && if(range_no &&
@ -193,7 +204,7 @@ NdbReceiver::do_get_value(NdbReceiver * org,
if(tRecAttr){ if(tRecAttr){
abort(); abort();
return ;// -1; return -1;
} }
// Store first recAttr for each row in m_rows[i] // Store first recAttr for each row in m_rows[i]
@ -205,7 +216,7 @@ NdbReceiver::do_get_value(NdbReceiver * org,
} }
prepareSend(); prepareSend();
return; return 0;
} }
NdbRecAttr* NdbRecAttr*

View File

@ -78,7 +78,11 @@ NdbScanFilter::~NdbScanFilter(){
int int
NdbScanFilter::begin(Group group){ NdbScanFilter::begin(Group group){
m_impl.m_stack2.push_back(m_impl.m_negative); if (m_impl.m_stack2.push_back(m_impl.m_negative))
{
m_impl.m_operation->setErrorCodeAbort(4000);
return -1;
}
switch(group){ switch(group){
case NdbScanFilter::AND: case NdbScanFilter::AND:
INT_DEBUG(("Begin(AND)")); INT_DEBUG(("Begin(AND)"));
@ -127,7 +131,11 @@ NdbScanFilter::begin(Group group){
} }
NdbScanFilterImpl::State tmp = m_impl.m_current; NdbScanFilterImpl::State tmp = m_impl.m_current;
m_impl.m_stack.push_back(m_impl.m_current); if (m_impl.m_stack.push_back(m_impl.m_current))
{
m_impl.m_operation->setErrorCodeAbort(4000);
return -1;
}
m_impl.m_current.m_group = group; m_impl.m_current.m_group = group;
m_impl.m_current.m_ownLabel = m_impl.m_label++; m_impl.m_current.m_ownLabel = m_impl.m_label++;
m_impl.m_current.m_popCount = 0; m_impl.m_current.m_popCount = 0;

View File

@ -797,9 +797,12 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr,
req->requestInfo = reqInfo; req->requestInfo = reqInfo;
for(Uint32 i = 0; i<theParallelism; i++){ for(Uint32 i = 0; i<theParallelism; i++){
m_receivers[i]->do_get_value(&theReceiver, batch_size, if (m_receivers[i]->do_get_value(&theReceiver, batch_size,
key_size, key_size,
m_read_range_no); m_read_range_no))
{
return -1;
}
} }
return 0; return 0;
} }

View File

@ -81,6 +81,7 @@ NdbTransaction::NdbTransaction( Ndb* aNdb ) :
{ {
theListState = NotInList; theListState = NotInList;
theError.code = 0; theError.code = 0;
//theId = NdbObjectIdMap::InvalidId;
theId = theNdb->theImpl->theNdbObjectIdMap.map(this); theId = theNdb->theImpl->theNdbObjectIdMap.map(this);
#define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz) #define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz)
@ -106,7 +107,7 @@ void init();
Remark: Initialise connection object for new transaction. Remark: Initialise connection object for new transaction.
*****************************************************************************/ *****************************************************************************/
void int
NdbTransaction::init() NdbTransaction::init()
{ {
theListState = NotInList; theListState = NotInList;
@ -147,6 +148,17 @@ NdbTransaction::init()
// //
theBlobFlag = false; theBlobFlag = false;
thePendingBlobOps = 0; thePendingBlobOps = 0;
if (theId == NdbObjectIdMap::InvalidId)
{
theId = theNdb->theImpl->theNdbObjectIdMap.map(this);
if (theId == NdbObjectIdMap::InvalidId)
{
theError.code = 4000;
return -1;
}
}
return 0;
}//NdbTransaction::init() }//NdbTransaction::init()
/***************************************************************************** /*****************************************************************************

View File

@ -816,8 +816,9 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
InvalidSignal: InvalidSignal:
#ifdef VM_TRACE #ifdef VM_TRACE
ndbout_c("Ndbif: Error Ndb::handleReceivedSignal " ndbout_c("Ndbif: Error Ndb::handleReceivedSignal "
"(GSN=%d, theImpl->theWaiter.m_state=%d)" "(tFirstDataPtr=%p, GSN=%d, theImpl->theWaiter.m_state=%d)"
" sender = (Block: %d Node: %d)", " sender = (Block: %d Node: %d)",
tFirstDataPtr,
tSignalNumber, tSignalNumber,
tWaitState, tWaitState,
refToBlock(aSignal->theSendersBlockRef), refToBlock(aSignal->theSendersBlockRef),

View File

@ -74,7 +74,10 @@ Ndb::checkFailedNode()
int int
Ndb::createConIdleList(int aNrOfCon) Ndb::createConIdleList(int aNrOfCon)
{ {
theImpl->theConIdleList.fill(this, aNrOfCon); if (theImpl->theConIdleList.fill(this, aNrOfCon))
{
return -1;
}
return aNrOfCon; return aNrOfCon;
} }
@ -90,7 +93,10 @@ Ndb::createConIdleList(int aNrOfCon)
int int
Ndb::createOpIdleList(int aNrOfOp) Ndb::createOpIdleList(int aNrOfOp)
{ {
theImpl->theOpIdleList.fill(this, aNrOfOp); if (theImpl->theOpIdleList.fill(this, aNrOfOp))
{
return -1;
}
return aNrOfOp; return aNrOfOp;
} }

View File

@ -0,0 +1,62 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "ObjectMap.hpp"
NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz)
{
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz);
#endif
}
NdbObjectIdMap::~NdbObjectIdMap()
{
free(m_map);
}
int NdbObjectIdMap::expand(Uint32 incSize)
{
NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
if (likely(tmp != 0))
{
m_map = tmp;
for(Uint32 i = m_size; i < newSize; i++){
m_map[i].m_next = i + 1;
}
m_firstFree = m_size;
m_map[newSize-1].m_next = InvalidId;
m_size = newSize;
}
else
{
NdbMutex_Unlock(m_mutex);
g_eventLogger.error("NdbObjectIdMap::expand: realloc(%u*%u) failed",
newSize, sizeof(MapEntry));
return -1;
}
NdbMutex_Unlock(m_mutex);
return 0;
}

View File

@ -20,6 +20,9 @@
//#include <NdbMutex.h> //#include <NdbMutex.h>
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <EventLogger.hpp>
extern EventLogger g_eventLogger;
//#define DEBUG_OBJECTMAP //#define DEBUG_OBJECTMAP
/** /**
@ -49,24 +52,6 @@ private:
int expand(Uint32 newSize); int expand(Uint32 newSize);
}; };
inline
NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz);
#endif
}
inline
NdbObjectIdMap::~NdbObjectIdMap(){
free(m_map);
}
inline inline
Uint32 Uint32
NdbObjectIdMap::map(void * object){ NdbObjectIdMap::map(void * object){
@ -102,7 +87,8 @@ NdbObjectIdMap::unmap(Uint32 id, void *object){
m_map[i].m_next = m_firstFree; m_map[i].m_next = m_firstFree;
m_firstFree = i; m_firstFree = i;
} else { } else {
ndbout_c("Error: NdbObjectIdMap::::unmap(%u, 0x%x) obj=0x%x", id, object, obj); g_eventLogger.error("NdbObjectIdMap::unmap(%u, 0x%x) obj=0x%x",
id, object, obj);
return 0; return 0;
} }
@ -128,31 +114,4 @@ NdbObjectIdMap::getObject(Uint32 id){
} }
return 0; return 0;
} }
inline int
NdbObjectIdMap::expand(Uint32 incSize){
NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
if (likely(tmp != 0))
{
m_map = tmp;
for(Uint32 i = m_size; i<newSize; i++){
m_map[i].m_next = i + 1;
}
m_firstFree = m_size;
m_map[newSize-1].m_next = InvalidId;
m_size = newSize;
}
else
{
NdbMutex_Unlock(m_mutex);
return -1;
}
NdbMutex_Unlock(m_mutex);
return 0;
}
#endif #endif

View File

@ -147,7 +147,10 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t)
{ {
SimpleSignal * s = t.check(m_jobBuffer); SimpleSignal * s = t.check(m_jobBuffer);
if(s != 0){ if(s != 0){
m_usedBuffer.push_back(s); if (m_usedBuffer.push_back(s))
{
return 0;
}
return s; return s;
} }
@ -162,7 +165,10 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t)
SimpleSignal * s = t.check(m_jobBuffer); SimpleSignal * s = t.check(m_jobBuffer);
if(s != 0){ if(s != 0){
m_usedBuffer.push_back(s); if (m_usedBuffer.push_back(s))
{
return 0;
}
return s; return s;
} }

View File

@ -353,7 +353,7 @@ Ndb_cluster_connection_impl::set_name(const char *name)
} }
} }
void int
Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid, Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid,
const ndb_mgm_configuration const ndb_mgm_configuration
&config) &config)
@ -402,7 +402,10 @@ Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid,
break; break;
} }
} }
m_impl.m_all_nodes.push_back(Node(group,remoteNodeId)); if (m_impl.m_all_nodes.push_back(Node(group,remoteNodeId)))
{
DBUG_RETURN(-1);
}
DBUG_PRINT("info",("saved %d %d", group,remoteNodeId)); DBUG_PRINT("info",("saved %d %d", group,remoteNodeId));
for (int i= m_impl.m_all_nodes.size()-2; for (int i= m_impl.m_all_nodes.size()-2;
i >= 0 && m_impl.m_all_nodes[i].group > m_impl.m_all_nodes[i+1].group; i >= 0 && m_impl.m_all_nodes[i].group > m_impl.m_all_nodes[i+1].group;
@ -449,7 +452,7 @@ Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid,
do_test(); do_test();
#endif #endif
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
void void
@ -532,7 +535,11 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds,
break; break;
m_impl.m_transporter_facade->start_instance(nodeId, props); m_impl.m_transporter_facade->start_instance(nodeId, props);
m_impl.init_nodes_vector(nodeId, *props); if (m_impl.init_nodes_vector(nodeId, *props))
{
ndbout_c("Ndb_cluster_connection::connect: malloc failure");
DBUG_RETURN(-1);
}
for(unsigned i=0; for(unsigned i=0;
i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size(); i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size();

View File

@ -68,7 +68,7 @@ private:
}; };
Vector<Node> m_all_nodes; Vector<Node> m_all_nodes;
void init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config); int init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config);
void connect_thread(); void connect_thread();
void set_name(const char *name); void set_name(const char *name);

View File

@ -219,6 +219,9 @@ public:
memcpy(&val.u32,data,4); memcpy(&val.u32,data,4);
v= val.u32; v= val.u32;
break; break;
case 24:
v= uint3korr((unsigned char*)data);
break;
case 16: case 16:
memcpy(&val.u16,data,2); memcpy(&val.u16,data,2);
v= val.u16; v= val.u16;

View File

@ -205,7 +205,7 @@ BackupRestore::table(const TableS & table){
BaseString tmp(name); BaseString tmp(name);
Vector<BaseString> split; Vector<BaseString> split;
if(tmp.split(split, "/") != 3){ if(tmp.split(split, "/") != 3){
err << "Invalid table name format " << name << endl; err << "Invalid table name format `" << name << "`" << endl;
return false; return false;
} }
@ -230,16 +230,17 @@ BackupRestore::table(const TableS & table){
if (dict->createTable(copy) == -1) if (dict->createTable(copy) == -1)
{ {
err << "Create table " << table.getTableName() << " failed: " err << "Create table `" << table.getTableName() << "` failed: "
<< dict->getNdbError() << endl; << dict->getNdbError() << endl;
return false; return false;
} }
info << "Successfully restored table " << table.getTableName()<< endl ; info << "Successfully restored table `"
<< table.getTableName() << "`" << endl;
} }
const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); const NdbDictionary::Table* tab = dict->getTable(split[2].c_str());
if(tab == 0){ if(tab == 0){
err << "Unable to find table: " << split[2].c_str() << endl; err << "Unable to find table: `" << split[2].c_str() << "`" << endl;
return false; return false;
} }
const NdbDictionary::Table* null = 0; const NdbDictionary::Table* null = 0;
@ -257,52 +258,57 @@ BackupRestore::endOfTables(){
for(size_t i = 0; i<m_indexes.size(); i++){ for(size_t i = 0; i<m_indexes.size(); i++){
NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]); NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]);
BaseString tmp(indtab.m_primaryTable.c_str());
Vector<BaseString> split; Vector<BaseString> split;
if(tmp.split(split, "/") != 3){ {
err << "Invalid table name format " << indtab.m_primaryTable.c_str() BaseString tmp(indtab.m_primaryTable.c_str());
<< endl; if (tmp.split(split, "/") != 3)
{
err << "Invalid table name format `" << indtab.m_primaryTable.c_str()
<< "`" << endl;
return false; return false;
} }
}
m_ndb->setDatabaseName(split[0].c_str()); m_ndb->setDatabaseName(split[0].c_str());
m_ndb->setSchemaName(split[1].c_str()); m_ndb->setSchemaName(split[1].c_str());
const NdbDictionary::Table * prim = dict->getTable(split[2].c_str()); const NdbDictionary::Table * prim = dict->getTable(split[2].c_str());
if(prim == 0){ if(prim == 0){
err << "Unable to find base table \"" << split[2].c_str() err << "Unable to find base table `" << split[2].c_str()
<< "\" for index " << "` for index `"
<< indtab.getName() << endl; << indtab.getName() << "`" << endl;
return false; return false;
} }
NdbTableImpl& base = NdbTableImpl::getImpl(*prim); NdbTableImpl& base = NdbTableImpl::getImpl(*prim);
NdbIndexImpl* idx; NdbIndexImpl* idx;
int id; Vector<BaseString> split_idx;
char idxName[255], buf[255]; {
if(sscanf(indtab.getName(), "%[^/]/%[^/]/%d/%s", BaseString tmp(indtab.getName());
buf, buf, &id, idxName) != 4){ if (tmp.split(split_idx, "/") != 4)
err << "Invalid index name format " << indtab.getName() << endl; {
err << "Invalid index name format `" << indtab.getName() << "`" << endl;
return false; return false;
} }
}
if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base)) if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base))
{ {
err << "Failed to create index " << idxName err << "Failed to create index `" << split_idx[3]
<< " on " << split[2].c_str() << endl; << "` on " << split[2].c_str() << endl;
return false; return false;
} }
idx->setName(idxName); idx->setName(split_idx[3].c_str());
if(dict->createIndex(* idx) != 0) if(dict->createIndex(* idx) != 0)
{ {
delete idx; delete idx;
err << "Failed to create index " << idxName err << "Failed to create index `" << split_idx[3].c_str()
<< " on " << split[2].c_str() << endl << "` on `" << split[2].c_str() << "`" << endl
<< dict->getNdbError() << endl; << dict->getNdbError() << endl;
return false; return false;
} }
delete idx; delete idx;
info << "Successfully created index " << idxName info << "Successfully created index `" << split_idx[3].c_str()
<< " on " << split[2].c_str() << endl; << "` on `" << split[2].c_str() << "`" << endl;
} }
return true; return true;
} }
@ -382,7 +388,7 @@ void BackupRestore::tuple_a(restore_callback_t *cb)
Uint32 length = (size * arraySize) / 8; Uint32 length = (size * arraySize) / 8;
if (j == 0 && tup.getTable()->have_auto_inc(i)) if (j == 0 && tup.getTable()->have_auto_inc(i))
tup.getTable()->update_max_auto_val(dataPtr,size); tup.getTable()->update_max_auto_val(dataPtr,size*arraySize);
if (attr_desc->m_column->getPrimaryKey()) if (attr_desc->m_column->getPrimaryKey())
{ {
@ -596,7 +602,7 @@ BackupRestore::logEntry(const LogEntry & tup)
const char * dataPtr = attr->Data.string_value; const char * dataPtr = attr->Data.string_value;
if (tup.m_table->have_auto_inc(attr->Desc->attrId)) if (tup.m_table->have_auto_inc(attr->Desc->attrId))
tup.m_table->update_max_auto_val(dataPtr,size); tup.m_table->update_max_auto_val(dataPtr,size*arraySize);
const Uint32 length = (size / 8) * arraySize; const Uint32 length = (size / 8) * arraySize;
if (attr->Desc->m_column->getPrimaryKey()) if (attr->Desc->m_column->getPrimaryKey())

View File

@ -559,8 +559,8 @@ main(int argc, char** argv)
for(Uint32 j= 0; j < g_consumers.size(); j++) for(Uint32 j= 0; j < g_consumers.size(); j++)
if (!g_consumers[j]->table(* table)) if (!g_consumers[j]->table(* table))
{ {
err << "Restore: Failed to restore table: "; err << "Restore: Failed to restore table: `";
err << table->getTableName() << " ... Exiting " << endl; err << table->getTableName() << "` ... Exiting " << endl;
exitHandler(NDBT_FAILED); exitHandler(NDBT_FAILED);
} }
} }

View File

@ -203,6 +203,7 @@ static const err_code_mapping err_map[]=
{ 284, HA_ERR_TABLE_DEF_CHANGED, 0 }, { 284, HA_ERR_TABLE_DEF_CHANGED, 0 },
{4000, HA_ERR_OUT_OF_MEM, 1 },
{4009, HA_ERR_NO_CONNECTION, 1 }, {4009, HA_ERR_NO_CONNECTION, 1 },
{ 0, 1, 0 }, { 0, 1, 0 },
@ -372,7 +373,10 @@ int ha_ndbcluster::records_update()
{ {
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
struct Ndb_statistics stat; struct Ndb_statistics stat;
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
return my_errno= HA_ERR_OUT_OF_MEM;
}
result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat); result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat);
if (result == 0) if (result == 0)
{ {
@ -841,7 +845,11 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob,
DBUG_PRINT("value", ("allocate blobs buffer size %u", offset)); DBUG_PRINT("value", ("allocate blobs buffer size %u", offset));
m_blobs_buffer= my_malloc(offset, MYF(MY_WME)); m_blobs_buffer= my_malloc(offset, MYF(MY_WME));
if (m_blobs_buffer == NULL) if (m_blobs_buffer == NULL)
{
sql_print_error("ha_ndbcluster::get_ndb_blobs_value: "
"my_malloc(%u) failed", offset);
DBUG_RETURN(-1); DBUG_RETURN(-1);
}
m_blobs_buffer_size= offset; m_blobs_buffer_size= offset;
} }
} }
@ -1026,6 +1034,12 @@ static int fix_unique_index_attr_order(NDB_INDEX_DATA &data,
if (data.unique_index_attrid_map) if (data.unique_index_attrid_map)
my_free((char*)data.unique_index_attrid_map, MYF(0)); my_free((char*)data.unique_index_attrid_map, MYF(0));
data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME)); data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME));
if (data.unique_index_attrid_map == 0)
{
sql_print_error("fix_unique_index_attr_order: my_malloc(%u) failure",
(unsigned int)sz);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts; KEY_PART_INFO* end= key_part+key_info->key_parts;
@ -1134,14 +1148,16 @@ int ha_ndbcluster::build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase)
{ {
DBUG_PRINT("info", ("Get handle to index %s", index_name)); DBUG_PRINT("info", ("Get handle to index %s", index_name));
const NDBINDEX *index= dict->getIndex(index_name, m_tabname); const NDBINDEX *index= dict->getIndex(index_name, m_tabname);
if (!index) DBUG_RETURN(1); if (!index)
ERR_RETURN(dict->getNdbError());
m_index[i].index= (void *) index; m_index[i].index= (void *) index;
} }
if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX) if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX)
{ {
DBUG_PRINT("info", ("Get handle to unique_index %s", unique_index_name)); DBUG_PRINT("info", ("Get handle to unique_index %s", unique_index_name));
const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname); const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname);
if (!index) DBUG_RETURN(1); if (!index)
ERR_RETURN(dict->getNdbError());
m_index[i].unique_index= (void *) index; m_index[i].unique_index= (void *) index;
error= fix_unique_index_attr_order(m_index[i], index, key_info); error= fix_unique_index_attr_order(m_index[i], index, key_info);
} }
@ -3228,7 +3244,10 @@ int ha_ndbcluster::info(uint flag)
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
struct Ndb_statistics stat; struct Ndb_statistics stat;
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
}
if (current_thd->variables.ndb_use_exact_count && if (current_thd->variables.ndb_use_exact_count &&
(result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat)) (result= ndb_get_table_statistics(this, true, ndb, m_tabname, &stat))
== 0) == 0)
@ -4037,7 +4056,10 @@ static int create_ndb_column(NDBCOL &col,
HA_CREATE_INFO *info) HA_CREATE_INFO *info)
{ {
// Set name // Set name
col.setName(field->field_name); if (col.setName(field->field_name))
{
return (my_errno= errno);
}
// Get char set // Get char set
CHARSET_INFO *cs= field->charset(); CHARSET_INFO *cs= field->charset();
// Set type and sizes // Set type and sizes
@ -4409,7 +4431,10 @@ int ha_ndbcluster::create(const char *name,
} }
DBUG_PRINT("table", ("name: %s", m_tabname)); DBUG_PRINT("table", ("name: %s", m_tabname));
tab.setName(m_tabname); if (tab.setName(m_tabname))
{
DBUG_RETURN(my_errno= errno);
}
tab.setLogging(!(create_info->options & HA_LEX_CREATE_TMP_TABLE)); tab.setLogging(!(create_info->options & HA_LEX_CREATE_TMP_TABLE));
// Save frm data for this table // Save frm data for this table
@ -4434,7 +4459,10 @@ int ha_ndbcluster::create(const char *name,
field->pack_length())); field->pack_length()));
if ((my_errno= create_ndb_column(col, field, create_info))) if ((my_errno= create_ndb_column(col, field, create_info)))
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
tab.addColumn(col); if (tab.addColumn(col))
{
DBUG_RETURN(my_errno= errno);
}
if (col.getPrimaryKey()) if (col.getPrimaryKey())
pk_length += (field->pack_length() + 3) / 4; pk_length += (field->pack_length() + 3) / 4;
} }
@ -4443,13 +4471,19 @@ int ha_ndbcluster::create(const char *name,
if (form->s->primary_key == MAX_KEY) if (form->s->primary_key == MAX_KEY)
{ {
DBUG_PRINT("info", ("Generating shadow key")); DBUG_PRINT("info", ("Generating shadow key"));
col.setName("$PK"); if (col.setName("$PK"))
{
DBUG_RETURN(my_errno= errno);
}
col.setType(NdbDictionary::Column::Bigunsigned); col.setType(NdbDictionary::Column::Bigunsigned);
col.setLength(1); col.setLength(1);
col.setNullable(FALSE); col.setNullable(FALSE);
col.setPrimaryKey(TRUE); col.setPrimaryKey(TRUE);
col.setAutoIncrement(TRUE); col.setAutoIncrement(TRUE);
tab.addColumn(col); if (tab.addColumn(col))
{
DBUG_RETURN(my_errno= errno);
}
pk_length += 2; pk_length += 2;
} }
@ -4555,13 +4589,19 @@ int ha_ndbcluster::create_index(const char *name,
// TODO Only temporary ordered indexes supported // TODO Only temporary ordered indexes supported
ndb_index.setLogging(FALSE); ndb_index.setLogging(FALSE);
} }
ndb_index.setTable(m_tabname); if (ndb_index.setTable(m_tabname))
{
DBUG_RETURN(my_errno= errno);
}
for (; key_part != end; key_part++) for (; key_part != end; key_part++)
{ {
Field *field= key_part->field; Field *field= key_part->field;
DBUG_PRINT("info", ("attr: %s", field->field_name)); DBUG_PRINT("info", ("attr: %s", field->field_name));
ndb_index.addColumnName(field->field_name); if (ndb_index.addColumnName(field->field_name))
{
DBUG_RETURN(my_errno= errno);
}
} }
if (dict->createIndex(ndb_index)) if (dict->createIndex(ndb_index))
@ -4616,7 +4656,10 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
m_table= (void *)orig_tab; m_table= (void *)orig_tab;
// Change current database to that of target table // Change current database to that of target table
set_dbname(to); set_dbname(to);
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
if (!(result= alter_table_name(new_tabname))) if (!(result= alter_table_name(new_tabname)))
{ {
// Rename .ndb file // Rename .ndb file
@ -4635,10 +4678,16 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
for (unsigned i = 0; i < index_list.count; i++) { for (unsigned i = 0; i < index_list.count; i++) {
NDBDICT::List::Element& index_el = index_list.elements[i]; NDBDICT::List::Element& index_el = index_list.elements[i];
set_dbname(from); set_dbname(from);
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
const NDBINDEX * index= dict->getIndex(index_el.name, *new_tab); const NDBINDEX * index= dict->getIndex(index_el.name, *new_tab);
set_dbname(to); set_dbname(to);
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
DBUG_PRINT("info", ("Creating index %s/%s", DBUG_PRINT("info", ("Creating index %s/%s",
m_dbname, index->getName())); m_dbname, index->getName()));
dict->createIndex(*index); dict->createIndex(*index);
@ -4646,7 +4695,10 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
m_dbname, index->getName())); m_dbname, index->getName()));
set_dbname(from); set_dbname(from);
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
dict->dropIndex(*index); dict->dropIndex(*index);
} }
} }
@ -4667,7 +4719,10 @@ int ha_ndbcluster::alter_table_name(const char *to)
DBUG_ENTER("alter_table_name_table"); DBUG_ENTER("alter_table_name_table");
NdbDictionary::Table new_tab= *orig_tab; NdbDictionary::Table new_tab= *orig_tab;
new_tab.setName(to); if (new_tab.setName(to))
{
DBUG_RETURN(my_errno= errno);
}
if (dict->alterTable(new_tab) != 0) if (dict->alterTable(new_tab) != 0)
ERR_RETURN(dict->getNdbError()); ERR_RETURN(dict->getNdbError());
@ -4913,7 +4968,10 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
if (!res) if (!res)
{ {
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
struct Ndb_statistics stat; struct Ndb_statistics stat;
res= ndb_get_table_statistics(NULL, false, ndb, m_tabname, &stat); res= ndb_get_table_statistics(NULL, false, ndb, m_tabname, &stat);
records= stat.row_count; records= stat.row_count;
@ -4945,6 +5003,11 @@ Thd_ndb* ha_ndbcluster::seize_thd_ndb()
DBUG_ENTER("seize_thd_ndb"); DBUG_ENTER("seize_thd_ndb");
thd_ndb= new Thd_ndb(); thd_ndb= new Thd_ndb();
if (thd_ndb == NULL)
{
my_errno= HA_ERR_OUT_OF_MEM;
return NULL;
}
thd_ndb->ndb->getDictionary()->set_local_table_data_size( thd_ndb->ndb->getDictionary()->set_local_table_data_size(
sizeof(Ndb_local_table_statistics) sizeof(Ndb_local_table_statistics)
); );
@ -5000,7 +5063,10 @@ int ha_ndbcluster::check_ndb_connection(THD* thd)
if (!(ndb= check_ndb_in_thd(thd))) if (!(ndb= check_ndb_in_thd(thd)))
DBUG_RETURN(HA_ERR_NO_CONNECTION); DBUG_RETURN(HA_ERR_NO_CONNECTION);
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
ERR_RETURN(ndb->getNdbError());
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -5034,8 +5100,10 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
if (!(ndb= check_ndb_in_thd(thd))) if (!(ndb= check_ndb_in_thd(thd)))
DBUG_RETURN(HA_ERR_NO_CONNECTION); DBUG_RETURN(HA_ERR_NO_CONNECTION);
ndb->setDatabaseName(db); if (ndb->setDatabaseName(db))
{
ERR_RETURN(ndb->getNdbError());
}
NDBDICT* dict= ndb->getDictionary(); NDBDICT* dict= ndb->getDictionary();
dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
dict->invalidateTable(name); dict->invalidateTable(name);
@ -5081,8 +5149,10 @@ int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name
if (!(ndb= check_ndb_in_thd(thd))) if (!(ndb= check_ndb_in_thd(thd)))
DBUG_RETURN(HA_ERR_NO_CONNECTION); DBUG_RETURN(HA_ERR_NO_CONNECTION);
ndb->setDatabaseName(db); if (ndb->setDatabaseName(db))
{
ERR_RETURN(ndb->getNdbError());
}
NDBDICT* dict= ndb->getDictionary(); NDBDICT* dict= ndb->getDictionary();
dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
dict->invalidateTable(name); dict->invalidateTable(name);
@ -5143,7 +5213,10 @@ int ndbcluster_drop_database(const char *path)
drop_list.push_back(thd->strdup(t.name)); drop_list.push_back(thd->strdup(t.name));
} }
// Drop any tables belonging to database // Drop any tables belonging to database
ndb->setDatabaseName(dbname); if (ndb->setDatabaseName(dbname))
{
ERR_RETURN(ndb->getNdbError());
}
List_iterator_fast<char> it(drop_list); List_iterator_fast<char> it(drop_list);
while ((tabname=it++)) while ((tabname=it++))
{ {
@ -5372,6 +5445,7 @@ bool ndbcluster_init()
{ {
DBUG_PRINT("error",("Ndb_cluster_connection(%s)", DBUG_PRINT("error",("Ndb_cluster_connection(%s)",
opt_ndbcluster_connectstring)); opt_ndbcluster_connectstring));
my_errno= HA_ERR_OUT_OF_MEM;
goto ndbcluster_init_error; goto ndbcluster_init_error;
} }
{ {
@ -5386,6 +5460,7 @@ bool ndbcluster_init()
if ( (g_ndb= new Ndb(g_ndb_cluster_connection, "sys")) == 0 ) if ( (g_ndb= new Ndb(g_ndb_cluster_connection, "sys")) == 0 )
{ {
DBUG_PRINT("error", ("failed to create global ndb object")); DBUG_PRINT("error", ("failed to create global ndb object"));
my_errno= HA_ERR_OUT_OF_MEM;
goto ndbcluster_init_error; goto ndbcluster_init_error;
} }
g_ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_local_table_statistics)); g_ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
@ -5741,7 +5816,10 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
Ndb *ndb; Ndb *ndb;
if (!(ndb= check_ndb_in_thd(thd))) if (!(ndb= check_ndb_in_thd(thd)))
DBUG_RETURN(1); DBUG_RETURN(1);
ndb->setDatabaseName(dbname); if (ndb->setDatabaseName(dbname))
{
ERR_RETURN(ndb->getNdbError());
}
uint lock= share->commit_count_lock; uint lock= share->commit_count_lock;
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
@ -5954,6 +6032,8 @@ static NDB_SHARE* get_share(const char *table_name)
{ {
DBUG_PRINT("error", ("Failed to alloc share")); DBUG_PRINT("error", ("Failed to alloc share"));
pthread_mutex_unlock(&ndbcluster_mutex); pthread_mutex_unlock(&ndbcluster_mutex);
sql_print_error("get_share: my_malloc(%u) failed",
(unsigned int)(sizeof(*share)+length+1));
return 0; return 0;
} }
} }
@ -6014,7 +6094,11 @@ static int packfrm(const void *data, uint len,
error= 1; error= 1;
org_len= len; org_len= len;
if (my_compress((byte*)data, &org_len, &comp_len)) if (my_compress((byte*)data, &org_len, &comp_len))
{
sql_print_error("packfrm: my_compress(org_len: %u)",
(unsigned int)org_len);
goto err; goto err;
}
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len)); DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len));
DBUG_DUMP("compressed", (char*)data, org_len); DBUG_DUMP("compressed", (char*)data, org_len);
@ -6022,8 +6106,10 @@ static int packfrm(const void *data, uint len,
error= 2; error= 2;
blob_len= sizeof(frm_blob_struct::frm_blob_header)+org_len; blob_len= sizeof(frm_blob_struct::frm_blob_header)+org_len;
if (!(blob= (frm_blob_struct*) my_malloc(blob_len,MYF(MY_WME)))) if (!(blob= (frm_blob_struct*) my_malloc(blob_len,MYF(MY_WME))))
{
sql_print_error("packfrm: my_malloc(%u)", blob_len);
goto err; goto err;
}
// Store compressed blob in machine independent format // Store compressed blob in machine independent format
int4store((char*)(&blob->head.ver), 1); int4store((char*)(&blob->head.ver), 1);
int4store((char*)(&blob->head.orglen), comp_len); int4store((char*)(&blob->head.orglen), comp_len);
@ -6062,14 +6148,23 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len,
DBUG_DUMP("blob->data", (char*) blob->data, complen); DBUG_DUMP("blob->data", (char*) blob->data, complen);
if (ver != 1) if (ver != 1)
{
sql_print_error("unpackfrm: ver != 1");
DBUG_RETURN(1); DBUG_RETURN(1);
}
if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME)))) if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
DBUG_RETURN(2); {
sql_print_error("unpackfrm: my_malloc(%u)",
(unsigned int)max(orglen, complen));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
memcpy(data, blob->data, complen); memcpy(data, blob->data, complen);
if (my_uncompress(data, &complen, &orglen)) if (my_uncompress(data, &complen, &orglen))
{ {
my_free((char*)data, MYF(0)); my_free((char*)data, MYF(0));
sql_print_error("unpackfrm: my_uncompress(complen: %u, orglen: %u)",
(unsigned int)complen, (unsigned int)orglen);
DBUG_RETURN(3); DBUG_RETURN(3);
} }
@ -6664,7 +6759,10 @@ ha_ndbcluster::update_table_comment(
return((char*)comment); return((char*)comment);
} }
ndb->setDatabaseName(m_dbname); if (ndb->setDatabaseName(m_dbname))
{
return((char*)comment);
}
NDBDICT* dict= ndb->getDictionary(); NDBDICT* dict= ndb->getDictionary();
const NDBTAB* tab; const NDBTAB* tab;
if (!(tab= dict->getTable(m_tabname))) if (!(tab= dict->getTable(m_tabname)))
@ -6677,6 +6775,8 @@ ha_ndbcluster::update_table_comment(
const unsigned fmt_len_plus_extra= length + strlen(fmt); const unsigned fmt_len_plus_extra= length + strlen(fmt);
if ((str= my_malloc(fmt_len_plus_extra, MYF(0))) == NULL) if ((str= my_malloc(fmt_len_plus_extra, MYF(0))) == NULL)
{ {
sql_print_error("ha_ndbcluster::update_table_comment: "
"my_malloc(%u) failed", (unsigned int)fmt_len_plus_extra);
return (char*)comment; return (char*)comment;
} }
@ -6699,9 +6799,19 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
DBUG_PRINT("enter", ("ndb_cache_check_time: %lu", ndb_cache_check_time)); DBUG_PRINT("enter", ("ndb_cache_check_time: %lu", ndb_cache_check_time));
thd= new THD; /* note that contructor of THD uses DBUG_ */ thd= new THD; /* note that contructor of THD uses DBUG_ */
if (thd == NULL)
{
my_errno= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
THD_CHECK_SENTRY(thd); THD_CHECK_SENTRY(thd);
ndb= new Ndb(g_ndb_cluster_connection, ""); ndb= new Ndb(g_ndb_cluster_connection, "");
if (ndb == NULL)
{
thd->cleanup();
delete thd;
DBUG_RETURN(NULL);
}
pthread_detach_this_thread(); pthread_detach_this_thread();
ndb_util_thread= pthread_self(); ndb_util_thread= pthread_self();
@ -6790,14 +6900,15 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
share->table_name)); share->table_name));
/* Contact NDB to get commit count for table */ /* Contact NDB to get commit count for table */
ndb->setDatabaseName(db);
struct Ndb_statistics stat; struct Ndb_statistics stat;
uint lock; uint lock;
pthread_mutex_lock(&share->mutex); pthread_mutex_lock(&share->mutex);
lock= share->commit_count_lock; lock= share->commit_count_lock;
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
if (ndb->setDatabaseName(db))
{
goto loop_next;
}
if (ndb_get_table_statistics(NULL, false, ndb, tabname, &stat) == 0) if (ndb_get_table_statistics(NULL, false, ndb, tabname, &stat) == 0)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
@ -6816,7 +6927,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
share->table_name)); share->table_name));
stat.commit_count= 0; stat.commit_count= 0;
} }
loop_next:
pthread_mutex_lock(&share->mutex); pthread_mutex_lock(&share->mutex);
if (share->commit_count_lock == lock) if (share->commit_count_lock == lock)
share->commit_count= stat.commit_count; share->commit_count= stat.commit_count;
@ -6885,6 +6996,11 @@ ha_ndbcluster::cond_push(const COND *cond)
{ {
DBUG_ENTER("cond_push"); DBUG_ENTER("cond_push");
Ndb_cond_stack *ndb_cond = new Ndb_cond_stack(); Ndb_cond_stack *ndb_cond = new Ndb_cond_stack();
if (ndb_cond == NULL)
{
my_errno= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname);); DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname););
if (m_cond_stack) if (m_cond_stack)
ndb_cond->next= m_cond_stack; ndb_cond->next= m_cond_stack;

View File

@ -1610,7 +1610,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field)
Item_field::Item_field(Field *f) Item_field::Item_field(Field *f)
:Item_ident(0, NullS, *f->table_name, f->field_name), :Item_ident(0, NullS, *f->table_name, f->field_name),
item_equal(0), no_const_subst(0), item_equal(0), no_const_subst(0),
have_privileges(0), any_privileges(0), fixed_as_field(0) have_privileges(0), any_privileges(0)
{ {
set_field(f); set_field(f);
/* /*
@ -1624,7 +1624,7 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
Field *f) Field *f)
:Item_ident(context_arg, f->table->s->db, *f->table_name, f->field_name), :Item_ident(context_arg, f->table->s->db, *f->table_name, f->field_name),
item_equal(0), no_const_subst(0), item_equal(0), no_const_subst(0),
have_privileges(0), any_privileges(0), fixed_as_field(0) have_privileges(0), any_privileges(0)
{ {
/* /*
We always need to provide Item_field with a fully qualified field We always need to provide Item_field with a fully qualified field
@ -1663,7 +1663,7 @@ Item_field::Item_field(Name_resolution_context *context_arg,
const char *field_name_arg) const char *field_name_arg)
:Item_ident(context_arg, db_arg,table_name_arg,field_name_arg), :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
field(0), result_field(0), item_equal(0), no_const_subst(0), field(0), result_field(0), item_equal(0), no_const_subst(0),
have_privileges(0), any_privileges(0), fixed_as_field(0) have_privileges(0), any_privileges(0)
{ {
SELECT_LEX *select= current_thd->lex->current_select; SELECT_LEX *select= current_thd->lex->current_select;
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
@ -1679,8 +1679,7 @@ Item_field::Item_field(THD *thd, Item_field *item)
item_equal(item->item_equal), item_equal(item->item_equal),
no_const_subst(item->no_const_subst), no_const_subst(item->no_const_subst),
have_privileges(item->have_privileges), have_privileges(item->have_privileges),
any_privileges(item->any_privileges), any_privileges(item->any_privileges)
fixed_as_field(item->fixed_as_field)
{ {
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
} }
@ -3447,6 +3446,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
Item **ref= (Item **) not_found_item; Item **ref= (Item **) not_found_item;
SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select; SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select;
Name_resolution_context *outer_context= 0; Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */ /* Currently derived tables cannot be correlated */
if (current_sel->master_unit()->first_select()->linkage != if (current_sel->master_unit()->first_select()->linkage !=
DERIVED_TABLE_TYPE) DERIVED_TABLE_TYPE)
@ -3455,7 +3455,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
outer_context; outer_context;
outer_context= outer_context->outer_context) outer_context= outer_context->outer_context)
{ {
SELECT_LEX *select= outer_context->select_lex; select= outer_context->select_lex;
Item_subselect *prev_subselect_item= Item_subselect *prev_subselect_item=
last_checked_context->select_lex->master_unit()->item; last_checked_context->select_lex->master_unit()->item;
last_checked_context= outer_context; last_checked_context= outer_context;
@ -3498,45 +3498,28 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
} }
if (*from_field != view_ref_found) if (*from_field != view_ref_found)
{ {
prev_subselect_item->used_tables_cache|= (*from_field)->table->map; prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
prev_subselect_item->const_item_cache= 0; prev_subselect_item->const_item_cache= 0;
set_field(*from_field);
if (!last_checked_context->select_lex->having_fix_field && if (!last_checked_context->select_lex->having_fix_field &&
!fixed_as_field) select->group_list.elements)
{ {
Item_outer_ref *rf; Item_outer_ref *rf;
Query_arena *arena= 0, backup;
/* /*
Each outer field is replaced for an Item_outer_ref object. If an outer field is resolved in a grouping select then it
This is done in order to get correct results when the outer is replaced for an Item_outer_ref object. Otherwise an
select employs a temporary table. Item_field object is used.
The original fields are saved in the inner_fields_list of the The new Item_outer_ref object is saved in the inner_refs_list of
outer select. This list is created by the following reasons: the outer select. Here it is only created. It can be fixed only
1. We can't add field items to the outer select list directly after the original field has been fixed and this is done in the
because the outer select hasn't been fully fixed yet. fix_inner_refs() function.
2. We need a location to refer to in the Item_ref object
so the inner_fields_list is used as such temporary
reference storage.
The new Item_outer_ref object replaces the original field and is
also saved in the inner_refs_list of the outer select. Here
it is only created. It can be fixed only after the original
field has been fixed and this is done in the fix_inner_refs()
function.
*/ */
set_field(*from_field); ;
arena= thd->activate_stmt_arena_if_needed(&backup); if (!(rf= new Item_outer_ref(context, this)))
rf= new Item_outer_ref(context, this);
if (!rf)
{
if (arena)
thd->restore_active_arena(arena, &backup);
return -1; return -1;
} thd->change_item_tree(reference, rf);
*reference= rf;
select->inner_refs_list.push_back(rf); select->inner_refs_list.push_back(rf);
if (arena) rf->in_sum_func= thd->lex->in_sum_func;
thd->restore_active_arena(arena, &backup);
fixed_as_field= 1;
} }
if (thd->lex->in_sum_func && if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level == thd->lex->in_sum_func->nest_level ==
@ -3642,11 +3625,20 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
rf= (place == IN_HAVING ? rf= (place == IN_HAVING ?
new Item_ref(context, ref, (char*) table_name, new Item_ref(context, ref, (char*) table_name,
(char*) field_name, alias_name_used) : (char*) field_name, alias_name_used) :
(!select->group_list.elements ?
new Item_direct_ref(context, ref, (char*) table_name, new Item_direct_ref(context, ref, (char*) table_name,
(char*) field_name, alias_name_used)); (char*) field_name, alias_name_used) :
new Item_outer_ref(context, ref, (char*) table_name,
(char*) field_name, alias_name_used)));
*ref= save; *ref= save;
if (!rf) if (!rf)
return -1; return -1;
if (place != IN_HAVING && select->group_list.elements)
{
outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf);
((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func;
}
thd->change_item_tree(reference, rf); thd->change_item_tree(reference, rf);
/* /*
rf is Item_ref => never substitute other items (in this case) rf is Item_ref => never substitute other items (in this case)
@ -5550,16 +5542,19 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
bool Item_outer_ref::fix_fields(THD *thd, Item **reference) bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
{ {
DBUG_ASSERT(*ref); bool err;
/* outer_field->check_cols() will be made in Item_direct_ref::fix_fields */ /* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */
outer_field->fixed_as_field= 1; if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference)))
if (!outer_field->fixed &&
(outer_field->fix_fields(thd, reference)))
return TRUE; return TRUE;
table_name= outer_field->table_name; err= Item_direct_ref::fix_fields(thd, reference);
return Item_direct_ref::fix_fields(thd, reference); if (!outer_ref)
outer_ref= *ref;
if ((*ref)->type() == Item::FIELD_ITEM)
table_name= ((Item_field*)outer_ref)->table_name;
return err;
} }
/* /*
Compare two view column references for equality. Compare two view column references for equality.

View File

@ -1220,7 +1220,6 @@ public:
uint have_privileges; uint have_privileges;
/* field need any privileges (for VIEW creation) */ /* field need any privileges (for VIEW creation) */
bool any_privileges; bool any_privileges;
bool fixed_as_field;
Item_field(Name_resolution_context *context_arg, Item_field(Name_resolution_context *context_arg,
const char *db_arg,const char *table_name_arg, const char *db_arg,const char *table_name_arg,
const char *field_name_arg); const char *field_name_arg);
@ -1978,30 +1977,49 @@ public:
}; };
/*
Class for outer fields.
An object of this class is created when the select where the outer field was
resolved is a grouping one. After it has been fixed the ref field will point
to either an Item_ref or an Item_direct_ref object which will be used to
access the field.
See also comments for the fix_inner_refs() and the
Item_field::fix_outer_field() functions.
*/
class Item_sum;
class Item_outer_ref :public Item_direct_ref class Item_outer_ref :public Item_direct_ref
{ {
public: public:
Item_field *outer_field; Item *outer_ref;
/* The aggregate function under which this outer ref is used, if any. */
Item_sum *in_sum_func;
/*
TRUE <=> that the outer_ref is already present in the select list
of the outer select.
*/
bool found_in_select_list;
Item_outer_ref(Name_resolution_context *context_arg, Item_outer_ref(Name_resolution_context *context_arg,
Item_field *outer_field_arg) Item_field *outer_field_arg)
:Item_direct_ref(context_arg, 0, outer_field_arg->table_name, :Item_direct_ref(context_arg, 0, outer_field_arg->table_name,
outer_field_arg->field_name), outer_field_arg->field_name),
outer_field(outer_field_arg) outer_ref(outer_field_arg), in_sum_func(0),
found_in_select_list(0)
{ {
ref= (Item**)&outer_field; ref= &outer_ref;
set_properties(); set_properties();
fixed= 0; fixed= 0;
} }
void cleanup() Item_outer_ref(Name_resolution_context *context_arg, Item **item,
{ const char *table_name_arg, const char *field_name_arg,
ref= (Item**)&outer_field; bool alias_name_used_arg)
fixed= 0; :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg,
Item_direct_ref::cleanup(); alias_name_used_arg),
outer_field->cleanup(); outer_ref(0), in_sum_func(0), found_in_select_list(1)
} {}
void save_in_result_field(bool no_conversions) void save_in_result_field(bool no_conversions)
{ {
outer_field->save_org_in_field(result_field); outer_ref->save_org_in_field(result_field);
} }
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
table_map used_tables() const table_map used_tables() const

View File

@ -68,6 +68,42 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
} }
/*
Compare row signature of two expressions
SYNOPSIS:
cmp_row_type()
item1 the first expression
item2 the second expression
DESCRIPTION
The function checks that two expressions have compatible row signatures
i.e. that the number of columns they return are the same and that if they
are both row expressions then each component from the first expression has
a row signature compatible with the signature of the corresponding component
of the second expression.
RETURN VALUES
1 type incompatibility has been detected
0 otherwise
*/
static int cmp_row_type(Item* item1, Item* item2)
{
uint n= item1->cols();
if (item2->check_cols(n))
return 1;
for (uint i=0; i<n; i++)
{
if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
(item1->element_index(i)->result_type() == ROW_RESULT &&
cmp_row_type(item1->element_index(i), item2->element_index(i))))
return 1;
}
return 0;
}
/* /*
Aggregates result types from the array of items. Aggregates result types from the array of items.
@ -82,14 +118,32 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
This function aggregates result types from the array of items. Found type This function aggregates result types from the array of items. Found type
supposed to be used later for comparison of values of these items. supposed to be used later for comparison of values of these items.
Aggregation itself is performed by the item_cmp_type() function. Aggregation itself is performed by the item_cmp_type() function.
The function also checks compatibility of row signatures for the
submitted items (see the spec for the cmp_row_type function).
RETURN VALUES
1 type incompatibility has been detected
0 otherwise
*/ */
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{ {
uint i; uint i;
type[0]= items[0]->result_type(); type[0]= items[0]->result_type();
for (i= 1 ; i < nitems ; i++) for (i= 1 ; i < nitems ; i++)
{
type[0]= item_cmp_type(type[0], items[i]->result_type()); type[0]= item_cmp_type(type[0], items[i]->result_type());
/*
When aggregating types of two row expressions we have to check
that they have the same cardinality and that each component
of the first row expression has a compatible row signature with
the signature of the corresponding component of the second row
expression.
*/
if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
return 1; // error found: invalid usage of rows
}
return 0;
} }
@ -1305,7 +1359,8 @@ void Item_func_between::fix_length_and_dec()
*/ */
if (!args[0] || !args[1] || !args[2]) if (!args[0] || !args[1] || !args[2])
return; return;
agg_cmp_type(thd, &cmp_type, args, 3); if ( agg_cmp_type(thd, &cmp_type, args, 3))
return;
if (cmp_type == STRING_RESULT && if (cmp_type == STRING_RESULT &&
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1)) agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
return; return;
@ -2021,7 +2076,8 @@ void Item_func_case::fix_length_and_dec()
for (nagg= 0; nagg < ncases/2 ; nagg++) for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2]; agg[nagg+1]= args[nagg*2];
nagg++; nagg++;
agg_cmp_type(thd, &cmp_type, agg, nagg); if (agg_cmp_type(thd, &cmp_type, agg, nagg))
return;
if ((cmp_type == STRING_RESULT) && if ((cmp_type == STRING_RESULT) &&
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1)) agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
return; return;
@ -2710,7 +2766,8 @@ void Item_func_in::fix_length_and_dec()
uint const_itm= 1; uint const_itm= 1;
THD *thd= current_thd; THD *thd= current_thd;
agg_cmp_type(thd, &cmp_type, args, arg_count); if (agg_cmp_type(thd, &cmp_type, args, arg_count))
return;
if (cmp_type == STRING_RESULT && if (cmp_type == STRING_RESULT &&
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))

View File

@ -369,6 +369,8 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
{ {
Item *fake_conds= 0; Item *fake_conds= 0;
SELECT_LEX *select_lex= &thd->lex->select_lex; SELECT_LEX *select_lex= &thd->lex->select_lex;
const char *operation = thd->lex->sql_command == SQLCOM_TRUNCATE ?
"TRUNCATE" : "DELETE";
DBUG_ENTER("mysql_prepare_delete"); DBUG_ENTER("mysql_prepare_delete");
List<Item> all_fields; List<Item> all_fields;
@ -383,14 +385,14 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!table_list->updatable || check_key_in_view(thd, table_list)) if (!table_list->updatable || check_key_in_view(thd, table_list))
{ {
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, operation);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
{ {
TABLE_LIST *duplicate; TABLE_LIST *duplicate;
if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0))) if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
{ {
update_non_unique_table_error(table_list, "DELETE", duplicate); update_non_unique_table_error(table_list, operation, duplicate);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
@ -895,7 +897,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if (!dont_send_ok) if (!dont_send_ok)
{ {
db_type table_type; db_type table_type;
mysql_frm_type(thd, path, &table_type); if (mysql_frm_type(thd, path, &table_type) == FRMTYPE_VIEW)
goto trunc_by_del;
if (table_type == DB_TYPE_UNKNOWN) if (table_type == DB_TYPE_UNKNOWN)
{ {
my_error(ER_NO_SUCH_TABLE, MYF(0), my_error(ER_NO_SUCH_TABLE, MYF(0),

View File

@ -1834,6 +1834,7 @@ bool st_lex::can_use_merged()
case SQLCOM_UPDATE_MULTI: case SQLCOM_UPDATE_MULTI:
case SQLCOM_DELETE: case SQLCOM_DELETE:
case SQLCOM_DELETE_MULTI: case SQLCOM_DELETE_MULTI:
case SQLCOM_TRUNCATE:
case SQLCOM_INSERT: case SQLCOM_INSERT:
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE: case SQLCOM_REPLACE:

View File

@ -278,15 +278,30 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
ref_pointer_array Array of references to Items used in current select ref_pointer_array Array of references to Items used in current select
DESCRIPTION DESCRIPTION
The function fixes fields referenced from inner selects and The function serves 3 purposes - adds fields referenced from inner
also fixes references (Item_ref objects) to these fields. Each field selects to the current select list, resolves which class to use
is fixed as a usual hidden field of the current select - it is added to access referenced item (Item_ref of Item_direct_ref) and fixes
to the all_fields list and the pointer to it is saved in the references (Item_ref objects) to these fields.
ref_pointer_array if latter is provided.
After the field has been fixed we proceed with fixing references If a field isn't already in the select list and the ref_pointer_array
(Item_ref objects) to this field from inner subqueries. If the is provided then it is added to the all_fields list and the pointer to
ref_pointer_array is provided then Item_ref objects is set to it is saved in the ref_pointer_array.
reference element in that array with the pointer to the field.
The class to access the outer field is determined by the following rules:
1. If the outer field isn't used under an aggregate function
then the Item_ref class should be used.
2. If the outer field is used under an aggregate function and this
function is aggregated in the select where the outer field was
resolved or in some more inner select then the Item_direct_ref
class should be used.
The resolution is done here and not at the fix_fields() stage as
it can be done only after sum functions are fixed and pulled up to
selects where they are have to be aggregated.
When the class is chosen it substitutes the original field in the
Item_outer_ref object.
After this we proceed with fixing references (Item_outer_ref objects) to
this field from inner subqueries.
RETURN RETURN
TRUE an error occured TRUE an error occured
@ -299,33 +314,64 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
{ {
Item_outer_ref *ref; Item_outer_ref *ref;
bool res= FALSE; bool res= FALSE;
bool direct_ref= FALSE;
List_iterator<Item_outer_ref> ref_it(select->inner_refs_list); List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
while ((ref= ref_it++)) while ((ref= ref_it++))
{ {
Item_field *item= ref->outer_field; Item *item= ref->outer_ref;
Item **item_ref= ref->ref;
Item_ref *new_ref;
/* /*
TODO: this field item already might be present in the select list. TODO: this field item already might be present in the select list.
In this case instead of adding new field item we could use an In this case instead of adding new field item we could use an
existing one. The change will lead to less operations for copying fields, existing one. The change will lead to less operations for copying fields,
smaller temporary tables and less data passed through filesort. smaller temporary tables and less data passed through filesort.
*/ */
if (ref_pointer_array) if (ref_pointer_array && !ref->found_in_select_list)
{ {
int el= all_fields.elements; int el= all_fields.elements;
ref_pointer_array[el]= (Item*)item; ref_pointer_array[el]= item;
/* Add the field item to the select list of the current select. */ /* Add the field item to the select list of the current select. */
all_fields.push_front((Item*)item); all_fields.push_front(item);
/* /*
If it's needed reset each Item_ref item that refers this field with If it's needed reset each Item_ref item that refers this field with
a new reference taken from ref_pointer_array. a new reference taken from ref_pointer_array.
*/ */
ref->ref= ref_pointer_array + el; item_ref= ref_pointer_array + el;
} }
if (!ref->fixed && ref->fix_fields(thd, 0))
if (ref->in_sum_func)
{ {
res= TRUE; Item_sum *sum_func;
if (ref->in_sum_func->nest_level > select->nest_level)
direct_ref= TRUE;
else
{
for (sum_func= ref->in_sum_func; sum_func &&
sum_func->aggr_level >= select->nest_level;
sum_func= sum_func->in_sum_func)
{
if (sum_func->aggr_level == select->nest_level)
{
direct_ref= TRUE;
break; break;
} }
}
}
}
new_ref= direct_ref ?
new Item_direct_ref(ref->context, item_ref, ref->field_name,
ref->table_name, ref->alias_name_used) :
new Item_ref(ref->context, item_ref, ref->field_name,
ref->table_name, ref->alias_name_used);
if (!new_ref)
return TRUE;
ref->outer_ref= new_ref;
ref->ref= &ref->outer_ref;
if (!ref->fixed && ref->fix_fields(thd, 0))
return TRUE;
thd->used_tables|= item->used_tables(); thd->used_tables|= item->used_tables();
} }
return res; return res;
@ -478,10 +524,6 @@ JOIN::prepare(Item ***rref_pointer_array,
if (having && having->with_sum_func) if (having && having->with_sum_func)
having->split_sum_func2(thd, ref_pointer_array, all_fields, having->split_sum_func2(thd, ref_pointer_array, all_fields,
&having, TRUE); &having, TRUE);
if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
DBUG_RETURN(-1);
if (select_lex->inner_sum_func_list) if (select_lex->inner_sum_func_list)
{ {
Item_sum *end=select_lex->inner_sum_func_list; Item_sum *end=select_lex->inner_sum_func_list;
@ -494,6 +536,10 @@ JOIN::prepare(Item ***rref_pointer_array,
} while (item_sum != end); } while (item_sum != end);
} }
if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
DBUG_RETURN(-1);
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
DBUG_RETURN(-1); DBUG_RETURN(-1);
@ -5214,7 +5260,9 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
} }
else if (keyuse->val->type() == Item::FIELD_ITEM || else if (keyuse->val->type() == Item::FIELD_ITEM ||
(keyuse->val->type() == Item::REF_ITEM && (keyuse->val->type() == Item::REF_ITEM &&
((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF) ) ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
Item_ref::DIRECT_REF) )
return new store_key_field(thd, return new store_key_field(thd,
key_part->field, key_part->field,
key_buff + maybe_null, key_buff + maybe_null,
@ -13539,9 +13587,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
ORDER *ord_iter; ORDER *ord_iter;
for (ord_iter= group; ord_iter; ord_iter= ord_iter->next) for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
if ((*ord_iter->item)->eq(item, 1)) if ((*ord_iter->item)->eq(item, 1))
break; goto next_item;
if (ord_iter)
continue;
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord) if (!ord)
@ -13556,6 +13602,7 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
*prev=ord; *prev=ord;
prev= &ord->next; prev= &ord->next;
} }
next_item:
ref_pointer_array++; ref_pointer_array++;
} }
*prev=0; *prev=0;

View File

@ -414,10 +414,11 @@ static int sort_keys(KEY *a, KEY *b)
which has some duplicates on its right which has some duplicates on its right
RETURN VALUES RETURN VALUES
void 0 ok
1 Error
*/ */
void check_duplicates_in_interval(const char *set_or_name, bool check_duplicates_in_interval(const char *set_or_name,
const char *name, TYPELIB *typelib, const char *name, TYPELIB *typelib,
CHARSET_INFO *cs, unsigned int *dup_val_count) CHARSET_INFO *cs, unsigned int *dup_val_count)
{ {
@ -433,6 +434,13 @@ void check_duplicates_in_interval(const char *set_or_name,
tmp.count--; tmp.count--;
if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs)) if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
{ {
if ((current_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
{
my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
name,*cur_value,set_or_name);
return 1;
}
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_DUPLICATED_VALUE_IN_TYPE, ER_DUPLICATED_VALUE_IN_TYPE,
ER(ER_DUPLICATED_VALUE_IN_TYPE), ER(ER_DUPLICATED_VALUE_IN_TYPE),
@ -440,6 +448,7 @@ void check_duplicates_in_interval(const char *set_or_name,
(*dup_val_count)++; (*dup_val_count)++;
} }
} }
return 0;
} }
@ -575,9 +584,10 @@ int prepare_create_field(create_field *sql_field,
if (sql_field->charset->state & MY_CS_BINSORT) if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::INTERVAL_FIELD; sql_field->unireg_check=Field::INTERVAL_FIELD;
check_duplicates_in_interval("ENUM",sql_field->field_name, if (check_duplicates_in_interval("ENUM",sql_field->field_name,
sql_field->interval, sql_field->interval,
sql_field->charset, &dup_val_count); sql_field->charset, &dup_val_count))
DBUG_RETURN(1);
break; break;
case FIELD_TYPE_SET: case FIELD_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
@ -585,9 +595,10 @@ int prepare_create_field(create_field *sql_field,
if (sql_field->charset->state & MY_CS_BINSORT) if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::BIT_FIELD; sql_field->unireg_check=Field::BIT_FIELD;
check_duplicates_in_interval("SET",sql_field->field_name, if (check_duplicates_in_interval("SET",sql_field->field_name,
sql_field->interval, sql_field->interval,
sql_field->charset, &dup_val_count); sql_field->charset, &dup_val_count))
DBUG_RETURN(1);
/* Check that count of unique members is not more then 64 */ /* Check that count of unique members is not more then 64 */
if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8) if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8)
{ {

View File

@ -743,6 +743,7 @@ bool st_select_lex::cleanup()
error= (bool) ((uint) error | (uint) lex_unit->cleanup()); error= (bool) ((uint) error | (uint) lex_unit->cleanup());
} }
non_agg_fields.empty(); non_agg_fields.empty();
inner_refs_list.empty();
DBUG_RETURN(error); DBUG_RETURN(error);
} }