mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1
into rurik.mysql.com:/home/igor/mysql-4.1
This commit is contained in:
commit
22ae7f3797
59 changed files with 582 additions and 242 deletions
|
@ -92,6 +92,28 @@ EXPORTS
|
|||
mysql_thread_safe
|
||||
mysql_use_result
|
||||
mysql_warning_count
|
||||
mysql_prepare
|
||||
mysql_execute
|
||||
mysql_param_count
|
||||
mysql_bind_param
|
||||
mysql_bind_result
|
||||
mysql_fetch
|
||||
mysql_fetch_column
|
||||
mysql_send_long_data
|
||||
mysql_get_metadata
|
||||
mysql_param_result
|
||||
mysql_stmt_close
|
||||
mysql_stmt_reset
|
||||
mysql_stmt_free_result
|
||||
mysql_stmt_errno
|
||||
mysql_stmt_error
|
||||
mysql_stmt_sqlstate
|
||||
mysql_stmt_affected_rows
|
||||
mysql_stmt_store_result
|
||||
mysql_stmt_row_seek
|
||||
mysql_stmt_row_tell
|
||||
mysql_stmt_data_seek
|
||||
mysql_stmt_num_rows
|
||||
net_buffer_length
|
||||
set_dynamic
|
||||
strcend
|
||||
|
|
|
@ -303,4 +303,5 @@
|
|||
#define ER_WARN_HOSTNAME_WONT_WORK 1284
|
||||
#define ER_UNKNOWN_STORAGE_ENGINE 1285
|
||||
#define ER_WARN_DEPRECATED_SYNTAX 1286
|
||||
#define ER_ERROR_MESSAGES 287
|
||||
#define ER_NON_UPDATABLE_TABLE 1287
|
||||
#define ER_ERROR_MESSAGES 288
|
||||
|
|
|
@ -2903,8 +2903,6 @@ row_search_for_mysql(
|
|||
|
||||
mtr_start(&mtr);
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/* PHASE 2: Try fast adaptive hash index search if possible */
|
||||
|
||||
|
|
|
@ -324,3 +324,59 @@ HEX(_ucs2 0x0123456789ABCDE)
|
|||
SELECT HEX(_ucs2 0x0123456789ABCDEF);
|
||||
HEX(_ucs2 0x0123456789ABCDEF)
|
||||
0123456789ABCDEF
|
||||
SELECT hex(cast(0xAA as char character set ucs2));
|
||||
hex(cast(0xAA as char character set ucs2))
|
||||
00AA
|
||||
SELECT hex(convert(0xAA using ucs2));
|
||||
hex(convert(0xAA using ucs2))
|
||||
00AA
|
||||
CREATE TABLE t1 (a char(10) character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
HEX(a)
|
||||
000A
|
||||
00AA
|
||||
0AAA
|
||||
AAAA
|
||||
000AAAAA
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a varchar(10) character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
HEX(a)
|
||||
000A
|
||||
00AA
|
||||
0AAA
|
||||
AAAA
|
||||
000AAAAA
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a text character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
HEX(a)
|
||||
000A
|
||||
00AA
|
||||
0AAA
|
||||
AAAA
|
||||
000AAAAA
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a mediumtext character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
HEX(a)
|
||||
000A
|
||||
00AA
|
||||
0AAA
|
||||
AAAA
|
||||
000AAAAA
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a longtext character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
HEX(a)
|
||||
000A
|
||||
00AA
|
||||
0AAA
|
||||
AAAA
|
||||
000AAAAA
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -213,7 +213,7 @@ ERROR 42000: You have an error in your SQL syntax. Check the manual that corres
|
|||
create table t1 (a int);
|
||||
insert into t1 values (1),(2),(3);
|
||||
update (select * from t1) as t1 set a = 5;
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use
|
||||
ERROR HY000: The target table t1 of the UPDATE is not updatable.
|
||||
delete from (select * from t1);
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(select * from t1)' at line 1
|
||||
insert into (select * from t1) values (5);
|
||||
|
@ -249,6 +249,31 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
2 DERIVED t1 ALL NULL NULL NULL NULL 2
|
||||
3 UNION t1 ALL NULL NULL NULL NULL 2
|
||||
drop table t1;
|
||||
CREATE TABLE `t1` (
|
||||
`N` int(11) unsigned NOT NULL default '0',
|
||||
`M` tinyint(1) default '0',
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1;
|
||||
Warnings:
|
||||
Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead.
|
||||
INSERT INTO `t1` (N, M) VALUES (1, 0),(1, 0),(1, 0),(2, 0),(2, 0),(3, 0);
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
|
||||
select * from t1;
|
||||
N M
|
||||
1 2
|
||||
1 2
|
||||
1 2
|
||||
2 2
|
||||
2 2
|
||||
3 0
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2;
|
||||
ERROR HY000: The target table P2 of the UPDATE is not updatable.
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
select * from t1;
|
||||
N M
|
||||
3 0
|
||||
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
ERROR HY000: The target table P2 of the DELETE is not updatable.
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
OBJECTID int(11) NOT NULL default '0',
|
||||
SORTORDER int(11) NOT NULL auto_increment,
|
||||
|
|
|
@ -244,7 +244,7 @@ select * from t2;
|
|||
n d
|
||||
1 30
|
||||
1 30
|
||||
DELETE t1, t2 FROM t1 a,t2 b where a.n=b.n;
|
||||
DELETE a, b FROM t1 a,t2 b where a.n=b.n;
|
||||
select * from t1;
|
||||
n d
|
||||
3 2
|
||||
|
|
|
@ -158,7 +158,7 @@ insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
|
|||
('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2),
|
||||
('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
|
||||
('2','2','0',1,7);
|
||||
delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||
delete from m1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||
select * from t1;
|
||||
F1 F2 F3 cnt groupid
|
||||
0 0 0 1 6
|
||||
|
|
|
@ -200,7 +200,7 @@ DROP TABLE t1;
|
|||
|
||||
|
||||
# Bug #2390
|
||||
# Check alignment
|
||||
# Check alignment for constants
|
||||
#
|
||||
SELECT HEX(_ucs2 0x0);
|
||||
SELECT HEX(_ucs2 0x01);
|
||||
|
@ -218,3 +218,39 @@ SELECT HEX(_ucs2 0x0123456789ABC);
|
|||
SELECT HEX(_ucs2 0x0123456789ABCD);
|
||||
SELECT HEX(_ucs2 0x0123456789ABCDE);
|
||||
SELECT HEX(_ucs2 0x0123456789ABCDEF);
|
||||
|
||||
#
|
||||
# Check alignment for from-binary-conversion with CAST and CONVERT
|
||||
#
|
||||
SELECT hex(cast(0xAA as char character set ucs2));
|
||||
SELECT hex(convert(0xAA using ucs2));
|
||||
|
||||
#
|
||||
# Check alignment for string types
|
||||
#
|
||||
CREATE TABLE t1 (a char(10) character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a varchar(10) character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a text character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a mediumtext character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a longtext character set ucs2);
|
||||
INSERT INTO t1 VALUES (0xA),(0xAA),(0xAAA),(0xAAAA),(0xAAAAA);
|
||||
SELECT HEX(a) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
-- the same should be also done with enum and set
|
||||
|
|
|
@ -116,7 +116,7 @@ select mail_id, if(folder.f_description!='', folder.f_description, folder.f_nam
|
|||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1),(2),(3);
|
||||
-- error 1149
|
||||
-- error 1287
|
||||
update (select * from t1) as t1 set a = 5;
|
||||
-- error 1064
|
||||
delete from (select * from t1);
|
||||
|
@ -141,6 +141,24 @@ explain select * from ( select * from t1 union select * from t1) a,(select * fro
|
|||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# multi-update & multi-delete with derived tables
|
||||
#
|
||||
CREATE TABLE `t1` (
|
||||
`N` int(11) unsigned NOT NULL default '0',
|
||||
`M` tinyint(1) default '0',
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t1` (N, M) VALUES (1, 0),(1, 0),(1, 0),(2, 0),(2, 0),(3, 0);
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
|
||||
select * from t1;
|
||||
-- error 1287
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2;
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
select * from t1;
|
||||
-- error 1287
|
||||
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# correct lex->current_select
|
||||
#
|
||||
|
|
|
@ -218,7 +218,7 @@ select * from t2;
|
|||
UPDATE t1 a ,t2 b SET a.d=b.d,b.d=30 WHERE a.n=b.n;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
DELETE t1, t2 FROM t1 a,t2 b where a.n=b.n;
|
||||
DELETE a, b FROM t1 a,t2 b where a.n=b.n;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -126,6 +126,6 @@ insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
|
|||
('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
|
||||
('2','2','0',1,7);
|
||||
|
||||
delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||
delete from m1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
16
sql/field.cc
16
sql/field.cc
|
@ -4055,18 +4055,13 @@ void Field_datetime::sql_type(String &res) const
|
|||
|
||||
/* Copy a string and fill with space */
|
||||
|
||||
static bool use_conversion(CHARSET_INFO *cs1, CHARSET_INFO *cs2)
|
||||
{
|
||||
return (cs1 != &my_charset_bin) && (cs2 != &my_charset_bin) && (cs1!=cs2);
|
||||
}
|
||||
|
||||
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||
{
|
||||
int error= 0;
|
||||
char buff[80];
|
||||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||
/* Convert character set if nesessary */
|
||||
if (use_conversion(cs, field_charset))
|
||||
if (String::needs_conversion(from, length, cs, field_charset))
|
||||
{
|
||||
tmpstr.copy(from, length, cs, field_charset);
|
||||
from= tmpstr.ptr();
|
||||
|
@ -4254,7 +4249,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
char buff[80];
|
||||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||
/* Convert character set if nesessary */
|
||||
if (use_conversion(cs, field_charset))
|
||||
if (String::needs_conversion(from, length, cs, field_charset))
|
||||
{
|
||||
tmpstr.copy(from, length, cs, field_charset);
|
||||
from= tmpstr.ptr();
|
||||
|
@ -4572,7 +4567,8 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||
|
||||
/* Convert character set if nesessary */
|
||||
if ((was_conversion= use_conversion(cs, field_charset)))
|
||||
if ((was_conversion= String::needs_conversion(from, length,
|
||||
cs, field_charset)))
|
||||
{
|
||||
tmpstr.copy(from, length, cs, field_charset);
|
||||
from= tmpstr.ptr();
|
||||
|
@ -5082,7 +5078,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
char buff[80];
|
||||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||
/* Convert character set if nesessary */
|
||||
if (use_conversion(cs, field_charset))
|
||||
if (String::needs_conversion(from, length, cs, field_charset))
|
||||
{
|
||||
tmpstr.copy(from, length, cs, field_charset);
|
||||
from= tmpstr.ptr();
|
||||
|
@ -5263,7 +5259,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
String tmpstr(buff,sizeof(buff), &my_charset_bin);
|
||||
|
||||
/* Convert character set if nesessary */
|
||||
if (use_conversion(cs, field_charset))
|
||||
if (String::needs_conversion(from, length, cs, field_charset))
|
||||
{
|
||||
tmpstr.copy(from, length, cs, field_charset);
|
||||
from= tmpstr.ptr();
|
||||
|
|
62
sql/item.cc
62
sql/item.cc
|
@ -71,18 +71,18 @@ Item::Item():
|
|||
Used for duplicating lists in processing queries with temporary
|
||||
tables
|
||||
*/
|
||||
Item::Item(THD *thd, Item &item):
|
||||
str_value(item.str_value),
|
||||
name(item.name),
|
||||
max_length(item.max_length),
|
||||
marker(item.marker),
|
||||
decimals(item.decimals),
|
||||
maybe_null(item.maybe_null),
|
||||
null_value(item.null_value),
|
||||
unsigned_flag(item.unsigned_flag),
|
||||
with_sum_func(item.with_sum_func),
|
||||
fixed(item.fixed),
|
||||
collation(item.collation)
|
||||
Item::Item(THD *thd, Item *item):
|
||||
str_value(item->str_value),
|
||||
name(item->name),
|
||||
max_length(item->max_length),
|
||||
marker(item->marker),
|
||||
decimals(item->decimals),
|
||||
maybe_null(item->maybe_null),
|
||||
null_value(item->null_value),
|
||||
unsigned_flag(item->unsigned_flag),
|
||||
with_sum_func(item->with_sum_func),
|
||||
fixed(item->fixed),
|
||||
collation(item->collation)
|
||||
{
|
||||
next= thd->free_list; // Put in free list
|
||||
thd->free_list= this;
|
||||
|
@ -110,12 +110,12 @@ Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
|
|||
}
|
||||
|
||||
// Constructor used by Item_field & Item_ref (see Item comment)
|
||||
Item_ident::Item_ident(THD *thd, Item_ident &item):
|
||||
Item_ident::Item_ident(THD *thd, Item_ident *item):
|
||||
Item(thd, item),
|
||||
db_name(item.db_name),
|
||||
table_name(item.table_name),
|
||||
field_name(item.field_name),
|
||||
depended_from(item.depended_from)
|
||||
db_name(item->db_name),
|
||||
table_name(item->table_name),
|
||||
field_name(item->field_name),
|
||||
depended_from(item->depended_from)
|
||||
{}
|
||||
|
||||
bool Item_ident::remove_dependence_processor(byte * arg)
|
||||
|
@ -296,10 +296,10 @@ Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name)
|
|||
}
|
||||
|
||||
// Constructor need to process subselect with temporary tables (see Item)
|
||||
Item_field::Item_field(THD *thd, Item_field &item)
|
||||
Item_field::Item_field(THD *thd, Item_field *item)
|
||||
:Item_ident(thd, item),
|
||||
field(item.field),
|
||||
result_field(item.result_field)
|
||||
field(item->field),
|
||||
result_field(item->result_field)
|
||||
{
|
||||
collation.set(DERIVATION_IMPLICIT);
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ table_map Item_field::used_tables() const
|
|||
|
||||
Item *Item_field::get_tmp_table_item(THD *thd)
|
||||
{
|
||||
Item_field *new_item= new Item_field(thd, *this);
|
||||
Item_field *new_item= new Item_field(thd, this);
|
||||
if (new_item)
|
||||
new_item->field= new_item->result_field;
|
||||
return new_item;
|
||||
|
@ -920,6 +920,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
|
||||
Item_ref *rf;
|
||||
*ref= rf= new Item_ref(last->ref_pointer_array + counter,
|
||||
ref,
|
||||
(char *)table_name,
|
||||
(char *)field_name);
|
||||
if (!rf)
|
||||
|
@ -936,7 +937,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
if (last->having_fix_field)
|
||||
{
|
||||
Item_ref *rf;
|
||||
*ref= rf= new Item_ref((where->db[0]?where->db:0),
|
||||
*ref= rf= new Item_ref(ref, *ref,
|
||||
(where->db[0]?where->db:0),
|
||||
(char *)where->alias,
|
||||
(char *)field_name);
|
||||
if (!rf)
|
||||
|
@ -962,6 +964,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Item_field::cleanup()
|
||||
{
|
||||
Item_ident::cleanup();
|
||||
field= result_field= 0;
|
||||
}
|
||||
|
||||
void Item::init_make_field(Send_field *tmp_field,
|
||||
enum enum_field_types field_type)
|
||||
|
@ -1601,6 +1608,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||
}
|
||||
|
||||
|
||||
void Item_ref::cleanup()
|
||||
{
|
||||
Item_ident::cleanup();
|
||||
if (hook_ptr)
|
||||
*hook_ptr= orig_item;
|
||||
}
|
||||
|
||||
|
||||
void Item_ref::print(String *str)
|
||||
{
|
||||
if (ref && *ref)
|
||||
|
@ -2009,7 +2024,8 @@ void Item_cache_row::bring_value()
|
|||
|
||||
|
||||
Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
||||
:Item(thd, *item), item_type(item->result_type())
|
||||
:Item(thd, item), item_type(item->result_type()),
|
||||
orig_type(item_type)
|
||||
{
|
||||
DBUG_ASSERT(item->fixed);
|
||||
|
||||
|
|
58
sql/item.h
58
sql/item.h
|
@ -124,8 +124,8 @@ public:
|
|||
top AND/OR ctructure of WHERE clause to protect it of
|
||||
optimisation changes in prepared statements
|
||||
*/
|
||||
Item(THD *thd, Item &item);
|
||||
virtual ~Item() { name=0; cleanup(); } /*lint -e1509 */
|
||||
Item(THD *thd, Item *item);
|
||||
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||
void set_name(const char *str,uint length, CHARSET_INFO *cs);
|
||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
virtual void cleanup() { fixed=0; }
|
||||
|
@ -227,6 +227,11 @@ public:
|
|||
|
||||
/* Used in sql_select.cc:eliminate_not_funcs() */
|
||||
virtual Item *neg_transformer() { return NULL; }
|
||||
void delete_self()
|
||||
{
|
||||
cleanup();
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -240,7 +245,7 @@ public:
|
|||
st_select_lex *depended_from;
|
||||
Item_ident(const char *db_name_par,const char *table_name_par,
|
||||
const char *field_name_par);
|
||||
Item_ident::Item_ident(THD *thd, Item_ident &item);
|
||||
Item_ident::Item_ident(THD *thd, Item_ident *item);
|
||||
const char *full_name() const;
|
||||
|
||||
bool remove_dependence_processor(byte * arg);
|
||||
|
@ -259,7 +264,7 @@ public:
|
|||
:Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0)
|
||||
{ collation.set(DERIVATION_IMPLICIT); }
|
||||
// Constructor need to process subselect with temporary tables (see Item)
|
||||
Item_field(THD *thd, Item_field &item);
|
||||
Item_field(THD *thd, Item_field *item);
|
||||
Item_field(Field *field);
|
||||
enum Type type() const { return FIELD_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
|
@ -290,6 +295,7 @@ public:
|
|||
bool get_time(TIME *ltime);
|
||||
bool is_null() { return field->is_null(); }
|
||||
Item *get_tmp_table_item(THD *thd);
|
||||
void cleanup();
|
||||
friend class Item_default_value;
|
||||
friend class Item_insert_value;
|
||||
};
|
||||
|
@ -498,7 +504,6 @@ public:
|
|||
set_name(name_par,0,cs);
|
||||
decimals=NOT_FIXED_DEC;
|
||||
}
|
||||
~Item_string() {}
|
||||
enum Type type() const { return STRING_ITEM; }
|
||||
double val()
|
||||
{
|
||||
|
@ -565,7 +570,6 @@ class Item_varbinary :public Item
|
|||
{
|
||||
public:
|
||||
Item_varbinary(const char *str,uint str_length);
|
||||
~Item_varbinary() {}
|
||||
enum Type type() const { return VARBIN_ITEM; }
|
||||
double val() { return (double) Item_varbinary::val_int(); }
|
||||
longlong val_int();
|
||||
|
@ -582,8 +586,8 @@ public:
|
|||
Field *result_field; /* Save result here */
|
||||
Item_result_field() :result_field(0) {}
|
||||
// Constructor used for Item_sum/Item_cond_and/or (see Item comment)
|
||||
Item_result_field(THD *thd, Item_result_field &item):
|
||||
Item(thd, item), result_field(item.result_field)
|
||||
Item_result_field(THD *thd, Item_result_field *item):
|
||||
Item(thd, item), result_field(item->result_field)
|
||||
{}
|
||||
~Item_result_field() {} /* Required with gcc 2.95 */
|
||||
Field *get_tmp_table_field() { return result_field; }
|
||||
|
@ -602,20 +606,25 @@ public:
|
|||
class Item_ref :public Item_ident
|
||||
{
|
||||
public:
|
||||
Field *result_field; /* Save result here */
|
||||
Field *result_field; /* Save result here */
|
||||
Item **ref;
|
||||
Item_ref(const char *db_par, const char *table_name_par,
|
||||
const char *field_name_par)
|
||||
:Item_ident(db_par,table_name_par,field_name_par),ref(0) {}
|
||||
Item_ref(Item **item, const char *table_name_par, const char *field_name_par)
|
||||
:Item_ident(NullS,table_name_par,field_name_par),ref(item) {}
|
||||
Item **hook_ptr; /* These two to restore */
|
||||
Item *orig_item; /* things in 'cleanup()' */
|
||||
Item_ref(Item **hook, Item *original,const char *db_par,
|
||||
const char *table_name_par, const char *field_name_par)
|
||||
:Item_ident(db_par,table_name_par,field_name_par),ref(0), hook_ptr(hook),
|
||||
orig_item(original) {}
|
||||
Item_ref(Item **item, Item **hook,
|
||||
const char *table_name_par, const char *field_name_par)
|
||||
:Item_ident(NullS,table_name_par,field_name_par),
|
||||
ref(item), hook_ptr(hook), orig_item(hook ? *hook:0) {}
|
||||
// Constructor need to process subselect with temporary tables (see Item)
|
||||
Item_ref(THD *thd, Item_ref &item)
|
||||
:Item_ident(thd, item), ref(item.ref) {}
|
||||
Item_ref(THD *thd, Item_ref *item, Item **hook)
|
||||
:Item_ident(thd, item), ref(item->ref),
|
||||
hook_ptr(hook), orig_item(hook ? *hook : 0) {}
|
||||
enum Type type() const { return REF_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{ return ref && (*ref)->eq(item, binary_cmp); }
|
||||
~Item_ref() { if (ref && (*ref) && (*ref) != this) delete *ref; }
|
||||
double val()
|
||||
{
|
||||
double tmp=(*ref)->val_result();
|
||||
|
@ -660,6 +669,7 @@ public:
|
|||
}
|
||||
Item *real_item() { return *ref; }
|
||||
void print(String *str);
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
class Item_in_subselect;
|
||||
|
@ -670,7 +680,7 @@ protected:
|
|||
public:
|
||||
Item_ref_null_helper(Item_in_subselect* master, Item **item,
|
||||
const char *table_name_par, const char *field_name_par):
|
||||
Item_ref(item, table_name_par, field_name_par), owner(master) {}
|
||||
Item_ref(item, NULL, table_name_par, field_name_par), owner(master) {}
|
||||
double val();
|
||||
longlong val_int();
|
||||
String* val_str(String* s);
|
||||
|
@ -734,7 +744,6 @@ public:
|
|||
name=item->name;
|
||||
cached_field_type= item->field_type();
|
||||
}
|
||||
~Item_copy_string() { delete item; }
|
||||
enum Type type() const { return COPY_STR_ITEM; }
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const { return cached_field_type; }
|
||||
|
@ -984,6 +993,11 @@ public:
|
|||
bool check_cols(uint c);
|
||||
bool null_inside();
|
||||
void bring_value();
|
||||
void cleanup()
|
||||
{
|
||||
Item_cache::cleanup();
|
||||
values= 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -994,6 +1008,7 @@ class Item_type_holder: public Item
|
|||
{
|
||||
protected:
|
||||
Item_result item_type;
|
||||
Item_result orig_type;
|
||||
Field *field_example;
|
||||
public:
|
||||
Item_type_holder(THD*, Item*);
|
||||
|
@ -1005,6 +1020,11 @@ public:
|
|||
String *val_str(String*);
|
||||
bool join_types(THD *thd, Item *);
|
||||
Field *example() { return field_example; }
|
||||
void cleanup()
|
||||
{
|
||||
Item::cleanup();
|
||||
item_type= orig_type;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -496,7 +496,6 @@ longlong Item_func_eq::val_int()
|
|||
return value == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Same as Item_func_eq, but NULL = NULL */
|
||||
|
||||
void Item_func_equal::fix_length_and_dec()
|
||||
|
@ -1652,10 +1651,10 @@ longlong Item_func_bit_and::val_int()
|
|||
return (longlong) (arg1 & arg2);
|
||||
}
|
||||
|
||||
Item_cond::Item_cond(THD *thd, Item_cond &item)
|
||||
Item_cond::Item_cond(THD *thd, Item_cond *item)
|
||||
:Item_bool_func(thd, item),
|
||||
abort_on_null(item.abort_on_null),
|
||||
and_tables_cache(item.and_tables_cache)
|
||||
abort_on_null(item->abort_on_null),
|
||||
and_tables_cache(item->and_tables_cache)
|
||||
{
|
||||
/*
|
||||
here should be following text:
|
||||
|
@ -1754,7 +1753,7 @@ void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
|||
uint el= fields.elements;
|
||||
fields.push_front(item);
|
||||
ref_pointer_array[el]= item;
|
||||
li.replace(new Item_ref(ref_pointer_array + el, 0, item->name));
|
||||
li.replace(new Item_ref(ref_pointer_array + el, li.ref(), 0, item->name));
|
||||
}
|
||||
item->update_used_tables();
|
||||
used_tables_cache|=item->used_tables();
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
Item_bool_func() :Item_int_func() {}
|
||||
Item_bool_func(Item *a) :Item_int_func(a) {}
|
||||
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
|
||||
Item_bool_func(THD *thd, Item_bool_func &item) :Item_int_func(thd, item) {}
|
||||
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
|
||||
void fix_length_and_dec() { decimals=0; max_length=1; }
|
||||
};
|
||||
|
||||
|
@ -197,11 +197,19 @@ public:
|
|||
|
||||
class Item_bool_rowready_func2 :public Item_bool_func2
|
||||
{
|
||||
Item *orig_a, *orig_b; /* propagate_const can change parameters */
|
||||
public:
|
||||
Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b)
|
||||
Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b),
|
||||
orig_a(a), orig_b(b)
|
||||
{
|
||||
allowed_arg_cols= a->cols();
|
||||
}
|
||||
void cleanup()
|
||||
{
|
||||
Item_bool_func2::cleanup();
|
||||
tmp_arg[0]= orig_a;
|
||||
tmp_arg[1]= orig_b;
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_not :public Item_bool_func
|
||||
|
@ -705,10 +713,6 @@ class Item_func_in :public Item_int_func
|
|||
}
|
||||
longlong val_int();
|
||||
void fix_length_and_dec();
|
||||
~Item_func_in()
|
||||
{
|
||||
cleanup(); /* This is not called by Item::~Item() */
|
||||
}
|
||||
void cleanup()
|
||||
{
|
||||
delete array;
|
||||
|
@ -885,10 +889,9 @@ public:
|
|||
list.push_back(i1);
|
||||
list.push_back(i2);
|
||||
}
|
||||
Item_cond(THD *thd, Item_cond &item);
|
||||
Item_cond(THD *thd, Item_cond *item);
|
||||
Item_cond(List<Item> &nlist)
|
||||
:Item_bool_func(), list(nlist), abort_on_null(0) {}
|
||||
~Item_cond() { list.delete_elements(); }
|
||||
bool add(Item *item) { return list.push_back(item); }
|
||||
bool fix_fields(THD *, struct st_table_list *, Item **ref);
|
||||
|
||||
|
@ -911,7 +914,7 @@ class Item_cond_and :public Item_cond
|
|||
public:
|
||||
Item_cond_and() :Item_cond() {}
|
||||
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
|
||||
Item_cond_and(THD *thd, Item_cond_and &item) :Item_cond(thd, item) {}
|
||||
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
|
||||
Item_cond_and(List<Item> &list): Item_cond(list) {}
|
||||
enum Functype functype() const { return COND_AND_FUNC; }
|
||||
longlong val_int();
|
||||
|
@ -919,7 +922,7 @@ public:
|
|||
Item* copy_andor_structure(THD *thd)
|
||||
{
|
||||
Item_cond_and *item;
|
||||
if((item= new Item_cond_and(thd, *this)))
|
||||
if((item= new Item_cond_and(thd, this)))
|
||||
item->copy_andor_arguments(thd, this);
|
||||
return item;
|
||||
}
|
||||
|
@ -931,7 +934,7 @@ class Item_cond_or :public Item_cond
|
|||
public:
|
||||
Item_cond_or() :Item_cond() {}
|
||||
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
|
||||
Item_cond_or(THD *thd, Item_cond_or &item) :Item_cond(thd, item) {}
|
||||
Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
|
||||
Item_cond_or(List<Item> &list): Item_cond(list) {}
|
||||
enum Functype functype() const { return COND_OR_FUNC; }
|
||||
longlong val_int();
|
||||
|
@ -940,7 +943,7 @@ public:
|
|||
Item* copy_andor_structure(THD *thd)
|
||||
{
|
||||
Item_cond_or *item;
|
||||
if((item= new Item_cond_or(thd, *this)))
|
||||
if((item= new Item_cond_or(thd, this)))
|
||||
item->copy_andor_arguments(thd, this);
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -130,13 +130,13 @@ Item_func::Item_func(List<Item> &list)
|
|||
set_arguments(list);
|
||||
}
|
||||
|
||||
Item_func::Item_func(THD *thd, Item_func &item)
|
||||
Item_func::Item_func(THD *thd, Item_func *item)
|
||||
:Item_result_field(thd, item),
|
||||
allowed_arg_cols(item.allowed_arg_cols),
|
||||
arg_count(item.arg_count),
|
||||
used_tables_cache(item.used_tables_cache),
|
||||
not_null_tables_cache(item.not_null_tables_cache),
|
||||
const_item_cache(item.const_item_cache)
|
||||
allowed_arg_cols(item->allowed_arg_cols),
|
||||
arg_count(item->arg_count),
|
||||
used_tables_cache(item->used_tables_cache),
|
||||
not_null_tables_cache(item->not_null_tables_cache),
|
||||
const_item_cache(item->const_item_cache)
|
||||
{
|
||||
if (arg_count)
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ Item_func::Item_func(THD *thd, Item_func &item)
|
|||
if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
||||
return;
|
||||
}
|
||||
memcpy((char*) args, (char*) item.args, sizeof(Item*)*arg_count);
|
||||
memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
|||
uint el= fields.elements;
|
||||
fields.push_front(item);
|
||||
ref_pointer_array[el]= item;
|
||||
*arg= new Item_ref(ref_pointer_array + el, 0, item->name);
|
||||
*arg= new Item_ref(ref_pointer_array + el, arg, 0, item->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,7 @@ public:
|
|||
}
|
||||
Item_func(List<Item> &list);
|
||||
// Constructor used for Item_cond_and/or (see Item comment)
|
||||
Item_func(THD *thd, Item_func &item);
|
||||
~Item_func() {} /* Nothing to do; Items are freed automaticly */
|
||||
Item_func(THD *thd, Item_func *item);
|
||||
bool fix_fields(THD *,struct st_table_list *, Item **ref);
|
||||
table_map used_tables() const;
|
||||
table_map not_null_tables() const;
|
||||
|
@ -200,7 +199,7 @@ public:
|
|||
Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; }
|
||||
Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; }
|
||||
Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; }
|
||||
Item_int_func(THD *thd, Item_int_func &item) :Item_func(thd, item) {}
|
||||
Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {}
|
||||
double val() { return (double) val_int(); }
|
||||
String *val_str(String*str);
|
||||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
|
@ -755,7 +754,6 @@ public:
|
|||
Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {}
|
||||
Item_udf_func(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_func(list), udf(udf_arg) {}
|
||||
~Item_udf_func() {}
|
||||
const char *func_name() const { return udf.name(); }
|
||||
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref)
|
||||
{
|
||||
|
@ -776,7 +774,6 @@ class Item_func_udf_float :public Item_udf_func
|
|||
Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
|
||||
Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_func(udf_arg,list) {}
|
||||
~Item_func_udf_float() {}
|
||||
longlong val_int() { return (longlong) Item_func_udf_float::val(); }
|
||||
double val();
|
||||
String *val_str(String *str);
|
||||
|
@ -790,7 +787,6 @@ public:
|
|||
Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
|
||||
Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_func(udf_arg,list) {}
|
||||
~Item_func_udf_int() {}
|
||||
longlong val_int();
|
||||
double val() { return (double) Item_func_udf_int::val_int(); }
|
||||
String *val_str(String *str);
|
||||
|
@ -805,7 +801,6 @@ public:
|
|||
Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
|
||||
Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_func(udf_arg,list) {}
|
||||
~Item_func_udf_str() {}
|
||||
String *val_str(String *);
|
||||
double val()
|
||||
{
|
||||
|
@ -830,7 +825,6 @@ class Item_func_udf_float :public Item_real_func
|
|||
public:
|
||||
Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {}
|
||||
Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {}
|
||||
~Item_func_udf_float() {}
|
||||
double val() { return 0.0; }
|
||||
};
|
||||
|
||||
|
@ -840,7 +834,6 @@ class Item_func_udf_int :public Item_int_func
|
|||
public:
|
||||
Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {}
|
||||
Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {}
|
||||
~Item_func_udf_int() {}
|
||||
longlong val_int() { return 0; }
|
||||
};
|
||||
|
||||
|
@ -850,7 +843,6 @@ class Item_func_udf_str :public Item_func
|
|||
public:
|
||||
Item_func_udf_str(udf_func *udf_arg) :Item_func() {}
|
||||
Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {}
|
||||
~Item_func_udf_str() {}
|
||||
String *val_str(String *) { null_value=1; return 0; }
|
||||
double val() { null_value=1; return 0.0; }
|
||||
longlong val_int() { null_value=1; return 0; }
|
||||
|
@ -997,7 +989,7 @@ public:
|
|||
|
||||
Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b),
|
||||
join_key(0), ft_handler(0), table(0), master(0), concat(0) { }
|
||||
~Item_func_match()
|
||||
void cleanup()
|
||||
{
|
||||
if (!master && ft_handler)
|
||||
{
|
||||
|
|
|
@ -91,7 +91,7 @@ void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
|||
uint el= fields.elements;
|
||||
fields.push_front(*arg);
|
||||
ref_pointer_array[el]= *arg;
|
||||
*arg= new Item_ref(ref_pointer_array + el, 0, (*arg)->name);
|
||||
*arg= new Item_ref(ref_pointer_array + el, arg, 0, (*arg)->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,12 +34,6 @@ public:
|
|||
with_null(0)
|
||||
{}
|
||||
|
||||
~Item_row()
|
||||
{
|
||||
if (array_holder && items)
|
||||
sql_element_free(items);
|
||||
}
|
||||
|
||||
enum Type type() const { return ROW_ITEM; };
|
||||
void illegal_method_call(const char *);
|
||||
bool is_null() { return null_value; }
|
||||
|
|
|
@ -616,7 +616,8 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array,
|
|||
uint el= fields.elements;
|
||||
fields.push_front(separator);
|
||||
ref_pointer_array[el]= separator;
|
||||
separator= new Item_ref(ref_pointer_array + el, 0, separator->name);
|
||||
separator= new Item_ref(ref_pointer_array + el,
|
||||
&separator, 0, separator->name);
|
||||
}
|
||||
Item_str_func::split_sum_func(ref_pointer_array, fields);
|
||||
}
|
||||
|
@ -1710,7 +1711,7 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
|
|||
uint el= fields.elements;
|
||||
fields.push_front(item);
|
||||
ref_pointer_array[el]= item;
|
||||
item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
||||
item= new Item_ref(ref_pointer_array + el, &item, 0, item->name);
|
||||
}
|
||||
Item_str_func::split_sum_func(ref_pointer_array, fields);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,6 @@ class Item_func_concat_ws :public Item_str_func
|
|||
public:
|
||||
Item_func_concat_ws(Item *a,List<Item> &list)
|
||||
:Item_str_func(list),separator(a) {}
|
||||
~Item_func_concat_ws() { delete separator; }
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
void update_used_tables();
|
||||
|
@ -409,7 +408,6 @@ class Item_func_make_set :public Item_str_func
|
|||
|
||||
public:
|
||||
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
|
||||
~Item_func_make_set() { delete item; }
|
||||
String *val_str(String *str);
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||
{
|
||||
|
|
|
@ -63,6 +63,11 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item_subselect::cleanup()
|
||||
{
|
||||
Item_result_field::cleanup();
|
||||
engine->cleanup();
|
||||
}
|
||||
|
||||
Item_subselect::~Item_subselect()
|
||||
{
|
||||
|
@ -639,7 +644,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
we can use same item for all selects.
|
||||
*/
|
||||
expr= new Item_ref((Item**)optimizer->get_cache(),
|
||||
expr= new Item_ref((Item**)optimizer->get_cache(),
|
||||
NULL,
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name);
|
||||
|
||||
|
@ -789,7 +795,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
|||
(char *) "<list ref>");
|
||||
func=
|
||||
eq_creator.create(new Item_ref((*optimizer->get_cache())->
|
||||
addr(i),
|
||||
addr(i),
|
||||
NULL,
|
||||
(char *)"<no matter>",
|
||||
(char *)in_left_expr_name),
|
||||
func);
|
||||
|
@ -887,6 +894,12 @@ subselect_single_select_engine(st_select_lex *select,
|
|||
this->select_lex= select_lex;
|
||||
}
|
||||
|
||||
void subselect_single_select_engine::cleanup()
|
||||
{
|
||||
prepared= 0;
|
||||
optimized= 0;
|
||||
executed= 0;
|
||||
}
|
||||
|
||||
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
|
||||
select_subselect *result_arg,
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
select_subselect *result);
|
||||
|
||||
~Item_subselect();
|
||||
void cleanup();
|
||||
virtual void reset()
|
||||
{
|
||||
null_value= 1;
|
||||
|
@ -199,6 +200,13 @@ public:
|
|||
|
||||
{}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
Item_exists_subselect::cleanup();
|
||||
abort_on_null= 0;
|
||||
transformed= 0;
|
||||
upper_not= 0;
|
||||
}
|
||||
subs_type substype() { return IN_SUBS; }
|
||||
void reset()
|
||||
{
|
||||
|
@ -261,6 +269,7 @@ public:
|
|||
maybe_null= 0;
|
||||
}
|
||||
virtual ~subselect_engine() {}; // to satisfy compiler
|
||||
virtual void cleanup() {}
|
||||
|
||||
// set_thd should be called before prepare()
|
||||
void set_thd(THD *thd_arg) { thd= thd_arg; }
|
||||
|
@ -290,6 +299,7 @@ public:
|
|||
subselect_single_select_engine(st_select_lex *select,
|
||||
select_subselect *result,
|
||||
Item_subselect *item);
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec();
|
||||
|
|
|
@ -42,17 +42,17 @@ Item_sum::Item_sum(List<Item> &list)
|
|||
}
|
||||
|
||||
// Constructor used in processing select with temporary tebles
|
||||
Item_sum::Item_sum(THD *thd, Item_sum &item):
|
||||
Item_result_field(thd, item), quick_group(item.quick_group)
|
||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||
Item_result_field(thd, item), quick_group(item->quick_group)
|
||||
{
|
||||
arg_count= item.arg_count;
|
||||
arg_count= item->arg_count;
|
||||
if (arg_count <= 2)
|
||||
args=tmp_args;
|
||||
else
|
||||
if (!(args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
|
||||
return;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
args[i]= item.args[i];
|
||||
args[i]= item->args[i];
|
||||
}
|
||||
|
||||
void Item_sum::mark_as_sum_func()
|
||||
|
@ -240,7 +240,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
|
||||
Item *Item_sum_sum::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_sum(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_sum(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -267,7 +267,7 @@ double Item_sum_sum::val()
|
|||
|
||||
Item *Item_sum_count::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_count(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_count(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -301,7 +301,7 @@ longlong Item_sum_count::val_int()
|
|||
|
||||
Item *Item_sum_avg::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_avg(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_avg(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,7 +346,7 @@ double Item_sum_std::val()
|
|||
|
||||
Item *Item_sum_std::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_std(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_std(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -356,7 +356,7 @@ Item *Item_sum_std::copy_or_same(THD* thd)
|
|||
|
||||
Item *Item_sum_variance::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_variance(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_variance(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -497,7 +497,7 @@ Item_sum_hybrid::val_str(String *str)
|
|||
|
||||
Item *Item_sum_min::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_min(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_min(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -550,7 +550,7 @@ bool Item_sum_min::add()
|
|||
|
||||
Item *Item_sum_max::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_max(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_max(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -616,7 +616,7 @@ void Item_sum_bit::clear()
|
|||
|
||||
Item *Item_sum_or::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_or(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_or(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -630,7 +630,7 @@ bool Item_sum_or::add()
|
|||
|
||||
Item *Item_sum_xor::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_xor(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_xor(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -644,7 +644,7 @@ bool Item_sum_xor::add()
|
|||
|
||||
Item *Item_sum_and::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_and(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_and(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1082,8 +1082,9 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
|||
}
|
||||
|
||||
|
||||
Item_sum_count_distinct::~Item_sum_count_distinct()
|
||||
void Item_sum_count_distinct::cleanup()
|
||||
{
|
||||
Item_sum_int::cleanup();
|
||||
/*
|
||||
Free table and tree if they belong to this item (if item have not pointer
|
||||
to original item from which was made copy => it own its objects )
|
||||
|
@ -1095,6 +1096,8 @@ Item_sum_count_distinct::~Item_sum_count_distinct()
|
|||
delete tmp_table_param;
|
||||
if (use_tree)
|
||||
delete_tree(tree);
|
||||
table= 0;
|
||||
use_tree= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1279,7 +1282,7 @@ int Item_sum_count_distinct::tree_to_myisam()
|
|||
|
||||
Item *Item_sum_count_distinct::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_count_distinct(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_count_distinct(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1379,7 +1382,7 @@ bool Item_udf_sum::add()
|
|||
|
||||
Item *Item_sum_udf_float::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_udf_float(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_udf_float(thd, this);
|
||||
}
|
||||
|
||||
double Item_sum_udf_float::val()
|
||||
|
@ -1402,7 +1405,7 @@ String *Item_sum_udf_float::val_str(String *str)
|
|||
|
||||
Item *Item_sum_udf_int::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_udf_int(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_udf_int(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1438,7 +1441,7 @@ void Item_sum_udf_str::fix_length_and_dec()
|
|||
|
||||
Item *Item_sum_udf_str::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_sum_udf_str(thd, *this);
|
||||
return new (&thd->mem_root) Item_sum_udf_str(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1661,6 +1664,23 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
|
|||
}
|
||||
|
||||
|
||||
void Item_func_group_concat::cleanup()
|
||||
{
|
||||
/*
|
||||
Free table and tree if they belong to this item (if item have not pointer
|
||||
to original item from which was made copy => it own its objects )
|
||||
*/
|
||||
if (!original)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
if (table)
|
||||
free_tmp_table(thd, table);
|
||||
delete tmp_table_param;
|
||||
if (tree_mode)
|
||||
delete_tree(tree);
|
||||
}
|
||||
}
|
||||
|
||||
Item_func_group_concat::~Item_func_group_concat()
|
||||
{
|
||||
/*
|
||||
|
@ -1676,18 +1696,13 @@ Item_func_group_concat::~Item_func_group_concat()
|
|||
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
|
||||
warning->set_msg(thd, warn_buff);
|
||||
}
|
||||
if (table)
|
||||
free_tmp_table(thd, table);
|
||||
delete tmp_table_param;
|
||||
if (tree_mode)
|
||||
delete_tree(tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item *Item_func_group_concat::copy_or_same(THD* thd)
|
||||
{
|
||||
return new (&thd->mem_root) Item_func_group_concat(thd, *this);
|
||||
return new (&thd->mem_root) Item_func_group_concat(thd, this);
|
||||
}
|
||||
|
||||
|
||||
|
|
147
sql/item_sum.h
147
sql/item_sum.h
|
@ -57,8 +57,12 @@ public:
|
|||
}
|
||||
Item_sum(List<Item> &list);
|
||||
//Copy constructor, need to perform subselects with temporary tables
|
||||
Item_sum(THD *thd, Item_sum &item);
|
||||
~Item_sum() { result_field=0; }
|
||||
Item_sum(THD *thd, Item_sum *item);
|
||||
void cleanup()
|
||||
{
|
||||
Item_result_field::cleanup();
|
||||
result_field=0;
|
||||
}
|
||||
|
||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||
virtual enum Sumfunctype sum_func () const=0;
|
||||
|
@ -106,7 +110,7 @@ public:
|
|||
Item_sum_num(Item *item_par) :Item_sum(item_par) {}
|
||||
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
|
||||
Item_sum_num(List<Item> &list) :Item_sum(list) {}
|
||||
Item_sum_num(THD *thd, Item_sum_num &item) :Item_sum(thd, item) {}
|
||||
Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {}
|
||||
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||
longlong val_int() { return (longlong) val(); } /* Real as default */
|
||||
String *val_str(String*str);
|
||||
|
@ -119,7 +123,7 @@ class Item_sum_int :public Item_sum_num
|
|||
public:
|
||||
Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
|
||||
Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
|
||||
Item_sum_int(THD *thd, Item_sum_int &item) :Item_sum_num(thd, item) {}
|
||||
Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
|
||||
double val() { return (double) val_int(); }
|
||||
String *val_str(String*str);
|
||||
enum Item_result result_type () const { return INT_RESULT; }
|
||||
|
@ -135,8 +139,8 @@ class Item_sum_sum :public Item_sum_num
|
|||
|
||||
public:
|
||||
Item_sum_sum(Item *item_par) :Item_sum_num(item_par),sum(0.0) {}
|
||||
Item_sum_sum(THD *thd, Item_sum_sum &item)
|
||||
:Item_sum_num(thd, item), sum(item.sum) {}
|
||||
Item_sum_sum(THD *thd, Item_sum_sum *item)
|
||||
:Item_sum_num(thd, item), sum(item->sum) {}
|
||||
enum Sumfunctype sum_func () const {return SUM_FUNC;}
|
||||
void clear();
|
||||
bool add();
|
||||
|
@ -158,9 +162,9 @@ class Item_sum_count :public Item_sum_int
|
|||
Item_sum_count(Item *item_par)
|
||||
:Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0)
|
||||
{}
|
||||
Item_sum_count(THD *thd, Item_sum_count &item)
|
||||
:Item_sum_int(thd, item), count(item.count),
|
||||
used_table_cache(item.used_table_cache)
|
||||
Item_sum_count(THD *thd, Item_sum_count *item)
|
||||
:Item_sum_int(thd, item), count(item->count),
|
||||
used_table_cache(item->used_table_cache)
|
||||
{}
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
bool const_item() const { return !used_table_cache; }
|
||||
|
@ -226,16 +230,16 @@ class Item_sum_count_distinct :public Item_sum_int
|
|||
tmp_table_param(0), tree(&tree_base), original(0), use_tree(0),
|
||||
always_null(0)
|
||||
{ quick_group= 0; }
|
||||
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct &item)
|
||||
:Item_sum_int(thd, item), table(item.table),
|
||||
used_table_cache(item.used_table_cache),
|
||||
field_lengths(item.field_lengths), tmp_table_param(item.tmp_table_param),
|
||||
tree(item.tree), original(&item), key_length(item.key_length),
|
||||
max_elements_in_tree(item.max_elements_in_tree),
|
||||
rec_offset(item.rec_offset), use_tree(item.use_tree),
|
||||
always_null(item.always_null)
|
||||
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
|
||||
:Item_sum_int(thd, item), table(item->table),
|
||||
used_table_cache(item->used_table_cache),
|
||||
field_lengths(item->field_lengths), tmp_table_param(item->tmp_table_param),
|
||||
tree(item->tree), original(item), key_length(item->key_length),
|
||||
max_elements_in_tree(item->max_elements_in_tree),
|
||||
rec_offset(item->rec_offset), use_tree(item->use_tree),
|
||||
always_null(item->always_null)
|
||||
{}
|
||||
~Item_sum_count_distinct();
|
||||
void cleanup();
|
||||
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
|
||||
|
@ -281,8 +285,8 @@ class Item_sum_avg :public Item_sum_num
|
|||
|
||||
public:
|
||||
Item_sum_avg(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
Item_sum_avg(THD *thd, Item_sum_avg &item)
|
||||
:Item_sum_num(thd, item), sum(item.sum), count(item.count) {}
|
||||
Item_sum_avg(THD *thd, Item_sum_avg *item)
|
||||
:Item_sum_num(thd, item), sum(item->sum), count(item->count) {}
|
||||
enum Sumfunctype sum_func () const {return AVG_FUNC;}
|
||||
void clear();
|
||||
bool add();
|
||||
|
@ -333,9 +337,9 @@ class Item_sum_variance : public Item_sum_num
|
|||
|
||||
public:
|
||||
Item_sum_variance(Item *item_par) :Item_sum_num(item_par),count(0) {}
|
||||
Item_sum_variance(THD *thd, Item_sum_variance &item):
|
||||
Item_sum_num(thd, item), sum(item.sum), sum_sqr(item.sum_sqr),
|
||||
count(item.count) {}
|
||||
Item_sum_variance(THD *thd, Item_sum_variance *item):
|
||||
Item_sum_num(thd, item), sum(item->sum), sum_sqr(item->sum_sqr),
|
||||
count(item->count) {}
|
||||
enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
|
||||
void clear();
|
||||
bool add();
|
||||
|
@ -366,7 +370,7 @@ class Item_sum_std :public Item_sum_variance
|
|||
{
|
||||
public:
|
||||
Item_sum_std(Item *item_par) :Item_sum_variance(item_par) {}
|
||||
Item_sum_std(THD *thd, Item_sum_std &item)
|
||||
Item_sum_std(THD *thd, Item_sum_std *item)
|
||||
:Item_sum_variance(thd, item)
|
||||
{}
|
||||
enum Sumfunctype sum_func () const { return STD_FUNC; }
|
||||
|
@ -397,11 +401,11 @@ class Item_sum_hybrid :public Item_sum
|
|||
used_table_cache(~(table_map) 0),
|
||||
cmp_charset(&my_charset_bin)
|
||||
{}
|
||||
Item_sum_hybrid(THD *thd, Item_sum_hybrid &item):
|
||||
Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value),
|
||||
sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type),
|
||||
hybrid_field_type(item.hybrid_field_type),cmp_sign(item.cmp_sign),
|
||||
used_table_cache(item.used_table_cache), cmp_charset(item.cmp_charset) {}
|
||||
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item):
|
||||
Item_sum(thd, item), value(item->value), tmp_value(item->tmp_value),
|
||||
sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type),
|
||||
hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign),
|
||||
used_table_cache(item->used_table_cache), cmp_charset(item->cmp_charset) {}
|
||||
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
bool const_item() const { return !used_table_cache; }
|
||||
|
@ -432,7 +436,7 @@ class Item_sum_min :public Item_sum_hybrid
|
|||
{
|
||||
public:
|
||||
Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
|
||||
Item_sum_min(THD *thd, Item_sum_min &item) :Item_sum_hybrid(thd, item) {}
|
||||
Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
|
||||
enum Sumfunctype sum_func () const {return MIN_FUNC;}
|
||||
|
||||
bool add();
|
||||
|
@ -445,7 +449,7 @@ class Item_sum_max :public Item_sum_hybrid
|
|||
{
|
||||
public:
|
||||
Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
|
||||
Item_sum_max(THD *thd, Item_sum_max &item) :Item_sum_hybrid(thd, item) {}
|
||||
Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
|
||||
enum Sumfunctype sum_func () const {return MAX_FUNC;}
|
||||
|
||||
bool add();
|
||||
|
@ -462,8 +466,8 @@ protected:
|
|||
public:
|
||||
Item_sum_bit(Item *item_par,ulonglong reset_arg)
|
||||
:Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
|
||||
Item_sum_bit(THD *thd, Item_sum_bit &item):
|
||||
Item_sum_int(thd, item), reset_bits(item.reset_bits), bits(item.bits) {}
|
||||
Item_sum_bit(THD *thd, Item_sum_bit *item):
|
||||
Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {}
|
||||
enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
|
||||
void clear();
|
||||
longlong val_int();
|
||||
|
@ -478,7 +482,7 @@ class Item_sum_or :public Item_sum_bit
|
|||
{
|
||||
public:
|
||||
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
|
||||
Item_sum_or(THD *thd, Item_sum_or &item) :Item_sum_bit(thd, item) {}
|
||||
Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
|
||||
bool add();
|
||||
const char *func_name() const { return "bit_or"; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
|
@ -489,7 +493,7 @@ class Item_sum_and :public Item_sum_bit
|
|||
{
|
||||
public:
|
||||
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
|
||||
Item_sum_and(THD *thd, Item_sum_and &item) :Item_sum_bit(thd, item) {}
|
||||
Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
|
||||
bool add();
|
||||
const char *func_name() const { return "bit_and"; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
|
@ -499,7 +503,7 @@ class Item_sum_xor :public Item_sum_bit
|
|||
{
|
||||
public:
|
||||
Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
|
||||
Item_sum_xor(THD *thd, Item_sum_xor &item) :Item_sum_bit(thd, item) {}
|
||||
Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
|
||||
bool add();
|
||||
const char *func_name() const { return "bit_xor"; }
|
||||
Item *copy_or_same(THD* thd);
|
||||
|
@ -521,9 +525,8 @@ public:
|
|||
Item_udf_sum( udf_func *udf_arg, List<Item> &list )
|
||||
:Item_sum( list ), udf(udf_arg)
|
||||
{ quick_group=0;}
|
||||
Item_udf_sum(THD *thd, Item_udf_sum &item)
|
||||
:Item_sum(thd, item), udf(item.udf) {}
|
||||
~Item_udf_sum() {}
|
||||
Item_udf_sum(THD *thd, Item_udf_sum *item)
|
||||
:Item_sum(thd, item), udf(item->udf) {}
|
||||
const char *func_name() const { return udf.name(); }
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
|
@ -546,9 +549,8 @@ class Item_sum_udf_float :public Item_udf_sum
|
|||
Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
|
||||
Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
|
||||
:Item_udf_sum(thd, item) {}
|
||||
~Item_sum_udf_float() {}
|
||||
longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
|
||||
double val();
|
||||
String *val_str(String*str);
|
||||
|
@ -563,9 +565,8 @@ public:
|
|||
Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
|
||||
Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
|
||||
:Item_udf_sum(thd, item) {}
|
||||
~Item_sum_udf_int() {}
|
||||
longlong val_int();
|
||||
double val() { return (double) Item_sum_udf_int::val_int(); }
|
||||
String *val_str(String*str);
|
||||
|
@ -581,9 +582,8 @@ public:
|
|||
Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
|
||||
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
|
||||
:Item_udf_sum(udf_arg,list) {}
|
||||
Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
|
||||
Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
|
||||
:Item_udf_sum(thd, item) {}
|
||||
~Item_sum_udf_str() {}
|
||||
String *val_str(String *);
|
||||
double val()
|
||||
{
|
||||
|
@ -610,9 +610,8 @@ class Item_sum_udf_float :public Item_sum_num
|
|||
public:
|
||||
Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
|
||||
Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
|
||||
:Item_sum_num(thd, item) {}
|
||||
~Item_sum_udf_float() {}
|
||||
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
||||
double val() { return 0.0; }
|
||||
void clear() {}
|
||||
|
@ -626,9 +625,8 @@ class Item_sum_udf_int :public Item_sum_num
|
|||
public:
|
||||
Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
|
||||
Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
|
||||
:Item_sum_num(thd, item) {}
|
||||
~Item_sum_udf_int() {}
|
||||
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
||||
longlong val_int() { return 0; }
|
||||
double val() { return 0; }
|
||||
|
@ -643,9 +641,8 @@ class Item_sum_udf_str :public Item_sum_num
|
|||
public:
|
||||
Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
|
||||
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
|
||||
Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
|
||||
Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
|
||||
:Item_sum_num(thd, item) {}
|
||||
~Item_sum_udf_str() {}
|
||||
String *val_str(String *) { null_value=1; return 0; }
|
||||
double val() { null_value=1; return 0.0; }
|
||||
longlong val_int() { null_value=1; return 0; }
|
||||
|
@ -707,33 +704,35 @@ class Item_func_group_concat : public Item_sum
|
|||
Item_func_group_concat(bool is_distinct,List<Item> *is_select,
|
||||
SQL_LIST *is_order,String *is_separator);
|
||||
|
||||
Item_func_group_concat(THD *thd, Item_func_group_concat &item)
|
||||
Item_func_group_concat(THD *thd, Item_func_group_concat *item)
|
||||
:Item_sum(thd, item),item_thd(thd),
|
||||
tmp_table_param(item.tmp_table_param),
|
||||
max_elements_in_tree(item.max_elements_in_tree),
|
||||
warning(item.warning),
|
||||
warning_available(item.warning_available),
|
||||
key_length(item.key_length),
|
||||
rec_offset(item.rec_offset),
|
||||
tree_mode(item.tree_mode),
|
||||
distinct(item.distinct),
|
||||
warning_for_row(item.warning_for_row),
|
||||
separator(item.separator),
|
||||
tree(item.tree),
|
||||
table(item.table),
|
||||
order(item.order),
|
||||
tables_list(item.tables_list),
|
||||
group_concat_max_len(item.group_concat_max_len),
|
||||
show_elements(item.show_elements),
|
||||
arg_count_order(item.arg_count_order),
|
||||
arg_count_field(item.arg_count_field),
|
||||
arg_show_fields(item.arg_show_fields),
|
||||
count_cut_values(item.count_cut_values),
|
||||
original(&item)
|
||||
tmp_table_param(item->tmp_table_param),
|
||||
max_elements_in_tree(item->max_elements_in_tree),
|
||||
warning(item->warning),
|
||||
warning_available(item->warning_available),
|
||||
key_length(item->key_length),
|
||||
rec_offset(item->rec_offset),
|
||||
tree_mode(item->tree_mode),
|
||||
distinct(item->distinct),
|
||||
warning_for_row(item->warning_for_row),
|
||||
separator(item->separator),
|
||||
tree(item->tree),
|
||||
table(item->table),
|
||||
order(item->order),
|
||||
tables_list(item->tables_list),
|
||||
group_concat_max_len(item->group_concat_max_len),
|
||||
show_elements(item->show_elements),
|
||||
arg_count_order(item->arg_count_order),
|
||||
arg_count_field(item->arg_count_field),
|
||||
arg_show_fields(item->arg_show_fields),
|
||||
count_cut_values(item->count_cut_values),
|
||||
original(item)
|
||||
{
|
||||
quick_group= item.quick_group;
|
||||
quick_group= item->quick_group;
|
||||
};
|
||||
~Item_func_group_concat();
|
||||
void cleanup();
|
||||
|
||||
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
|
||||
const char *func_name() const { return "group_concat"; }
|
||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
||||
|
|
|
@ -38,7 +38,7 @@ class Item_sum_unique_users :public Item_sum_num
|
|||
public:
|
||||
Item_sum_unique_users(Item *name_arg,int start,int end,Item *item_arg)
|
||||
:Item_sum_num(item_arg) {}
|
||||
Item_sum_unique_users(THD *thd, Item_sum_unique_users &item)
|
||||
Item_sum_unique_users(THD *thd, Item_sum_unique_users *item)
|
||||
:Item_sum_num(thd, item) {}
|
||||
double val() { return 0.0; }
|
||||
enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;}
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
}
|
||||
Item *copy_or_same(THD* thd)
|
||||
{
|
||||
return new Item_sum_unique_users(thd, *this);
|
||||
return new Item_sum_unique_users(thd, this);
|
||||
}
|
||||
void print(String *str) { str->append("0.0", 3); }
|
||||
};
|
||||
|
|
|
@ -760,6 +760,11 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
|
|||
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||
const char **end_of_word);
|
||||
|
||||
/* sql_parse.cc */
|
||||
void free_items(Item *item);
|
||||
void cleanup_items(Item *item);
|
||||
|
||||
|
||||
/*
|
||||
External variables
|
||||
*/
|
||||
|
|
|
@ -299,3 +299,4 @@ character-set=latin2
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -293,3 +293,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -301,3 +301,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -295,3 +295,4 @@ character-set=latin7
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -302,3 +302,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=greek
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=latin2
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=ujis
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=euckr
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -294,3 +294,4 @@ character-set=latin2
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -291,3 +291,4 @@ character-set=latin1
|
|||
"MySQL foi inicializado em modo --skip-name-resolve. Você necesita reincializá-lo sem esta opção para este grant funcionar",
|
||||
"Motor de tabela desconhecido '%s'",
|
||||
"'%s' é desatualizado. Use '%s' em seu lugar.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -294,3 +294,4 @@ character-set=latin2
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=koi8r
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"Таблица %-.100s в %s не может изменятся.",
|
||||
|
|
|
@ -285,3 +285,4 @@ character-set=cp1250
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -298,3 +298,4 @@ character-set=latin2
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -290,3 +290,4 @@ character-set=latin1
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"The target table %-.100s of the %s is not updatable.",
|
||||
|
|
|
@ -295,3 +295,4 @@ character-set=koi8u
|
|||
"MySQL is started in --skip-name-resolve mode. You need to restart it without this switch for this grant to work",
|
||||
"Unknown table engine '%s'",
|
||||
"'%s' is deprecated. Use '%s' instead.",
|
||||
"Таблиця %-.100s у %s не може оновлюватись.",
|
||||
|
|
|
@ -127,6 +127,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
|
|||
lex->select_lex.expr_list.empty();
|
||||
lex->select_lex.ftfunc_list_alloc.empty();
|
||||
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
|
||||
lex->select_lex.group_list.empty();
|
||||
lex->select_lex.order_list.empty();
|
||||
lex->current_select= &lex->select_lex;
|
||||
lex->yacc_yyss=lex->yacc_yyvs=0;
|
||||
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
|
||||
|
|
|
@ -1109,7 +1109,7 @@ end:
|
|||
void free_items(Item *item)
|
||||
{
|
||||
for (; item ; item=item->next)
|
||||
delete item;
|
||||
item->delete_self();
|
||||
}
|
||||
|
||||
/* This works because items are allocated with sql_alloc() */
|
||||
|
@ -2665,15 +2665,29 @@ mysql_execute_command(THD *thd)
|
|||
table_count++;
|
||||
/* All tables in aux_tables must be found in FROM PART */
|
||||
TABLE_LIST *walk;
|
||||
for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next)
|
||||
for (walk= (TABLE_LIST*) tables; walk; walk= walk->next)
|
||||
{
|
||||
if (!strcmp(auxi->real_name,walk->real_name) &&
|
||||
!strcmp(walk->db,auxi->db))
|
||||
if (!strcmp(auxi->real_name, walk->alias) &&
|
||||
!strcmp(walk->db, auxi->db))
|
||||
break;
|
||||
}
|
||||
if (!walk)
|
||||
{
|
||||
net_printf(thd,ER_NONUNIQ_TABLE,auxi->real_name);
|
||||
if (lex->derived_tables)
|
||||
{
|
||||
// are we trying to delete derived table?
|
||||
for (walk= (TABLE_LIST*) tables; walk; walk= walk->next)
|
||||
{
|
||||
if (!strcmp(auxi->real_name,walk->alias) &&
|
||||
walk->derived)
|
||||
{
|
||||
net_printf(thd, ER_NON_UPDATABLE_TABLE,
|
||||
auxi->real_name, "DELETE");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
net_printf(thd, ER_NONUNIQ_TABLE, auxi->real_name);
|
||||
goto error;
|
||||
}
|
||||
walk->lock_type= auxi->lock_type;
|
||||
|
|
|
@ -756,7 +756,8 @@ static bool mysql_test_select_fields(Prepared_statement *stmt,
|
|||
JOIN *join= new JOIN(thd, fields, select_options, result);
|
||||
thd->used_tables= 0; // Updated by setup_fields
|
||||
|
||||
if (join->prepare(&select_lex->ref_pointer_array, tables,
|
||||
if (join->prepare(&select_lex->ref_pointer_array,
|
||||
(TABLE_LIST*)select_lex->get_table_list(),
|
||||
wild_num, conds, og_num, order, group, having, proc,
|
||||
select_lex, unit))
|
||||
DBUG_RETURN(1);
|
||||
|
@ -925,6 +926,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
|
|||
sl->prep_where= sl->where;
|
||||
}
|
||||
|
||||
cleanup_items(thd->free_list);
|
||||
stmt->set_statement(thd);
|
||||
thd->set_statement(&thd->stmt_backup);
|
||||
|
||||
|
@ -975,14 +977,10 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
XXX: while thd->query_id is incremented for each command, stmt->query_id
|
||||
holds query_id of prepare stage. Keeping old query_id seems to be more
|
||||
natural, but differs from the way prepared statements work in 4.1:
|
||||
*/
|
||||
/* stmt->query_id= thd->query_id; */
|
||||
stmt->query_id= thd->query_id;
|
||||
thd->stmt_backup.set_statement(thd);
|
||||
thd->set_statement(stmt);
|
||||
thd->free_list= 0;
|
||||
|
||||
/*
|
||||
To make sure that all runtime data is stored in its own memory root and
|
||||
|
@ -1006,6 +1004,11 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
if (sl->prep_where)
|
||||
sl->where= sl->prep_where->copy_andor_structure(thd);
|
||||
DBUG_ASSERT(sl->join == 0);
|
||||
ORDER *order;
|
||||
for (order=(ORDER *)sl->group_list.first ; order ; order=order->next)
|
||||
order->item= (Item **)(order+1);
|
||||
for (order=(ORDER *)sl->order_list.first ; order ; order=order->next)
|
||||
order->item= (Item **)(order+1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1042,6 +1045,8 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
|
||||
|
||||
free_items(thd->free_list);
|
||||
cleanup_items(stmt->free_list);
|
||||
free_root(&thd->mem_root, MYF(0));
|
||||
thd->set_statement(&thd->stmt_backup);
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
|
@ -8283,7 +8283,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||
if (pos->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
Item_field *item;
|
||||
if (!(item= new Item_field(thd, *((Item_field*) pos))))
|
||||
if (!(item= new Item_field(thd, ((Item_field*) pos))))
|
||||
goto err;
|
||||
pos= item;
|
||||
if (item->field->flags & BLOB_FLAG)
|
||||
|
|
|
@ -228,6 +228,27 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Checks that the source string can be just copied
|
||||
to the destination string without conversion.
|
||||
If either character set conversion or adding leading
|
||||
zeros (e.g. for UCS-2) must be done then return
|
||||
value is TRUE else FALSE.
|
||||
*/
|
||||
bool String::needs_conversion(const char *str, uint32 arg_length,
|
||||
CHARSET_INFO *from_cs,
|
||||
CHARSET_INFO *to_cs)
|
||||
{
|
||||
if ((to_cs == &my_charset_bin) ||
|
||||
(to_cs == from_cs) ||
|
||||
my_charset_same(from_cs, to_cs) ||
|
||||
((from_cs == &my_charset_bin) && (!(arg_length % to_cs->mbminlen))))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
** For real multi-byte, ascii incompatible charactser sets,
|
||||
** like UCS-2, add leading zeros if we have an incomplete character.
|
||||
|
@ -237,15 +258,15 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
|
|||
** SELECT _ucs2 0x00AA
|
||||
*/
|
||||
|
||||
bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
||||
CHARSET_INFO *cs)
|
||||
bool String::copy_aligned(const char *str,uint32 arg_length,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
/* How many bytes are in incomplete character */
|
||||
uint32 offs= (arg_length % cs->mbminlen);
|
||||
|
||||
if (!offs) /* All characters are complete, just copy */
|
||||
{
|
||||
set(str, arg_length, cs);
|
||||
copy(str, arg_length, cs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -274,15 +295,35 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
/* How many bytes are in incomplete character */
|
||||
uint32 offs= (arg_length % cs->mbminlen);
|
||||
|
||||
if (!offs) /* All characters are complete, just copy */
|
||||
{
|
||||
set(str, arg_length, cs);
|
||||
return FALSE;
|
||||
}
|
||||
return copy_aligned(str, arg_length, cs);
|
||||
}
|
||||
|
||||
/* Copy with charset convertion */
|
||||
|
||||
bool String::copy(const char *str, uint32 arg_length,
|
||||
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
|
||||
{
|
||||
if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
|
||||
if (!needs_conversion(str, arg_length, from_cs, to_cs))
|
||||
{
|
||||
return copy(str, arg_length, to_cs);
|
||||
}
|
||||
if ((from_cs == &my_charset_bin) && (arg_length % to_cs->mbminlen))
|
||||
{
|
||||
return copy_aligned(str, arg_length, to_cs);
|
||||
}
|
||||
|
||||
uint32 new_length= to_cs->mbmaxlen*arg_length;
|
||||
if (alloc(new_length))
|
||||
return TRUE;
|
||||
|
|
|
@ -183,6 +183,9 @@ public:
|
|||
bool copy(); // Alloc string if not alloced
|
||||
bool copy(const String &s); // Allocate new string
|
||||
bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
|
||||
static bool needs_conversion(const char *s, uint32 arg_length,
|
||||
CHARSET_INFO *cs_from, CHARSET_INFO *cs_to);
|
||||
bool copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
|
||||
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
|
||||
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
|
||||
CHARSET_INFO *csto);
|
||||
|
|
|
@ -434,13 +434,36 @@ int mysql_multi_update(THD *thd,
|
|||
fix_tables_pointers(thd->lex->all_selects_list);
|
||||
|
||||
select_lex->select_limit= HA_POS_ERROR;
|
||||
|
||||
table_map item_tables= 0, derived_tables= 0;
|
||||
if (thd->lex->derived_tables)
|
||||
{
|
||||
// Assign table map values to check updatability of derived tables
|
||||
uint tablenr=0;
|
||||
for (TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
|
||||
table_list;
|
||||
table_list= table_list->next, tablenr++)
|
||||
{
|
||||
table_list->table->map= (table_map) 1 << tablenr;
|
||||
}
|
||||
}
|
||||
if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0))
|
||||
DBUG_RETURN(-1);
|
||||
if (thd->lex->derived_tables)
|
||||
{
|
||||
// Find tables used in items
|
||||
List_iterator_fast<Item> it(*fields);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
item_tables|= item->used_tables();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Count tables and setup timestamp handling
|
||||
*/
|
||||
for (tl= select_lex->get_table_list() ; tl ; tl=tl->next)
|
||||
for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
|
||||
{
|
||||
TABLE *table= tl->table;
|
||||
if (table->timestamp_field)
|
||||
|
@ -450,6 +473,18 @@ int mysql_multi_update(THD *thd,
|
|||
if (table->timestamp_field->query_id != thd->query_id)
|
||||
table->time_stamp= table->timestamp_field->offset() +1;
|
||||
}
|
||||
if (tl->derived)
|
||||
derived_tables|= table->map;
|
||||
}
|
||||
if (thd->lex->derived_tables && (item_tables & derived_tables))
|
||||
{
|
||||
// find derived table which cause error
|
||||
for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
|
||||
{
|
||||
if (tl->derived && (item_tables & tl->table->map))
|
||||
my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE),
|
||||
MYF(0), tl->alias, "UPDATE");
|
||||
}
|
||||
}
|
||||
|
||||
if (!(result=new multi_update(thd, table_list, fields, values,
|
||||
|
|
|
@ -3155,13 +3155,6 @@ join_table:
|
|||
| '(' SELECT_SYM select_derived ')' opt_table_alias
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->sql_command == SQLCOM_UPDATE &&
|
||||
&lex->select_lex == lex->current_select->outer_select())
|
||||
{
|
||||
send_error(lex->thd, ER_SYNTAX_ERROR);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
|
||||
lex->current_select= unit->outer_select();
|
||||
if (!($$= lex->current_select->
|
||||
|
@ -3838,6 +3831,13 @@ update:
|
|||
Select->set_lock_for_tables($3);
|
||||
if (lex->select_lex.table_list.elements > 1)
|
||||
lex->sql_command= SQLCOM_UPDATE_MULTI;
|
||||
else if (lex->select_lex.get_table_list()->derived)
|
||||
{
|
||||
/* it is single table update and it is update of derived table */
|
||||
net_printf(lex->thd, ER_NON_UPDATABLE_TABLE,
|
||||
lex->select_lex.get_table_list()->alias, "UPDATE");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -4486,7 +4486,7 @@ simple_ident:
|
|||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
||||
sel->get_in_sum_expr() > 0) ?
|
||||
(Item*) new Item_field(NullS,NullS,$1.str) :
|
||||
(Item*) new Item_ref(NullS,NullS,$1.str);
|
||||
(Item*) new Item_ref(0,0, NullS,NullS,$1.str);
|
||||
}
|
||||
| ident '.' ident
|
||||
{
|
||||
|
@ -4502,7 +4502,7 @@ simple_ident:
|
|||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
||||
sel->get_in_sum_expr() > 0) ?
|
||||
(Item*) new Item_field(NullS,$1.str,$3.str) :
|
||||
(Item*) new Item_ref(NullS,$1.str,$3.str);
|
||||
(Item*) new Item_ref(0,0,NullS,$1.str,$3.str);
|
||||
}
|
||||
| '.' ident '.' ident
|
||||
{
|
||||
|
@ -4518,7 +4518,7 @@ simple_ident:
|
|||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
||||
sel->get_in_sum_expr() > 0) ?
|
||||
(Item*) new Item_field(NullS,$2.str,$4.str) :
|
||||
(Item*) new Item_ref(NullS,$2.str,$4.str);
|
||||
(Item*) new Item_ref(0,0,NullS,$2.str,$4.str);
|
||||
}
|
||||
| ident '.' ident '.' ident
|
||||
{
|
||||
|
@ -4536,8 +4536,8 @@ simple_ident:
|
|||
(Item*) new Item_field((YYTHD->client_capabilities &
|
||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||
$3.str, $5.str) :
|
||||
(Item*) new Item_ref((YYTHD->client_capabilities &
|
||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||
(Item*) new Item_ref(0,0,(YYTHD->client_capabilities &
|
||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||
$3.str, $5.str);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue