Fixed UNION fields type/length detecting
This commit is contained in:
parent
4883d21b29
commit
7191ea0ae3
@ -53,7 +53,7 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
|
|||||||
4 d
|
4 d
|
||||||
5 f
|
5 f
|
||||||
6 e
|
6 e
|
||||||
7 g
|
7 gg
|
||||||
select a,b from t1 union select a,b from t1;
|
select a,b from t1 union select a,b from t1;
|
||||||
a b
|
a b
|
||||||
1 a
|
1 a
|
||||||
@ -449,10 +449,10 @@ INSERT INTO t2 (id, id_master, text1, text2) VALUES("4", "1",
|
|||||||
SELECT 1 AS id_master, 1 AS id, NULL AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
SELECT 1 AS id_master, 1 AS id, NULL AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
||||||
id_master id text1 text2
|
id_master id text1 text2
|
||||||
1 1 NULL ABCDE
|
1 1 NULL ABCDE
|
||||||
1 1 bar1
|
1 1 foo1 bar1
|
||||||
1 2 bar2
|
1 2 foo2 bar2
|
||||||
1 3 NULL bar3
|
1 3 NULL bar3
|
||||||
1 4 bar4
|
1 4 foo4 bar4
|
||||||
SELECT 1 AS id_master, 1 AS id, 'ABCDE' AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
SELECT 1 AS id_master, 1 AS id, 'ABCDE' AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
||||||
id_master id text1 text2
|
id_master id text1 text2
|
||||||
1 1 ABCDE ABCDE
|
1 1 ABCDE ABCDE
|
||||||
@ -523,3 +523,204 @@ pla_id matintnum
|
|||||||
105 c
|
105 c
|
||||||
0 0
|
0 0
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
create table t1 SELECT "a" as a UNION select "aa" as a;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
a
|
||||||
|
aa
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(2) NOT NULL default ''
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT 12 as a UNION select "aa" as a;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
12
|
||||||
|
aa
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(2) NOT NULL default ''
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT 12 as a UNION select 12.2 as a;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
12.0
|
||||||
|
12.2
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` double(4,1) NOT NULL default '0.0'
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t2 (it1 tinyint, it2 tinyint not null, i int not null, f float, d double, y year, da date, dt datetime, sc char(10), sv varchar(10), b blob);
|
||||||
|
insert into t2 values (NULL, 1, 3, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest');
|
||||||
|
create table t1 SELECT it2 from t2 UNION select it1 from t2;
|
||||||
|
select * from t1;
|
||||||
|
it2
|
||||||
|
1
|
||||||
|
NULL
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`it2` tinyint(4) default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT it2 from t2 UNION select i from t2;
|
||||||
|
select * from t1;
|
||||||
|
it2
|
||||||
|
1
|
||||||
|
3
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`it2` int(11) NOT NULL default '0'
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT i from t2 UNION select f from t2;
|
||||||
|
select * from t1;
|
||||||
|
i
|
||||||
|
3
|
||||||
|
1.5
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`i` float default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select d from t2;
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
1.5
|
||||||
|
2.5
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f` double default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select y from t2;
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
1.5
|
||||||
|
1972
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f` double default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select da from t2;
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
1.5
|
||||||
|
1972-10-22
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f` char(12) binary default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT y from t2 UNION select da from t2;
|
||||||
|
select * from t1;
|
||||||
|
y
|
||||||
|
1972
|
||||||
|
1972-10-22
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`y` char(10) binary default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT y from t2 UNION select dt from t2;
|
||||||
|
select * from t1;
|
||||||
|
y
|
||||||
|
1972
|
||||||
|
1972-10-22 11:50:00
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`y` char(19) binary default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT da from t2 UNION select dt from t2;
|
||||||
|
select * from t1;
|
||||||
|
da
|
||||||
|
1972-10-22 00:00:00
|
||||||
|
1972-10-22 11:50:00
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`da` datetime default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select sc from t2;
|
||||||
|
select * from t1;
|
||||||
|
dt
|
||||||
|
1972-10-22 11:50:00
|
||||||
|
testc
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`dt` char(19) default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select sv from t2;
|
||||||
|
select * from t1;
|
||||||
|
dt
|
||||||
|
1972-10-22 11:50:00
|
||||||
|
testv
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`dt` char(19) default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT sc from t2 UNION select sv from t2;
|
||||||
|
select * from t1;
|
||||||
|
sc
|
||||||
|
testc
|
||||||
|
testv
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`sc` varchar(10) default NULL
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
dt
|
||||||
|
1972-10-22 11:50:00
|
||||||
|
tetetetetest
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`dt` blob
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT sv from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
sv
|
||||||
|
testv
|
||||||
|
tetetetetest
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`sv` blob
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
i
|
||||||
|
3
|
||||||
|
2.5
|
||||||
|
tetetetetest
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`i` blob
|
||||||
|
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1,t2;
|
||||||
|
@ -302,3 +302,85 @@ insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd'
|
|||||||
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
||||||
SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id union SELECT 0, 0;
|
SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id union SELECT 0, 0;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# types conversions
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
create table t1 SELECT "a" as a UNION select "aa" as a;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT 12 as a UNION select "aa" as a;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT 12 as a UNION select 12.2 as a;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t2 (it1 tinyint, it2 tinyint not null, i int not null, f float, d double, y year, da date, dt datetime, sc char(10), sv varchar(10), b blob);
|
||||||
|
insert into t2 values (NULL, 1, 3, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest');
|
||||||
|
|
||||||
|
create table t1 SELECT it2 from t2 UNION select it1 from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT it2 from t2 UNION select i from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT i from t2 UNION select f from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select d from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select y from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT f from t2 UNION select da from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT y from t2 UNION select da from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT y from t2 UNION select dt from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT da from t2 UNION select dt from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select sc from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select sv from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT sc from t2 UNION select sv from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT dt from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT sv from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2;
|
||||||
|
select * from t1;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1,t2;
|
||||||
|
48
sql/field.h
48
sql/field.h
@ -230,6 +230,24 @@ public:
|
|||||||
virtual bool has_charset(void) const { return FALSE; }
|
virtual bool has_charset(void) const { return FALSE; }
|
||||||
virtual void set_charset(CHARSET_INFO *charset) { }
|
virtual void set_charset(CHARSET_INFO *charset) { }
|
||||||
void set_warning(const unsigned int level, const unsigned int code);
|
void set_warning(const unsigned int level, const unsigned int code);
|
||||||
|
/*
|
||||||
|
number which describe preferences of field type converion,
|
||||||
|
for example, if we have int and float, float is prefered as more general
|
||||||
|
|
||||||
|
ennumiration begins from:
|
||||||
|
100 for int types
|
||||||
|
300 for float point
|
||||||
|
500 time/date
|
||||||
|
700 string
|
||||||
|
*/
|
||||||
|
virtual uint convert_order()= 0;
|
||||||
|
/*
|
||||||
|
Is this type is compatible with given
|
||||||
|
(given can be stored in it)
|
||||||
|
Should take care only of types 'less' then current
|
||||||
|
*/
|
||||||
|
virtual bool convert_order_compatible(uint order) { return 0; }
|
||||||
|
|
||||||
friend bool reopen_table(THD *,struct st_table *,bool);
|
friend bool reopen_table(THD *,struct st_table *,bool);
|
||||||
friend int cre_myisam(my_string name, register TABLE *form, uint options,
|
friend int cre_myisam(my_string name, register TABLE *form, uint options,
|
||||||
ulonglong auto_increment_value);
|
ulonglong auto_increment_value);
|
||||||
@ -334,6 +352,7 @@ public:
|
|||||||
void overflow(bool negative);
|
void overflow(bool negative);
|
||||||
bool zero_pack() const { return 0; }
|
bool zero_pack() const { return 0; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 130; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -369,6 +388,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return 1; }
|
uint32 pack_length() const { return 1; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 100; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -404,6 +424,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return 2; }
|
uint32 pack_length() const { return 2; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 101; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -434,6 +455,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return 3; }
|
uint32 pack_length() const { return 3; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 102; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -469,6 +491,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return 4; }
|
uint32 pack_length() const { return 4; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 103; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -507,6 +530,7 @@ public:
|
|||||||
uint32 pack_length() const { return 8; }
|
uint32 pack_length() const { return 8; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool store_for_compare() { return 1; }
|
bool store_for_compare() { return 1; }
|
||||||
|
uint convert_order() { return 104; }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -540,6 +564,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return sizeof(float); }
|
uint32 pack_length() const { return sizeof(float); }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 300; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -573,6 +598,7 @@ public:
|
|||||||
void sort_string(char *buff,uint length);
|
void sort_string(char *buff,uint length);
|
||||||
uint32 pack_length() const { return sizeof(double); }
|
uint32 pack_length() const { return sizeof(double); }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 301; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -606,6 +632,7 @@ public:
|
|||||||
uint32 pack_length() const { return 0; }
|
uint32 pack_length() const { return 0; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
|
uint convert_order() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -649,6 +676,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool get_date(TIME *ltime,uint fuzzydate);
|
bool get_date(TIME *ltime,uint fuzzydate);
|
||||||
bool get_time(TIME *ltime);
|
bool get_time(TIME *ltime);
|
||||||
|
uint convert_order() { return 520; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<520; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -674,6 +703,8 @@ public:
|
|||||||
String *val_str(String*,String *);
|
String *val_str(String*,String *);
|
||||||
bool send_binary(Protocol *protocol);
|
bool send_binary(Protocol *protocol);
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
|
uint convert_order() { return 501; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<520; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -706,6 +737,8 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool store_for_compare() { return 1; }
|
bool store_for_compare() { return 1; }
|
||||||
bool zero_pack() const { return 1; }
|
bool zero_pack() const { return 1; }
|
||||||
|
uint convert_order() { return 502; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<520; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Field_newdate :public Field_str {
|
class Field_newdate :public Field_str {
|
||||||
@ -737,6 +770,8 @@ public:
|
|||||||
bool zero_pack() const { return 1; }
|
bool zero_pack() const { return 1; }
|
||||||
bool get_date(TIME *ltime,uint fuzzydate);
|
bool get_date(TIME *ltime,uint fuzzydate);
|
||||||
bool get_time(TIME *ltime);
|
bool get_time(TIME *ltime);
|
||||||
|
uint convert_order() { return 503; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<520; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -770,6 +805,8 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
bool store_for_compare() { return 1; }
|
bool store_for_compare() { return 1; }
|
||||||
bool zero_pack() const { return 1; }
|
bool zero_pack() const { return 1; }
|
||||||
|
uint convert_order() { return 504; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<520; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -807,6 +844,8 @@ public:
|
|||||||
bool zero_pack() const { return 1; }
|
bool zero_pack() const { return 1; }
|
||||||
bool get_date(TIME *ltime,uint fuzzydate);
|
bool get_date(TIME *ltime,uint fuzzydate);
|
||||||
bool get_time(TIME *ltime);
|
bool get_time(TIME *ltime);
|
||||||
|
uint convert_order() { return 530; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord<=501; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -851,6 +890,7 @@ public:
|
|||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
|
uint convert_order() { return 700; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -894,6 +934,7 @@ public:
|
|||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
|
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
|
uint convert_order() { return 701; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -983,6 +1024,7 @@ public:
|
|||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
|
uint convert_order() { return 701; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1011,6 +1053,8 @@ public:
|
|||||||
|
|
||||||
void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
|
void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
|
||||||
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
|
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
|
||||||
|
uint convert_order() { return 750; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord < 750; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1052,6 +1096,8 @@ public:
|
|||||||
bool optimize_range(uint idx) { return 0; }
|
bool optimize_range(uint idx) { return 0; }
|
||||||
bool eq_def(Field *field);
|
bool eq_def(Field *field);
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
|
uint convert_order() { return 30; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord < 30; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1077,6 +1123,8 @@ public:
|
|||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
enum_field_types real_type() const { return FIELD_TYPE_SET; }
|
enum_field_types real_type() const { return FIELD_TYPE_SET; }
|
||||||
bool has_charset(void) const { return TRUE; }
|
bool has_charset(void) const { return TRUE; }
|
||||||
|
uint convert_order() { return 40; }
|
||||||
|
bool convert_order_compatible(uint ord) { return ord < 40; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
121
sql/item.cc
121
sql/item.cc
@ -312,7 +312,7 @@ void Item_field::set_field(Field *field_par)
|
|||||||
const char *Item_ident::full_name() const
|
const char *Item_ident::full_name() const
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
if (!table_name)
|
if (!table_name || !field_name)
|
||||||
return field_name ? field_name : name ? name : "tmp_field";
|
return field_name ? field_name : name ? name : "tmp_field";
|
||||||
if (db_name && db_name[0])
|
if (db_name && db_name[0])
|
||||||
{
|
{
|
||||||
@ -1876,6 +1876,8 @@ void Item_cache_str::store(Item *item)
|
|||||||
}
|
}
|
||||||
collation.set(item->collation);
|
collation.set(item->collation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double Item_cache_str::val()
|
double Item_cache_str::val()
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@ -1885,6 +1887,8 @@ double Item_cache_str::val()
|
|||||||
else
|
else
|
||||||
return (double)0;
|
return (double)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_cache_str::val_int()
|
longlong Item_cache_str::val_int()
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@ -1895,6 +1899,7 @@ longlong Item_cache_str::val_int()
|
|||||||
return (longlong)0;
|
return (longlong)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_cache_row::allocate(uint num)
|
bool Item_cache_row::allocate(uint num)
|
||||||
{
|
{
|
||||||
item_count= num;
|
item_count= num;
|
||||||
@ -1903,6 +1908,7 @@ bool Item_cache_row::allocate(uint num)
|
|||||||
(Item_cache **) thd->calloc(sizeof(Item_cache *)*item_count)));
|
(Item_cache **) thd->calloc(sizeof(Item_cache *)*item_count)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_cache_row::setup(Item * item)
|
bool Item_cache_row::setup(Item * item)
|
||||||
{
|
{
|
||||||
example= item;
|
example= item;
|
||||||
@ -1919,6 +1925,7 @@ bool Item_cache_row::setup(Item * item)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_cache_row::store(Item * item)
|
void Item_cache_row::store(Item * item)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
@ -1930,6 +1937,7 @@ void Item_cache_row::store(Item * item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_cache_row::illegal_method_call(const char *method)
|
void Item_cache_row::illegal_method_call(const char *method)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_cache_row::illegal_method_call");
|
DBUG_ENTER("Item_cache_row::illegal_method_call");
|
||||||
@ -1939,6 +1947,7 @@ void Item_cache_row::illegal_method_call(const char *method)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_cache_row::check_cols(uint c)
|
bool Item_cache_row::check_cols(uint c)
|
||||||
{
|
{
|
||||||
if (c != item_count)
|
if (c != item_count)
|
||||||
@ -1949,6 +1958,7 @@ bool Item_cache_row::check_cols(uint c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_cache_row::null_inside()
|
bool Item_cache_row::null_inside()
|
||||||
{
|
{
|
||||||
for (uint i= 0; i < item_count; i++)
|
for (uint i= 0; i < item_count; i++)
|
||||||
@ -1968,6 +1978,7 @@ bool Item_cache_row::null_inside()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_cache_row::bring_value()
|
void Item_cache_row::bring_value()
|
||||||
{
|
{
|
||||||
for (uint i= 0; i < item_count; i++)
|
for (uint i= 0; i < item_count; i++)
|
||||||
@ -1975,6 +1986,114 @@ void Item_cache_row::bring_value()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
||||||
|
:Item(thd, *item), item_type(item->result_type())
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(item->fixed);
|
||||||
|
if (item->type() == Item::FIELD_ITEM)
|
||||||
|
{
|
||||||
|
Item_field *fitem= (Item_field*) item;
|
||||||
|
field_example= (Field*) thd->memdup((const char*)fitem->field,
|
||||||
|
fitem->field->size_of());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
field_example= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT
|
||||||
|
static Item_result type_convertor[4][4]=
|
||||||
|
{{STRING_RESULT, STRING_RESULT, STRING_RESULT, ROW_RESULT},
|
||||||
|
{STRING_RESULT, REAL_RESULT, REAL_RESULT, ROW_RESULT},
|
||||||
|
{STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT},
|
||||||
|
{ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT}};
|
||||||
|
|
||||||
|
void Item_type_holder::join_types(THD *thd, Item *item)
|
||||||
|
{
|
||||||
|
bool change_field= 0, skip_store_field= 0;
|
||||||
|
Item_result new_type= type_convertor[item_type][item->result_type()];
|
||||||
|
|
||||||
|
// we have both fields
|
||||||
|
if (field_example && item->type() == Item::FIELD_ITEM)
|
||||||
|
{
|
||||||
|
Field *field= ((Item_field *)item)->field;
|
||||||
|
|
||||||
|
// is new field better
|
||||||
|
if ((change_field=
|
||||||
|
field_example->convert_order() < field->convert_order()))
|
||||||
|
{
|
||||||
|
// is it compatible?
|
||||||
|
if (field->convert_order_compatible(field_example->convert_order()))
|
||||||
|
skip_store_field= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if old field can't store value of 'worse' new field we will make
|
||||||
|
decision about result field tipe based only on Item result type
|
||||||
|
*/
|
||||||
|
if (field_example->convert_order_compatible(field->convert_order()))
|
||||||
|
skip_store_field= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// size/type should be changed
|
||||||
|
if (change_field ||
|
||||||
|
(new_type != item_type) ||
|
||||||
|
(max_length < item->max_length) ||
|
||||||
|
((new_type == INT_RESULT) &&
|
||||||
|
(decimals < item->decimals)) ||
|
||||||
|
(!maybe_null && item->maybe_null))
|
||||||
|
{
|
||||||
|
// new field has some parameters worse then current
|
||||||
|
skip_store_field|= (change_field &&
|
||||||
|
(max_length > item->max_length) ||
|
||||||
|
((new_type == INT_RESULT) &&
|
||||||
|
(decimals > item->decimals)) ||
|
||||||
|
(maybe_null && !item->maybe_null));
|
||||||
|
if (skip_store_field || item->type() != Item::FIELD_ITEM)
|
||||||
|
field_example= 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
we do not need following, because we use mem_root
|
||||||
|
if (field_example)
|
||||||
|
thd->free(field_example)
|
||||||
|
*/
|
||||||
|
Item_field *fitem= (Item_field*) item;
|
||||||
|
field_example= (Field*) thd->memdup((const char*)fitem->field,
|
||||||
|
fitem->field->size_of());
|
||||||
|
}
|
||||||
|
max_length= max(max_length, item->max_length);
|
||||||
|
decimals= max(decimals, item->decimals);
|
||||||
|
maybe_null|= item->maybe_null;
|
||||||
|
item_type= new_type;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(item_type != ROW_RESULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Item_type_holder::val()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0); // should never be called
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item_type_holder::val_int()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0); // should never be called
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String *Item_type_holder::val_str(String*)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0); // should never be called
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instantiate templates
|
** Instantiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
32
sql/item.h
32
sql/item.h
@ -98,7 +98,7 @@ public:
|
|||||||
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
|
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
|
||||||
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
||||||
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
|
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
|
||||||
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM};
|
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER};
|
||||||
|
|
||||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||||
|
|
||||||
@ -371,17 +371,17 @@ class Item_int :public Item
|
|||||||
public:
|
public:
|
||||||
const longlong value;
|
const longlong value;
|
||||||
Item_int(int32 i,uint length=11) :value((longlong) i)
|
Item_int(int32 i,uint length=11) :value((longlong) i)
|
||||||
{ max_length=length;}
|
{ max_length=length; fixed= 1; }
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
Item_int(longlong i,uint length=21) :value(i)
|
Item_int(longlong i,uint length=21) :value(i)
|
||||||
{ max_length=length;}
|
{ max_length=length; fixed= 1;}
|
||||||
#endif
|
#endif
|
||||||
Item_int(const char *str_arg,longlong i,uint length) :value(i)
|
Item_int(const char *str_arg,longlong i,uint length) :value(i)
|
||||||
{ max_length=length; name=(char*) str_arg;}
|
{ max_length=length; name=(char*) str_arg; fixed= 1; }
|
||||||
Item_int(const char *str_arg) :
|
Item_int(const char *str_arg) :
|
||||||
value(str_arg[0] == '-' ? strtoll(str_arg,(char**) 0,10) :
|
value(str_arg[0] == '-' ? strtoll(str_arg,(char**) 0,10) :
|
||||||
(longlong) strtoull(str_arg,(char**) 0,10))
|
(longlong) strtoull(str_arg,(char**) 0,10))
|
||||||
{ max_length= (uint) strlen(str_arg); name=(char*) str_arg;}
|
{ max_length= (uint) strlen(str_arg); name=(char*) str_arg; fixed= 1; }
|
||||||
enum Type type() const { return INT_ITEM; }
|
enum Type type() const { return INT_ITEM; }
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
enum Item_result result_type () const { return INT_RESULT; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
|
||||||
@ -969,6 +969,28 @@ public:
|
|||||||
void bring_value();
|
void bring_value();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used to store type. name, length of Item for UNIONS & derived table
|
||||||
|
*/
|
||||||
|
class Item_type_holder: public Item
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Item_result item_type;
|
||||||
|
Field *field_example;
|
||||||
|
public:
|
||||||
|
Item_type_holder(THD*, Item*);
|
||||||
|
|
||||||
|
Item_result result_type () const { return item_type; }
|
||||||
|
enum Type type() const { return TYPE_HOLDER; }
|
||||||
|
double val();
|
||||||
|
longlong val_int();
|
||||||
|
String *val_str(String*);
|
||||||
|
void join_types(THD *thd, Item *);
|
||||||
|
Field *example() { return field_example; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern Item_buff *new_Item_buff(Item *item);
|
extern Item_buff *new_Item_buff(Item *item);
|
||||||
extern Item_result item_cmp_type(Item_result a,Item_result b);
|
extern Item_result item_cmp_type(Item_result a,Item_result b);
|
||||||
extern Item *resolve_const_item(Item *item,Item *cmp_item);
|
extern Item *resolve_const_item(Item *item,Item *cmp_item);
|
||||||
|
@ -924,7 +924,7 @@ int subselect_single_select_engine::prepare()
|
|||||||
(ORDER*) select_lex->group_list.first,
|
(ORDER*) select_lex->group_list.first,
|
||||||
select_lex->having,
|
select_lex->having,
|
||||||
(ORDER*) 0, select_lex,
|
(ORDER*) 0, select_lex,
|
||||||
select_lex->master_unit(), 0))
|
select_lex->master_unit()))
|
||||||
return 1;
|
return 1;
|
||||||
thd->lex.current_select= save_select;
|
thd->lex.current_select= save_select;
|
||||||
return 0;
|
return 0;
|
||||||
@ -932,7 +932,7 @@ int subselect_single_select_engine::prepare()
|
|||||||
|
|
||||||
int subselect_union_engine::prepare()
|
int subselect_union_engine::prepare()
|
||||||
{
|
{
|
||||||
return unit->prepare(thd, result, 0);
|
return unit->prepare(thd, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int subselect_uniquesubquery_engine::prepare()
|
int subselect_uniquesubquery_engine::prepare()
|
||||||
@ -942,12 +942,12 @@ int subselect_uniquesubquery_engine::prepare()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Item_result set_row(SELECT_LEX *select_lex, Item * item,
|
static Item_result set_row(List<Item> &item_list, Item *item,
|
||||||
Item_cache **row, bool *maybe_null)
|
Item_cache **row, bool *maybe_null)
|
||||||
{
|
{
|
||||||
Item_result res_type= STRING_RESULT;
|
Item_result res_type= STRING_RESULT;
|
||||||
Item *sel_item;
|
Item *sel_item;
|
||||||
List_iterator_fast<Item> li(select_lex->item_list);
|
List_iterator_fast<Item> li(item_list);
|
||||||
for (uint i= 0; (sel_item= li++); i++)
|
for (uint i= 0; (sel_item= li++); i++)
|
||||||
{
|
{
|
||||||
item->max_length= sel_item->max_length;
|
item->max_length= sel_item->max_length;
|
||||||
@ -962,7 +962,7 @@ static Item_result set_row(SELECT_LEX *select_lex, Item * item,
|
|||||||
row[i]->collation.set(sel_item->collation);
|
row[i]->collation.set(sel_item->collation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (select_lex->item_list.elements > 1)
|
if (item_list.elements > 1)
|
||||||
res_type= ROW_RESULT;
|
res_type= ROW_RESULT;
|
||||||
return res_type;
|
return res_type;
|
||||||
}
|
}
|
||||||
@ -970,7 +970,7 @@ static Item_result set_row(SELECT_LEX *select_lex, Item * item,
|
|||||||
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
|
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(row || select_lex->item_list.elements==1);
|
DBUG_ASSERT(row || select_lex->item_list.elements==1);
|
||||||
res_type= set_row(select_lex, item, row, &maybe_null);
|
res_type= set_row(select_lex->item_list, item, row, &maybe_null);
|
||||||
item->collation.set(row[0]->collation);
|
item->collation.set(row[0]->collation);
|
||||||
if (cols() != 1)
|
if (cols() != 1)
|
||||||
maybe_null= 0;
|
maybe_null= 0;
|
||||||
@ -981,44 +981,11 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
|
|||||||
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
|
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
|
||||||
|
|
||||||
if (unit->first_select()->item_list.elements == 1)
|
if (unit->first_select()->item_list.elements == 1)
|
||||||
{
|
res_type= set_row(unit->types, item, row, &maybe_null);
|
||||||
uint32 mlen= 0, len;
|
|
||||||
Item *sel_item= 0;
|
|
||||||
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
|
||||||
{
|
|
||||||
List_iterator_fast<Item> li(sl->item_list);
|
|
||||||
Item *s_item= li++;
|
|
||||||
if ((len= s_item->max_length) > mlen)
|
|
||||||
mlen= len;
|
|
||||||
if (!sel_item)
|
|
||||||
sel_item= s_item;
|
|
||||||
maybe_null= s_item->maybe_null;
|
|
||||||
}
|
|
||||||
item->max_length= mlen;
|
|
||||||
res_type= sel_item->result_type();
|
|
||||||
item->decimals= sel_item->decimals;
|
|
||||||
if (row)
|
|
||||||
{
|
|
||||||
if (!(row[0]= Item_cache::get_cache(res_type)))
|
|
||||||
return;
|
|
||||||
row[0]->set_len_n_dec(mlen, sel_item->decimals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SELECT_LEX *sl= unit->first_select();
|
|
||||||
bool fake= 0;
|
bool fake= 0;
|
||||||
res_type= set_row(sl, item, row, &fake);
|
res_type= set_row(unit->types, item, row, &fake);
|
||||||
for (sl= sl->next_select(); sl; sl= sl->next_select())
|
|
||||||
{
|
|
||||||
List_iterator_fast<Item> li(sl->item_list);
|
|
||||||
Item *sel_item;
|
|
||||||
for (uint i= 0; (sel_item= li++); i++)
|
|
||||||
{
|
|
||||||
if (sel_item->max_length > row[i]->max_length)
|
|
||||||
row[i]->max_length= sel_item->max_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ int mysql_select(THD *thd, Item ***rref_pointer_array,
|
|||||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||||
Item *having, ORDER *proc_param, ulong select_type,
|
Item *having, ORDER *proc_param, ulong select_type,
|
||||||
select_result *result, SELECT_LEX_UNIT *unit,
|
select_result *result, SELECT_LEX_UNIT *unit,
|
||||||
SELECT_LEX *select_lex, bool tables_and_fields_initied);
|
SELECT_LEX *select_lex);
|
||||||
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
|
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
|
||||||
void fix_tables_pointers(SELECT_LEX *select_lex);
|
void fix_tables_pointers(SELECT_LEX *select_lex);
|
||||||
void fix_tables_pointers(SELECT_LEX_UNIT *select_lex);
|
void fix_tables_pointers(SELECT_LEX_UNIT *select_lex);
|
||||||
@ -491,7 +491,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
|||||||
int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
|
int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
|
||||||
select_result *result);
|
select_result *result);
|
||||||
int mysql_union(THD *thd, LEX *lex, select_result *result,
|
int mysql_union(THD *thd, LEX *lex, select_result *result,
|
||||||
SELECT_LEX_UNIT *unit, bool tables_and_fields_initied);
|
SELECT_LEX_UNIT *unit);
|
||||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
|
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
|
||||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||||
Item ***copy_func, Field **from_field,
|
Item ***copy_func, Field **from_field,
|
||||||
@ -675,7 +675,6 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||||||
int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
||||||
List<Item> &item, bool set_query_id,
|
List<Item> &item, bool set_query_id,
|
||||||
List<Item> *sum_func_list, bool allow_sum_func);
|
List<Item> *sum_func_list, bool allow_sum_func);
|
||||||
void unfix_item_list(List<Item> item_list);
|
|
||||||
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
||||||
int setup_ftfuncs(SELECT_LEX* select);
|
int setup_ftfuncs(SELECT_LEX* select);
|
||||||
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
|
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
|
||||||
|
@ -2023,20 +2023,6 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||||||
DBUG_RETURN(test(thd->net.report_error));
|
DBUG_RETURN(test(thd->net.report_error));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Mark all items in list as not fixed (0 assigned to 'fixed' field)
|
|
||||||
|
|
||||||
SYNOPSYS
|
|
||||||
unfix_item_list()
|
|
||||||
item_list - list of items
|
|
||||||
*/
|
|
||||||
void unfix_item_list(List<Item> item_list)
|
|
||||||
{
|
|
||||||
Item *item;
|
|
||||||
List_iterator_fast<Item> it(item_list);
|
|
||||||
while ((item= it++))
|
|
||||||
item->walk(&Item::remove_fixed, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remap table numbers if INSERT ... SELECT
|
Remap table numbers if INSERT ... SELECT
|
||||||
|
@ -946,6 +946,7 @@ class select_union :public select_result {
|
|||||||
bool send_data(List<Item> &items);
|
bool send_data(List<Item> &items);
|
||||||
bool send_eof();
|
bool send_eof();
|
||||||
bool flush();
|
bool flush();
|
||||||
|
void set_table(TABLE *tbl) { table= tbl; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Base subselect interface class */
|
/* Base subselect interface class */
|
||||||
|
@ -62,16 +62,15 @@
|
|||||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
||||||
TABLE_LIST *org_table_list)
|
TABLE_LIST *org_table_list)
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_cursor= unit->first_select();
|
SELECT_LEX *first_select= unit->first_select();
|
||||||
List<Item> item_list;
|
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
int res;
|
int res;
|
||||||
select_union *derived_result;
|
select_union *derived_result;
|
||||||
TABLE_LIST *tables= (TABLE_LIST *)select_cursor->table_list.first;
|
TABLE_LIST *tables= (TABLE_LIST *)first_select->table_list.first;
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
bool is_union= select_cursor->next_select() &&
|
bool is_union= first_select->next_select() &&
|
||||||
select_cursor->next_select()->linkage == UNION_TYPE;
|
first_select->next_select()->linkage == UNION_TYPE;
|
||||||
bool is_subsel= select_cursor->first_inner_unit() ? 1: 0;
|
bool is_subsel= first_select->first_inner_unit() ? 1: 0;
|
||||||
SELECT_LEX *save_current_select= lex->current_select;
|
SELECT_LEX *save_current_select= lex->current_select;
|
||||||
DBUG_ENTER("mysql_derived");
|
DBUG_ENTER("mysql_derived");
|
||||||
|
|
||||||
@ -112,16 +111,12 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||||||
fix_tables_pointers(unit);
|
fix_tables_pointers(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
lex->current_select= select_cursor;
|
if(!(derived_result= new select_union(0)))
|
||||||
TABLE_LIST *first_table= (TABLE_LIST*) select_cursor->table_list.first;
|
DBUG_RETURN(1); // out of memory
|
||||||
/* Setting up. A must if a join or IGNORE, USE or similar are utilised */
|
|
||||||
if (setup_tables(first_table) ||
|
// st_select_lex_unit::prepare coppectly work for single select
|
||||||
setup_wild(thd, first_table, select_cursor->item_list, 0,
|
if ((res= unit->prepare(thd, derived_result)))
|
||||||
select_cursor->with_wild))
|
|
||||||
{
|
|
||||||
res= -1;
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is done in order to redo all field optimisations when any of the
|
This is done in order to redo all field optimisations when any of the
|
||||||
@ -133,30 +128,16 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||||||
cursor->table->clear_query_id= 1;
|
cursor->table->clear_query_id= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
item_list= select_cursor->item_list;
|
|
||||||
select_cursor->with_wild= 0;
|
|
||||||
if (select_cursor->setup_ref_array(thd,
|
|
||||||
select_cursor->order_list.elements +
|
|
||||||
select_cursor->group_list.elements) ||
|
|
||||||
setup_fields(thd, select_cursor->ref_pointer_array, first_table,
|
|
||||||
item_list, 0, 0, 1))
|
|
||||||
{
|
|
||||||
res= -1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
// Item list should be fix_fielded yet another time in JOIN::prepare
|
|
||||||
unfix_item_list(item_list);
|
|
||||||
|
|
||||||
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
||||||
tmp_table_param.field_count= item_list.elements;
|
tmp_table_param.field_count= unit->types.elements;
|
||||||
/*
|
/*
|
||||||
Temp table is created so that it hounours if UNION without ALL is to be
|
Temp table is created so that it hounours if UNION without ALL is to be
|
||||||
processed
|
processed
|
||||||
*/
|
*/
|
||||||
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
|
if (!(table= create_tmp_table(thd, &tmp_table_param, unit->types,
|
||||||
(ORDER*) 0,
|
(ORDER*) 0,
|
||||||
is_union && !unit->union_option, 1,
|
is_union && !unit->union_option, 1,
|
||||||
(select_cursor->options | thd->options |
|
(first_select->options | thd->options |
|
||||||
TMP_TABLE_ALL_COLUMNS),
|
TMP_TABLE_ALL_COLUMNS),
|
||||||
HA_POS_ERROR,
|
HA_POS_ERROR,
|
||||||
org_table_list->alias)))
|
org_table_list->alias)))
|
||||||
@ -164,33 +145,32 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||||||
res= -1;
|
res= -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
derived_result->set_table(table);
|
||||||
if ((derived_result=new select_union(table)))
|
|
||||||
{
|
|
||||||
derived_result->tmp_table_param=tmp_table_param;
|
derived_result->tmp_table_param=tmp_table_param;
|
||||||
unit->offset_limit_cnt= select_cursor->offset_limit;
|
|
||||||
unit->select_limit_cnt= select_cursor->select_limit+
|
unit->offset_limit_cnt= first_select->offset_limit;
|
||||||
select_cursor->offset_limit;
|
unit->select_limit_cnt= first_select->select_limit+
|
||||||
if (unit->select_limit_cnt < select_cursor->select_limit)
|
first_select->offset_limit;
|
||||||
|
if (unit->select_limit_cnt < first_select->select_limit)
|
||||||
unit->select_limit_cnt= HA_POS_ERROR;
|
unit->select_limit_cnt= HA_POS_ERROR;
|
||||||
if (unit->select_limit_cnt == HA_POS_ERROR)
|
if (unit->select_limit_cnt == HA_POS_ERROR)
|
||||||
select_cursor->options&= ~OPTION_FOUND_ROWS;
|
first_select->options&= ~OPTION_FOUND_ROWS;
|
||||||
|
|
||||||
if (is_union)
|
if (is_union)
|
||||||
res= mysql_union(thd, lex, derived_result, unit, 1);
|
res= mysql_union(thd, lex, derived_result, unit);
|
||||||
else
|
else
|
||||||
res= mysql_select(thd, &select_cursor->ref_pointer_array,
|
res= mysql_select(thd, &first_select->ref_pointer_array,
|
||||||
(TABLE_LIST*) select_cursor->table_list.first,
|
(TABLE_LIST*) first_select->table_list.first,
|
||||||
select_cursor->with_wild,
|
first_select->with_wild,
|
||||||
select_cursor->item_list, select_cursor->where,
|
first_select->item_list, first_select->where,
|
||||||
(select_cursor->order_list.elements+
|
(first_select->order_list.elements+
|
||||||
select_cursor->group_list.elements),
|
first_select->group_list.elements),
|
||||||
(ORDER *) select_cursor->order_list.first,
|
(ORDER *) first_select->order_list.first,
|
||||||
(ORDER *) select_cursor->group_list.first,
|
(ORDER *) first_select->group_list.first,
|
||||||
select_cursor->having, (ORDER*) NULL,
|
first_select->having, (ORDER*) NULL,
|
||||||
(select_cursor->options | thd->options |
|
(first_select->options | thd->options |
|
||||||
SELECT_NO_UNLOCK),
|
SELECT_NO_UNLOCK),
|
||||||
derived_result, unit, select_cursor, 1);
|
derived_result, unit, first_select);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -204,7 +184,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||||||
{
|
{
|
||||||
org_table_list->real_name=table->real_name;
|
org_table_list->real_name=table->real_name;
|
||||||
org_table_list->table=table;
|
org_table_list->table=table;
|
||||||
table->derived_select_number= select_cursor->select_number;
|
table->derived_select_number= first_select->select_number;
|
||||||
table->tmp_table= TMP_TABLE;
|
table->tmp_table= TMP_TABLE;
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
org_table_list->grant.privilege= SELECT_ACL;
|
org_table_list->grant.privilege= SELECT_ACL;
|
||||||
@ -227,7 +207,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete derived_result;
|
delete derived_result;
|
||||||
}
|
|
||||||
if (res)
|
if (res)
|
||||||
free_tmp_table(thd, table);
|
free_tmp_table(thd, table);
|
||||||
else
|
else
|
||||||
|
@ -295,7 +295,6 @@ class JOIN;
|
|||||||
class select_union;
|
class select_union;
|
||||||
class st_select_lex_unit: public st_select_lex_node {
|
class st_select_lex_unit: public st_select_lex_node {
|
||||||
protected:
|
protected:
|
||||||
List<Item> item_list;
|
|
||||||
TABLE_LIST result_table_list;
|
TABLE_LIST result_table_list;
|
||||||
select_union *union_result;
|
select_union *union_result;
|
||||||
TABLE *table; /* temporary table using for appending UNION results */
|
TABLE *table; /* temporary table using for appending UNION results */
|
||||||
@ -305,9 +304,13 @@ protected:
|
|||||||
ulong found_rows_for_union;
|
ulong found_rows_for_union;
|
||||||
bool prepared, // prepare phase already performed for UNION (unit)
|
bool prepared, // prepare phase already performed for UNION (unit)
|
||||||
optimized, // optimize phase already performed for UNION (unit)
|
optimized, // optimize phase already performed for UNION (unit)
|
||||||
executed, // already executed
|
executed; // already executed
|
||||||
t_and_f; // used for transferring tables_and_fields_initied UNIT:: methods
|
|
||||||
public:
|
public:
|
||||||
|
// list of fields which points to temporary table for union
|
||||||
|
List<Item> item_list;
|
||||||
|
// list of types of items inside union (used for union & derived tables)
|
||||||
|
List<Item> types;
|
||||||
/*
|
/*
|
||||||
Pointer to 'last' select or pointer to unit where stored
|
Pointer to 'last' select or pointer to unit where stored
|
||||||
global parameters for union
|
global parameters for union
|
||||||
@ -342,7 +345,7 @@ public:
|
|||||||
void exclude_tree();
|
void exclude_tree();
|
||||||
|
|
||||||
/* UNION methods */
|
/* UNION methods */
|
||||||
int prepare(THD *thd, select_result *result, bool tables_and_fields_initied);
|
int prepare(THD *thd, select_result *result);
|
||||||
int exec();
|
int exec();
|
||||||
int cleanup();
|
int cleanup();
|
||||||
|
|
||||||
|
@ -2716,7 +2716,7 @@ mysql_execute_command(THD *thd)
|
|||||||
(ORDER *)NULL,
|
(ORDER *)NULL,
|
||||||
select_lex->options | thd->options |
|
select_lex->options | thd->options |
|
||||||
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
|
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
|
||||||
result, unit, select_lex, 0);
|
result, unit, select_lex);
|
||||||
if (thd->net.report_error)
|
if (thd->net.report_error)
|
||||||
res= -1;
|
res= -1;
|
||||||
delete result;
|
delete result;
|
||||||
|
@ -682,7 +682,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
|
|||||||
|
|
||||||
if (join->prepare(&select_lex->ref_pointer_array, tables,
|
if (join->prepare(&select_lex->ref_pointer_array, tables,
|
||||||
wild_num, conds, og_num, order, group, having, proc,
|
wild_num, conds, og_num, order, group, having, proc,
|
||||||
select_lex, unit, 0))
|
select_lex, unit))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (send_prep_stmt(stmt, fields.elements) ||
|
if (send_prep_stmt(stmt, fields.elements) ||
|
||||||
thd->protocol_simple.send_fields(&fields, 0) ||
|
thd->protocol_simple.send_fields(&fields, 0) ||
|
||||||
|
@ -177,7 +177,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
|
|||||||
|
|
||||||
fix_tables_pointers(lex->all_selects_list);
|
fix_tables_pointers(lex->all_selects_list);
|
||||||
if (select_lex->next_select())
|
if (select_lex->next_select())
|
||||||
res=mysql_union(thd, lex, result, &lex->unit, 0);
|
res=mysql_union(thd, lex, result, &lex->unit);
|
||||||
else
|
else
|
||||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||||
(TABLE_LIST*) select_lex->table_list.first,
|
(TABLE_LIST*) select_lex->table_list.first,
|
||||||
@ -190,7 +190,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
|
|||||||
select_lex->having,
|
select_lex->having,
|
||||||
(ORDER*) lex->proc_list.first,
|
(ORDER*) lex->proc_list.first,
|
||||||
select_lex->options | thd->options,
|
select_lex->options | thd->options,
|
||||||
result, &(lex->unit), &(lex->select_lex), 0);
|
result, &(lex->unit), &(lex->select_lex));
|
||||||
|
|
||||||
/* Don't set res if it's -1 as we may want this later */
|
/* Don't set res if it's -1 as we may want this later */
|
||||||
DBUG_PRINT("info",("res: %d report_error: %d", res,
|
DBUG_PRINT("info",("res: %d report_error: %d", res,
|
||||||
@ -285,8 +285,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
ORDER *order_init, ORDER *group_init,
|
ORDER *order_init, ORDER *group_init,
|
||||||
Item *having_init,
|
Item *having_init,
|
||||||
ORDER *proc_param_init, SELECT_LEX *select,
|
ORDER *proc_param_init, SELECT_LEX *select,
|
||||||
SELECT_LEX_UNIT *unit,
|
SELECT_LEX_UNIT *unit)
|
||||||
bool tables_and_fields_initied)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::prepare");
|
DBUG_ENTER("JOIN::prepare");
|
||||||
|
|
||||||
@ -302,10 +301,8 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
|
|
||||||
/* Check that all tables, fields, conds and order are ok */
|
/* Check that all tables, fields, conds and order are ok */
|
||||||
|
|
||||||
if ((tables_and_fields_initied ? 0 : (setup_tables(tables_list) ||
|
if (setup_tables(tables_list) ||
|
||||||
setup_wild(thd, tables_list,
|
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
||||||
fields_list,
|
|
||||||
&all_fields, wild_num))) ||
|
|
||||||
select_lex->setup_ref_array(thd, og_num) ||
|
select_lex->setup_ref_array(thd, og_num) ||
|
||||||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
||||||
&all_fields, 1) ||
|
&all_fields, 1) ||
|
||||||
@ -1536,7 +1533,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
|||||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||||
Item *having, ORDER *proc_param, ulong select_options,
|
Item *having, ORDER *proc_param, ulong select_options,
|
||||||
select_result *result, SELECT_LEX_UNIT *unit,
|
select_result *result, SELECT_LEX_UNIT *unit,
|
||||||
SELECT_LEX *select_lex, bool tables_and_fields_initied)
|
SELECT_LEX *select_lex)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
bool free_join= 1;
|
bool free_join= 1;
|
||||||
@ -1546,6 +1543,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
|||||||
if (select_lex->join != 0)
|
if (select_lex->join != 0)
|
||||||
{
|
{
|
||||||
join= select_lex->join;
|
join= select_lex->join;
|
||||||
|
// is it single SELECT in derived table, called in derived table creation
|
||||||
|
if (select_lex->linkage != DERIVED_TABLE_TYPE ||
|
||||||
|
(select_options & SELECT_DESCRIBE))
|
||||||
|
{
|
||||||
if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
|
if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
|
||||||
{
|
{
|
||||||
//here is EXPLAIN of subselect or derived table
|
//here is EXPLAIN of subselect or derived table
|
||||||
@ -1559,14 +1560,15 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
|||||||
{
|
{
|
||||||
if (join->prepare(rref_pointer_array, tables, wild_num,
|
if (join->prepare(rref_pointer_array, tables, wild_num,
|
||||||
conds, og_num, order, group, having, proc_param,
|
conds, og_num, order, group, having, proc_param,
|
||||||
select_lex, unit, tables_and_fields_initied))
|
select_lex, unit))
|
||||||
{
|
{
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
join->select_options= select_options;
|
|
||||||
free_join= 0;
|
free_join= 0;
|
||||||
}
|
}
|
||||||
|
join->select_options= select_options;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
join= new JOIN(thd, fields, select_options, result);
|
join= new JOIN(thd, fields, select_options, result);
|
||||||
@ -1574,7 +1576,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
|||||||
thd->used_tables=0; // Updated by setup_fields
|
thd->used_tables=0; // Updated by setup_fields
|
||||||
if (join->prepare(rref_pointer_array, tables, wild_num,
|
if (join->prepare(rref_pointer_array, tables, wild_num,
|
||||||
conds, og_num, order, group, having, proc_param,
|
conds, og_num, order, group, having, proc_param,
|
||||||
select_lex, unit, tables_and_fields_initied))
|
select_lex, unit))
|
||||||
{
|
{
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -4545,6 +4547,115 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
|||||||
Create internal temporary table
|
Create internal temporary table
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create field for temporary table from given field
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
create_tmp_field_from_field()
|
||||||
|
thd Thread handler
|
||||||
|
org_field field from which new field will be created
|
||||||
|
item Item to create a field for
|
||||||
|
table Temporary table
|
||||||
|
modify_item 1 if item->result_field should point to new item.
|
||||||
|
This is relevent for how fill_record() is going to
|
||||||
|
work:
|
||||||
|
If modify_item is 1 then fill_record() will update
|
||||||
|
the record in the original table.
|
||||||
|
If modify_item is 0 then fill_record() will update
|
||||||
|
the temporary table
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 on error
|
||||||
|
new_created field
|
||||||
|
*/
|
||||||
|
static Field* create_tmp_field_from_field(THD *thd,
|
||||||
|
Field* org_field,
|
||||||
|
Item *item,
|
||||||
|
TABLE *table,
|
||||||
|
bool modify_item)
|
||||||
|
{
|
||||||
|
Field *new_field;
|
||||||
|
|
||||||
|
// The following should always be true
|
||||||
|
if ((new_field= org_field->new_field(&thd->mem_root,table)))
|
||||||
|
{
|
||||||
|
if (modify_item)
|
||||||
|
((Item_field *)item)->result_field= new_field;
|
||||||
|
else
|
||||||
|
new_field->field_name= item->name;
|
||||||
|
if (org_field->maybe_null())
|
||||||
|
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
||||||
|
if (org_field->type() == FIELD_TYPE_VAR_STRING)
|
||||||
|
table->db_create_options|= HA_OPTION_PACK_RECORD;
|
||||||
|
}
|
||||||
|
return new_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create field for temporary table using type of given item
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
create_tmp_field_from_item()
|
||||||
|
thd Thread handler
|
||||||
|
item Item to create a field for
|
||||||
|
table Temporary table
|
||||||
|
copy_func If set and item is a function, store copy of item
|
||||||
|
in this array
|
||||||
|
modify_item 1 if item->result_field should point to new item.
|
||||||
|
This is relevent for how fill_record() is going to
|
||||||
|
work:
|
||||||
|
If modify_item is 1 then fill_record() will update
|
||||||
|
the record in the original table.
|
||||||
|
If modify_item is 0 then fill_record() will update
|
||||||
|
the temporary table
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 on error
|
||||||
|
new_created field
|
||||||
|
*/
|
||||||
|
static Field* create_tmp_field_from_item(THD *thd,
|
||||||
|
Item *item,
|
||||||
|
TABLE *table,
|
||||||
|
Item ***copy_func,
|
||||||
|
bool modify_item)
|
||||||
|
{
|
||||||
|
bool maybe_null=item->maybe_null;
|
||||||
|
Field *new_field;
|
||||||
|
LINT_INIT(new_field);
|
||||||
|
|
||||||
|
switch (item->result_type()) {
|
||||||
|
case REAL_RESULT:
|
||||||
|
new_field=new Field_double(item->max_length, maybe_null,
|
||||||
|
item->name, table, item->decimals);
|
||||||
|
break;
|
||||||
|
case INT_RESULT:
|
||||||
|
new_field=new Field_longlong(item->max_length, maybe_null,
|
||||||
|
item->name, table, item->unsigned_flag);
|
||||||
|
break;
|
||||||
|
case STRING_RESULT:
|
||||||
|
if (item->max_length > 255)
|
||||||
|
new_field= new Field_blob(item->max_length, maybe_null,
|
||||||
|
item->name, table,
|
||||||
|
item->collation.collation);
|
||||||
|
else
|
||||||
|
new_field= new Field_string(item->max_length, maybe_null,
|
||||||
|
item->name, table,
|
||||||
|
item->collation.collation);
|
||||||
|
break;
|
||||||
|
case ROW_RESULT:
|
||||||
|
default:
|
||||||
|
// This case should never be choosen
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
new_field= 0; // to satisfy compiler (uninitialized variable)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (copy_func && item->is_result_field())
|
||||||
|
*((*copy_func)++) = item; // Save for copy_funcs
|
||||||
|
if (modify_item)
|
||||||
|
item->set_result_field(new_field);
|
||||||
|
return new_field;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create field for temporary table
|
Create field for temporary table
|
||||||
|
|
||||||
@ -4556,6 +4667,8 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
|||||||
type Type of item (normally item->type)
|
type Type of item (normally item->type)
|
||||||
copy_func If set and item is a function, store copy of item
|
copy_func If set and item is a function, store copy of item
|
||||||
in this array
|
in this array
|
||||||
|
from_field if field will be created using other field as example,
|
||||||
|
pointer example field will be written here
|
||||||
group 1 if we are going to do a relative group by on result
|
group 1 if we are going to do a relative group by on result
|
||||||
modify_item 1 if item->result_field should point to new item.
|
modify_item 1 if item->result_field should point to new item.
|
||||||
This is relevent for how fill_record() is going to
|
This is relevent for how fill_record() is going to
|
||||||
@ -4622,24 +4735,9 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
return 0; // Error
|
return 0; // Error
|
||||||
}
|
}
|
||||||
case Item::FIELD_ITEM:
|
case Item::FIELD_ITEM:
|
||||||
{
|
return create_tmp_field_from_field(thd, (*from_field=
|
||||||
Field *org_field=((Item_field*) item)->field,*new_field;
|
((Item_field*) item)->field),
|
||||||
|
item, table, modify_item);
|
||||||
*from_field=org_field;
|
|
||||||
// The following should always be true
|
|
||||||
if ((new_field= org_field->new_field(&thd->mem_root,table)))
|
|
||||||
{
|
|
||||||
if (modify_item)
|
|
||||||
((Item_field*) item)->result_field= new_field;
|
|
||||||
else
|
|
||||||
new_field->field_name=item->name;
|
|
||||||
if (org_field->maybe_null())
|
|
||||||
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
|
||||||
if (org_field->type()==FIELD_TYPE_VAR_STRING)
|
|
||||||
table->db_create_options|= HA_OPTION_PACK_RECORD;
|
|
||||||
}
|
|
||||||
return new_field;
|
|
||||||
}
|
|
||||||
case Item::FUNC_ITEM:
|
case Item::FUNC_ITEM:
|
||||||
case Item::COND_ITEM:
|
case Item::COND_ITEM:
|
||||||
case Item::FIELD_AVG_ITEM:
|
case Item::FIELD_AVG_ITEM:
|
||||||
@ -4653,40 +4751,14 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
case Item::REF_ITEM:
|
case Item::REF_ITEM:
|
||||||
case Item::NULL_ITEM:
|
case Item::NULL_ITEM:
|
||||||
case Item::VARBIN_ITEM:
|
case Item::VARBIN_ITEM:
|
||||||
|
return create_tmp_field_from_item(thd, item, table,
|
||||||
|
copy_func, modify_item);
|
||||||
|
case Item::TYPE_HOLDER:
|
||||||
{
|
{
|
||||||
bool maybe_null=item->maybe_null;
|
Field *example= ((Item_type_holder *)item)->example();
|
||||||
Field *new_field;
|
if (example)
|
||||||
LINT_INIT(new_field);
|
return create_tmp_field_from_field(thd, example, item, table, 0);
|
||||||
|
return create_tmp_field_from_item(thd, item, table, copy_func, 0);
|
||||||
switch (item->result_type()) {
|
|
||||||
case REAL_RESULT:
|
|
||||||
new_field=new Field_double(item->max_length,maybe_null,
|
|
||||||
item->name,table,item->decimals);
|
|
||||||
break;
|
|
||||||
case INT_RESULT:
|
|
||||||
new_field=new Field_longlong(item->max_length,maybe_null,
|
|
||||||
item->name,table, item->unsigned_flag);
|
|
||||||
break;
|
|
||||||
case STRING_RESULT:
|
|
||||||
if (item->max_length > 255)
|
|
||||||
new_field= new Field_blob(item->max_length,maybe_null,
|
|
||||||
item->name,table,item->collation.collation);
|
|
||||||
else
|
|
||||||
new_field= new Field_string(item->max_length,maybe_null,
|
|
||||||
item->name,table,item->collation.collation);
|
|
||||||
break;
|
|
||||||
case ROW_RESULT:
|
|
||||||
default:
|
|
||||||
// This case should never be choosen
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
new_field= 0; // to satisfy compiler (uninitialized variable)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (copy_func && item->is_result_field())
|
|
||||||
*((*copy_func)++) = item; // Save for copy_funcs
|
|
||||||
if (modify_item)
|
|
||||||
item->set_result_field(new_field);
|
|
||||||
return new_field;
|
|
||||||
}
|
}
|
||||||
default: // Dosen't have to be stored
|
default: // Dosen't have to be stored
|
||||||
return 0;
|
return 0;
|
||||||
@ -9077,7 +9149,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
|||||||
select_lex->having,
|
select_lex->having,
|
||||||
(ORDER*) thd->lex.proc_list.first,
|
(ORDER*) thd->lex.proc_list.first,
|
||||||
select_lex->options | thd->options | SELECT_DESCRIBE,
|
select_lex->options | thd->options | SELECT_DESCRIBE,
|
||||||
result, unit, select_lex, 0);
|
result, unit, select_lex);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ class JOIN :public Sql_alloc
|
|||||||
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
||||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||||
Item *having, ORDER *proc_param, SELECT_LEX *select,
|
Item *having, ORDER *proc_param, SELECT_LEX *select,
|
||||||
SELECT_LEX_UNIT *unit, bool tables_and_fields_initied);
|
SELECT_LEX_UNIT *unit);
|
||||||
int optimize();
|
int optimize();
|
||||||
int reinit();
|
int reinit();
|
||||||
void exec();
|
void exec();
|
||||||
|
144
sql/sql_union.cc
144
sql/sql_union.cc
@ -25,11 +25,11 @@
|
|||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
|
|
||||||
int mysql_union(THD *thd, LEX *lex, select_result *result,
|
int mysql_union(THD *thd, LEX *lex, select_result *result,
|
||||||
SELECT_LEX_UNIT *unit, bool tables_and_fields_initied)
|
SELECT_LEX_UNIT *unit)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_union");
|
DBUG_ENTER("mysql_union");
|
||||||
int res= 0;
|
int res= 0;
|
||||||
if (!(res= unit->prepare(thd, result, tables_and_fields_initied)))
|
if (!(res= unit->prepare(thd, result)))
|
||||||
res= unit->exec();
|
res= unit->exec();
|
||||||
res|= unit->cleanup();
|
res|= unit->cleanup();
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
@ -59,12 +59,6 @@ select_union::~select_union()
|
|||||||
int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
||||||
{
|
{
|
||||||
unit= u;
|
unit= u;
|
||||||
if (not_describe && list.elements != table->fields)
|
|
||||||
{
|
|
||||||
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
|
|
||||||
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,11 +106,11 @@ bool select_union::flush()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
|
int st_select_lex_unit::prepare(THD *thd, select_result *sel_result)
|
||||||
bool tables_and_fields_initied)
|
|
||||||
{
|
{
|
||||||
SELECT_LEX *lex_select_save= thd->lex.current_select;
|
SELECT_LEX *lex_select_save= thd->lex.current_select;
|
||||||
SELECT_LEX *select_cursor,*sl;
|
SELECT_LEX *sl, *first_select;
|
||||||
|
select_result *tmp_result;
|
||||||
DBUG_ENTER("st_select_lex_unit::prepare");
|
DBUG_ENTER("st_select_lex_unit::prepare");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -129,74 +123,33 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
prepared= 1;
|
prepared= 1;
|
||||||
res= 0;
|
res= 0;
|
||||||
found_rows_for_union= first_select_in_union()->options & OPTION_FOUND_ROWS;
|
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
t_and_f= tables_and_fields_initied;
|
|
||||||
|
|
||||||
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
|
bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM));
|
||||||
thd->lex.current_select= sl= select_cursor= first_select_in_union();
|
thd->lex.current_select= sl= first_select= first_select_in_union();
|
||||||
|
found_rows_for_union= first_select->options & OPTION_FOUND_ROWS;
|
||||||
|
|
||||||
/* Global option */
|
/* Global option */
|
||||||
if (t_and_f)
|
|
||||||
|
if (first_select->next_select())
|
||||||
{
|
{
|
||||||
// Item list and tables will be initialized by mysql_derived
|
if (!(tmp_result= union_result= new select_union(0)))
|
||||||
item_list= select_cursor->item_list;
|
goto err;
|
||||||
|
union_result->not_describe= 1;
|
||||||
|
union_result->tmp_table_param= tmp_table_param;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item_list.empty();
|
tmp_result= sel_result;
|
||||||
TABLE_LIST *first_table= (TABLE_LIST*) select_cursor->table_list.first;
|
// single select should be processed like select in p[arantses
|
||||||
|
first_select->braces= 1;
|
||||||
if (setup_tables(first_table) ||
|
|
||||||
setup_wild(thd, first_table, select_cursor->item_list, 0,
|
|
||||||
select_cursor->with_wild))
|
|
||||||
goto err;
|
|
||||||
List_iterator<Item> it(select_cursor->item_list);
|
|
||||||
Item *item;
|
|
||||||
item_list= select_cursor->item_list;
|
|
||||||
select_cursor->with_wild= 0;
|
|
||||||
if (select_cursor->setup_ref_array(thd,
|
|
||||||
select_cursor->order_list.elements +
|
|
||||||
select_cursor->group_list.elements) ||
|
|
||||||
setup_fields(thd, select_cursor->ref_pointer_array, first_table,
|
|
||||||
item_list, 0, 0, 1))
|
|
||||||
goto err;
|
|
||||||
// Item list should be fix_fielded yet another time in JOIN::prepare
|
|
||||||
unfix_item_list(item_list);
|
|
||||||
|
|
||||||
t_and_f= 1;
|
|
||||||
while((item=it++))
|
|
||||||
{
|
|
||||||
item->maybe_null=1;
|
|
||||||
if (item->type() == Item::FIELD_ITEM)
|
|
||||||
((class Item_field *)item)->field->table->maybe_null=1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tmp_table_param.field_count=item_list.elements;
|
|
||||||
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
|
|
||||||
(ORDER*) 0, !union_option,
|
|
||||||
1, (select_cursor->options | thd->options |
|
|
||||||
TMP_TABLE_ALL_COLUMNS),
|
|
||||||
HA_POS_ERROR, (char*) "")))
|
|
||||||
goto err;
|
|
||||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
|
||||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
|
||||||
bzero((char*) &result_table_list,sizeof(result_table_list));
|
|
||||||
result_table_list.db= (char*) "";
|
|
||||||
result_table_list.real_name=result_table_list.alias= (char*) "union";
|
|
||||||
result_table_list.table=table;
|
|
||||||
|
|
||||||
if (!(union_result=new select_union(table)))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
union_result->not_describe=1;
|
|
||||||
union_result->tmp_table_param=tmp_table_param;
|
|
||||||
|
|
||||||
for (;sl; sl= sl->next_select())
|
for (;sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
JOIN *join= new JOIN(thd, sl->item_list,
|
JOIN *join= new JOIN(thd, sl->item_list,
|
||||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||||
union_result);
|
tmp_result);
|
||||||
thd->lex.current_select= sl;
|
thd->lex.current_select= sl;
|
||||||
offset_limit_cnt= sl->offset_limit;
|
offset_limit_cnt= sl->offset_limit;
|
||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
||||||
@ -215,27 +168,76 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
|
|||||||
(ORDER*) sl->group_list.first,
|
(ORDER*) sl->group_list.first,
|
||||||
sl->having,
|
sl->having,
|
||||||
(ORDER*) NULL,
|
(ORDER*) NULL,
|
||||||
sl, this, t_and_f);
|
sl, this);
|
||||||
t_and_f= 0;
|
|
||||||
if (res || thd->is_fatal_error)
|
if (res || thd->is_fatal_error)
|
||||||
goto err;
|
goto err;
|
||||||
|
if (sl == first_select)
|
||||||
|
{
|
||||||
|
types.empty();
|
||||||
|
List_iterator_fast<Item> it(sl->item_list);
|
||||||
|
Item *item;
|
||||||
|
while((item= it++))
|
||||||
|
{
|
||||||
|
types.push_back(new Item_type_holder(thd, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thd->is_fatal_error)
|
||||||
|
goto err; // out of memory
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (types.elements != sl->item_list.elements)
|
||||||
|
{
|
||||||
|
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
|
||||||
|
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
List_iterator_fast<Item> it(sl->item_list);
|
||||||
|
List_iterator_fast<Item> tp(types);
|
||||||
|
Item *type, *item;
|
||||||
|
while((type= tp++, item= it++))
|
||||||
|
{
|
||||||
|
((Item_type_holder*)type)->join_types(thd, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_select->next_select())
|
||||||
|
{
|
||||||
|
tmp_table_param.field_count= types.elements;
|
||||||
|
if (!(table= create_tmp_table(thd, &tmp_table_param, types,
|
||||||
|
(ORDER*) 0, !union_option, 1,
|
||||||
|
(first_select_in_union()->options |
|
||||||
|
thd->options |
|
||||||
|
TMP_TABLE_ALL_COLUMNS),
|
||||||
|
HA_POS_ERROR, (char*) "")))
|
||||||
|
goto err;
|
||||||
|
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||||
|
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||||
|
bzero((char*) &result_table_list, sizeof(result_table_list));
|
||||||
|
result_table_list.db= (char*) "";
|
||||||
|
result_table_list.real_name= result_table_list.alias= (char*) "union";
|
||||||
|
result_table_list.table= table;
|
||||||
|
union_result->set_table(table);
|
||||||
|
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
thd->lex.current_select= lex_select_save;
|
thd->lex.current_select= lex_select_save;
|
||||||
{
|
{
|
||||||
List_iterator<Item> it(select_cursor->item_list);
|
|
||||||
Field **field;
|
Field **field;
|
||||||
|
|
||||||
for (field= table->field; *field; field++)
|
for (field= table->field; *field; field++)
|
||||||
{
|
{
|
||||||
(void) it++;
|
|
||||||
if (item_list.push_back(new Item_field(*field)))
|
if (item_list.push_back(new Item_field(*field)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
first_select->braces= 0; // remove our changes
|
||||||
|
|
||||||
|
thd->lex.current_select= lex_select_save;
|
||||||
|
|
||||||
DBUG_RETURN(res || thd->is_fatal_error ? 1 : 0);
|
DBUG_RETURN(res || thd->is_fatal_error ? 1 : 0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
thd->lex.current_select= lex_select_save;
|
thd->lex.current_select= lex_select_save;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -419,7 +421,7 @@ int st_select_lex_unit::exec()
|
|||||||
(ORDER*)global_parameters->order_list.first,
|
(ORDER*)global_parameters->order_list.first,
|
||||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||||
options | SELECT_NO_UNLOCK,
|
options | SELECT_NO_UNLOCK,
|
||||||
result, this, fake_select_lex, 0);
|
result, this, fake_select_lex);
|
||||||
if (!res)
|
if (!res)
|
||||||
thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
|
thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
|
||||||
/*
|
/*
|
||||||
|
@ -461,7 +461,7 @@ int mysql_multi_update(THD *thd,
|
|||||||
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
|
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
|
||||||
(ORDER *)NULL,
|
(ORDER *)NULL,
|
||||||
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
|
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
|
||||||
result, unit, select_lex, 0);
|
result, unit, select_lex);
|
||||||
delete result;
|
delete result;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user