mirror of
https://github.com/MariaDB/server.git
synced 2026-05-07 07:35:32 +02:00
Merge sgluhov@bk-internal.mysql.com:/home/bk/mysql-4.1
into gluh.mysql.r18.ru:/home/gluh/mysql-4.1.curr sql/sql_yacc.yy: Auto merged
This commit is contained in:
commit
66de313563
39 changed files with 498 additions and 328 deletions
|
|
@ -425,8 +425,9 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sprintf(buff, "%s",
|
sprintf(buff, "%s",
|
||||||
|
#ifndef NOT_YET
|
||||||
"Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
|
"Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
|
||||||
#ifdef NOT_YET
|
#else
|
||||||
"Type 'help [[%]function name[%]]' to get help on usage of function.\n");
|
"Type 'help [[%]function name[%]]' to get help on usage of function.\n");
|
||||||
#endif
|
#endif
|
||||||
put_info(buff,INFO_INFO);
|
put_info(buff,INFO_INFO);
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ enum enum_server_command
|
||||||
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
|
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
|
||||||
#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */
|
#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */
|
||||||
#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
|
#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
|
||||||
#define CLIENT_REMEMBER_OPTIONS ((ulong) (1L << 31))
|
#define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31)
|
||||||
|
|
||||||
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
|
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
|
||||||
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
|
#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,6 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||||
*prev_row= row;
|
*prev_row= row;
|
||||||
row->data= columns;
|
row->data= columns;
|
||||||
MYSQL_ROW col_end= columns + mysql->field_count;
|
MYSQL_ROW col_end= columns + mysql->field_count;
|
||||||
uint len;
|
|
||||||
for (; columns < col_end; columns++)
|
for (; columns < col_end; columns++)
|
||||||
src->load_column(&data->alloc, columns);
|
src->load_column(&data->alloc, columns);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -332,10 +332,10 @@ char ** copy_arguments_ptr= 0;
|
||||||
|
|
||||||
int init_embedded_server(int argc, char **argv, char **groups)
|
int init_embedded_server(int argc, char **argv, char **groups)
|
||||||
{
|
{
|
||||||
char glob_hostname[FN_REFLEN];
|
/*
|
||||||
|
This mess is to allow people to call the init function without
|
||||||
/* This mess is to allow people to call the init function without
|
having to mess with a fake argv
|
||||||
* having to mess with a fake argv */
|
*/
|
||||||
int *argcp;
|
int *argcp;
|
||||||
char ***argvp;
|
char ***argvp;
|
||||||
int fake_argc = 1;
|
int fake_argc = 1;
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,21 @@ void mi_copy_status(void* to,void *from)
|
||||||
((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state;
|
((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if should allow concurrent inserts
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
Don't allow concurrent inserts if we have a hole in the table.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Rtree indexes are disabled in mi_open()
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok to use concurrent inserts
|
||||||
|
1 not ok
|
||||||
|
*/
|
||||||
|
|
||||||
my_bool mi_check_status(void* param)
|
my_bool mi_check_status(void* param)
|
||||||
{
|
{
|
||||||
MI_INFO *info=(MI_INFO*) param;
|
MI_INFO *info=(MI_INFO*) param;
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch(info->s->keyinfo[inx].key_alg)
|
switch (info->s->keyinfo[inx].key_alg) {
|
||||||
{
|
|
||||||
case HA_KEY_ALG_RTREE:
|
case HA_KEY_ALG_RTREE:
|
||||||
/*
|
/*
|
||||||
Note that rtree doesn't support that the table
|
Note that rtree doesn't support that the table
|
||||||
|
|
@ -71,33 +70,32 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
|
||||||
case HA_KEY_ALG_BTREE:
|
case HA_KEY_ALG_BTREE:
|
||||||
default:
|
default:
|
||||||
if (!changed)
|
if (!changed)
|
||||||
{
|
|
||||||
error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
|
error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
|
||||||
info->lastkey_length,flag,
|
info->lastkey_length,flag,
|
||||||
info->s->state.key_root[inx]);
|
info->s->state.key_root[inx]);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
error= _mi_search(info,info->s->keyinfo+inx,info->lastkey,
|
error= _mi_search(info,info->s->keyinfo+inx,info->lastkey,
|
||||||
USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
|
USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
|
||||||
}
|
}
|
||||||
if (!error && info->s->concurrent_insert)
|
}
|
||||||
|
|
||||||
|
if (info->s->concurrent_insert)
|
||||||
|
{
|
||||||
|
if (!error)
|
||||||
{
|
{
|
||||||
while (info->lastpos >= info->state->data_file_length)
|
while (info->lastpos >= info->state->data_file_length)
|
||||||
{
|
{
|
||||||
/* Skip rows that are inserted by other threads since we got a lock */
|
/* Skip rows inserted by other threads since we got a lock */
|
||||||
if ((error=_mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
|
if ((error=_mi_search_next(info,info->s->keyinfo+inx,
|
||||||
|
info->lastkey,
|
||||||
info->lastkey_length,
|
info->lastkey_length,
|
||||||
SEARCH_BIGGER,
|
SEARCH_BIGGER,
|
||||||
info->s->state.key_root[inx])))
|
info->s->state.key_root[inx])))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->s->concurrent_insert)
|
|
||||||
rw_unlock(&info->s->key_root_lock[inx]);
|
rw_unlock(&info->s->key_root_lock[inx]);
|
||||||
|
}
|
||||||
/* Don't clear if database-changed */
|
/* Don't clear if database-changed */
|
||||||
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
info->update|= HA_STATE_NEXT_FOUND;
|
info->update|= HA_STATE_NEXT_FOUND;
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
|
||||||
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
|
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
|
||||||
USE_WHOLE_KEY, flag, share->state.key_root[inx]);
|
USE_WHOLE_KEY, flag, share->state.key_root[inx]);
|
||||||
|
|
||||||
|
if (share->concurrent_insert)
|
||||||
|
{
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
while (info->lastpos >= info->state->data_file_length)
|
while (info->lastpos >= info->state->data_file_length)
|
||||||
|
|
@ -64,9 +66,8 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (share->concurrent_insert)
|
|
||||||
rw_unlock(&share->key_root_lock[inx]);
|
rw_unlock(&share->key_root_lock[inx]);
|
||||||
|
}
|
||||||
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
info->update|= HA_STATE_PREV_FOUND;
|
info->update|= HA_STATE_PREV_FOUND;
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
||||||
|
|
@ -136,17 +136,7 @@ grp ROUND(group_concat(a separator ""))
|
||||||
3 456789
|
3 456789
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (grp int, c char(10));
|
create table t1 (grp int, c char(10));
|
||||||
insert into t1 values (1,NULL);
|
insert into t1 values (1,NULL),(2,"b"),(2,NULL),(3,"E"),(3,NULL),(3,"D"),(3,NULL),(3,NULL),(3,"D"),(4,""),(5,NULL);
|
||||||
insert into t1 values (2,"b");
|
|
||||||
insert into t1 values (2,NULL);
|
|
||||||
insert into t1 values (3,"E");
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,"D");
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,"D");
|
|
||||||
insert into t1 values (4,"");
|
|
||||||
insert into t1 values (5,NULL);
|
|
||||||
select grp,group_concat(c order by c) from t1 group by grp;
|
select grp,group_concat(c order by c) from t1 group by grp;
|
||||||
grp group_concat(c order by c)
|
grp group_concat(c order by c)
|
||||||
1 NULL
|
1 NULL
|
||||||
|
|
@ -222,3 +212,75 @@ select group_concat(a1 order by (t1.a)) from t1;
|
||||||
group_concat(a1 order by (t1.a))
|
group_concat(a1 order by (t1.a))
|
||||||
b,a,c
|
b,a,c
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
CREATE TABLE t1 (id1 tinyint(4) NOT NULL, id2 tinyint(4) NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(2, 1),(2, 2),(2, 3);
|
||||||
|
CREATE TABLE t2 (id1 tinyint(4) NOT NULL);
|
||||||
|
INSERT INTO t2 VALUES (1),(2),(3),(4),(5);
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 AND t1.id1=1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 1,2,3,4,5
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 1,2,3,4,5
|
||||||
|
2 1,2,3
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 DESC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 5,4,3,2,1
|
||||||
|
2 3,2,1
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 5,4,3,2,1
|
||||||
|
2 3,2,1
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,6-t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 51,42,33,24,15
|
||||||
|
2 33,24,15
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,6-t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 51,42,33,24,15
|
||||||
|
2 33,24,15
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,"/",6-t1.id2 ORDER BY 1+0,6-t1.id2,t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
id1 concat_id
|
||||||
|
1 5/1,4/2,3/3,2/4,1/5
|
||||||
|
2 3/3,2/4,1/5
|
||||||
|
drop table t1,t2;
|
||||||
|
create table t1 (s1 char(10), s2 int not null);
|
||||||
|
insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4);
|
||||||
|
select distinct s1 from t1 order by s2;
|
||||||
|
s1
|
||||||
|
c
|
||||||
|
a
|
||||||
|
b
|
||||||
|
select group_concat(distinct s1) from t1;
|
||||||
|
group_concat(distinct s1)
|
||||||
|
a,b,c
|
||||||
|
select group_concat(distinct s1 order by s2) from t1 where s2 < 4;
|
||||||
|
group_concat(distinct s1 order by s2)
|
||||||
|
c,b,a
|
||||||
|
select group_concat(distinct s1 order by s2) from t1;
|
||||||
|
group_concat(distinct s1 order by s2)
|
||||||
|
c,b,a,c
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a int, c int);
|
||||||
|
insert into t1 values (1, 2), (2, 3), (2, 4), (3, 5);
|
||||||
|
create table t2 (a int, c int);
|
||||||
|
insert into t2 values (1, 5), (2, 4), (3, 3), (3,3);
|
||||||
|
select group_concat(c) from t1;
|
||||||
|
group_concat(c)
|
||||||
|
2,3,4,5
|
||||||
|
select group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1;
|
||||||
|
grp
|
||||||
|
5,4,3,2
|
||||||
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1;
|
||||||
|
grp
|
||||||
|
5,4,3,2
|
||||||
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
||||||
|
grp
|
||||||
|
2,4,3,5
|
||||||
|
select a,c,(select group_concat(c order by a) from t2 where a=t1.a) as grp from t1 order by grp;
|
||||||
|
a c grp
|
||||||
|
3 5 3,3
|
||||||
|
2 3 4
|
||||||
|
2 4 4
|
||||||
|
1 2 5
|
||||||
|
drop table t1,t2;
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
instr(version(),convert('debug' using utf8))!=0;
|
instr(version(),convert('debug' using utf8))!=0
|
||||||
1
|
1
|
||||||
|
|
@ -50,22 +50,12 @@ select grp,group_concat(c order by grp desc) from t1 group by grp order by grp;
|
||||||
select grp, group_concat(a separator "")+0 from t1 group by grp;
|
select grp, group_concat(a separator "")+0 from t1 group by grp;
|
||||||
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
|
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
|
||||||
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
|
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# Test NULL values
|
# Test NULL values
|
||||||
|
|
||||||
drop table t1;
|
|
||||||
create table t1 (grp int, c char(10));
|
create table t1 (grp int, c char(10));
|
||||||
insert into t1 values (1,NULL);
|
insert into t1 values (1,NULL),(2,"b"),(2,NULL),(3,"E"),(3,NULL),(3,"D"),(3,NULL),(3,NULL),(3,"D"),(4,""),(5,NULL);
|
||||||
insert into t1 values (2,"b");
|
|
||||||
insert into t1 values (2,NULL);
|
|
||||||
insert into t1 values (3,"E");
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,"D");
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,NULL);
|
|
||||||
insert into t1 values (3,"D");
|
|
||||||
insert into t1 values (4,"");
|
|
||||||
insert into t1 values (5,NULL);
|
|
||||||
select grp,group_concat(c order by c) from t1 group by grp;
|
select grp,group_concat(c order by c) from t1 group by grp;
|
||||||
|
|
||||||
# Test warnings
|
# Test warnings
|
||||||
|
|
@ -130,3 +120,57 @@ insert into t2 values (1),(2),(3);
|
||||||
select group_concat(a1 order by (t1.a IN (select a0 from t2))) from t1;
|
select group_concat(a1 order by (t1.a IN (select a0 from t2))) from t1;
|
||||||
select group_concat(a1 order by (t1.a)) from t1;
|
select group_concat(a1 order by (t1.a)) from t1;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem with GROUP BY (Bug #2695)
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id1 tinyint(4) NOT NULL, id2 tinyint(4) NOT NULL);
|
||||||
|
INSERT INTO t1 VALUES (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(2, 1),(2, 2),(2, 3);
|
||||||
|
CREATE TABLE t2 (id1 tinyint(4) NOT NULL);
|
||||||
|
INSERT INTO t2 VALUES (1),(2),(3),(4),(5);
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 AND t1.id1=1 GROUP BY t1.id1;
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY t1.id2 DESC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
|
||||||
|
# The following failed when it was run twice:
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,6-t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,6-t1.id2 ORDER BY 6-t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
|
||||||
|
SELECT t1.id1, GROUP_CONCAT(t1.id2,"/",6-t1.id2 ORDER BY 1+0,6-t1.id2,t1.id2 ASC) AS concat_id FROM t1, t2 WHERE t1.id1 = t2.id1 GROUP BY t1.id1;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem with distinct (Bug #3381)
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (s1 char(10), s2 int not null);
|
||||||
|
insert into t1 values ('a',2),('b',2),('c',1),('a',3),('b',4),('c',4);
|
||||||
|
select distinct s1 from t1 order by s2;
|
||||||
|
select group_concat(distinct s1) from t1;
|
||||||
|
select group_concat(distinct s1 order by s2) from t1 where s2 < 4;
|
||||||
|
# The following is wrong and needs to be fixed ASAP
|
||||||
|
select group_concat(distinct s1 order by s2) from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test with subqueries (Bug #3319)
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (a int, c int);
|
||||||
|
insert into t1 values (1, 2), (2, 3), (2, 4), (3, 5);
|
||||||
|
create table t2 (a int, c int);
|
||||||
|
insert into t2 values (1, 5), (2, 4), (3, 3), (3,3);
|
||||||
|
select group_concat(c) from t1;
|
||||||
|
select group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1;
|
||||||
|
|
||||||
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1;
|
||||||
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
||||||
|
|
||||||
|
# The following returns random results as we are sorting on blob addresses
|
||||||
|
# select group_concat(c order by (select group_concat(c order by a) from t2 where t2.a=t1.a)) as grp from t1;
|
||||||
|
# select group_concat(c order by (select group_concat(c) from t2 where a=t1.a)) as grp from t1;
|
||||||
|
|
||||||
|
select a,c,(select group_concat(c order by a) from t2 where a=t1.a) as grp from t1 order by grp;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,6 @@ select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1=
|
||||||
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
|
select max(t1.a2),max(t2.a1) from t1 left outer join t2 on t1.a1=10;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tests to check MIN/MAX query optimization
|
# Tests to check MIN/MAX query optimization
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
-- source include/have_crypt.inc
|
-- source include/have_debug.inc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test for Bug #2385 CREATE TABLE LIKE lacks locking on source and destination table
|
# Test for Bug #2385 CREATE TABLE LIKE lacks locking on source and destination table
|
||||||
|
|
|
||||||
|
|
@ -2044,7 +2044,7 @@ error:
|
||||||
/* Free alloced memory */
|
/* Free alloced memory */
|
||||||
end_server(mysql);
|
end_server(mysql);
|
||||||
mysql_close_free(mysql);
|
mysql_close_free(mysql);
|
||||||
if (!(client_flag & CLIENT_REMEMBER_OPTIONS))
|
if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
|
||||||
mysql_close_free_options(mysql);
|
mysql_close_free_options(mysql);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ static bool read_texts(const char *file_name,const char ***point,
|
||||||
char name[FN_REFLEN];
|
char name[FN_REFLEN];
|
||||||
const char *buff;
|
const char *buff;
|
||||||
uchar head[32],*pos;
|
uchar head[32],*pos;
|
||||||
CHARSET_INFO *cset;
|
CHARSET_INFO *cset; // For future
|
||||||
DBUG_ENTER("read_texts");
|
DBUG_ENTER("read_texts");
|
||||||
|
|
||||||
*point=0; // If something goes wrong
|
*point=0; // If something goes wrong
|
||||||
|
|
@ -137,7 +137,7 @@ err1:
|
||||||
if (file != FERR)
|
if (file != FERR)
|
||||||
VOID(my_close(file,MYF(MY_WME)));
|
VOID(my_close(file,MYF(MY_WME)));
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
DBUG_RETURN(1); // Impossible
|
DBUG_RETURN(1); // keep compiler happy
|
||||||
} /* read_texts */
|
} /* read_texts */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
11
sql/field.cc
11
sql/field.cc
|
|
@ -161,13 +161,6 @@ static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline uint field_length_without_space(const char *ptr, uint length)
|
|
||||||
{
|
|
||||||
const char *end= ptr+length;
|
|
||||||
while (end > ptr && end[-1] == ' ')
|
|
||||||
end--;
|
|
||||||
return (uint) (end-ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tables of filed type compatibility.
|
Tables of filed type compatibility.
|
||||||
|
|
@ -306,7 +299,7 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
||||||
field_name(field_name_arg),
|
field_name(field_name_arg),
|
||||||
query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
|
query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
|
||||||
unireg_check(unireg_check_arg),
|
unireg_check(unireg_check_arg),
|
||||||
field_length(length_arg),null_bit(null_bit_arg),abs_offset(0)
|
field_length(length_arg),null_bit(null_bit_arg)
|
||||||
{
|
{
|
||||||
flags=null_ptr ? 0: NOT_NULL_FLAG;
|
flags=null_ptr ? 0: NOT_NULL_FLAG;
|
||||||
comment.str= (char*) "";
|
comment.str= (char*) "";
|
||||||
|
|
@ -5597,7 +5590,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
|
||||||
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
|
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0; // This shouldn't happen
|
return 0; // Keep compiler happy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@ public:
|
||||||
uint32 field_length; // Length of field
|
uint32 field_length; // Length of field
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
uchar null_bit; // Bit used to test null bit
|
uchar null_bit; // Bit used to test null bit
|
||||||
uint abs_offset; // use only in group_concat
|
|
||||||
|
|
||||||
Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
|
Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
|
||||||
utype unireg_check_arg, const char *field_name_arg,
|
utype unireg_check_arg, const char *field_name_arg,
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,6 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
|
||||||
my_bool not_used __attribute__((unused)));
|
my_bool not_used __attribute__((unused)));
|
||||||
static INNOBASE_SHARE *get_share(const char *table_name);
|
static INNOBASE_SHARE *get_share(const char *table_name);
|
||||||
static void free_share(INNOBASE_SHARE *share);
|
static void free_share(INNOBASE_SHARE *share);
|
||||||
static void innobase_print_error(const char* db_errpfx, char* buffer);
|
|
||||||
|
|
||||||
/* General functions */
|
/* General functions */
|
||||||
|
|
||||||
|
|
@ -1292,18 +1291,6 @@ innobase_close_connection(
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
Prints an error message. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
innobase_print_error(
|
|
||||||
/*=================*/
|
|
||||||
const char* db_errpfx, /* in: error prefix text */
|
|
||||||
char* buffer) /* in: error text */
|
|
||||||
{
|
|
||||||
sql_print_error("%s: %s", db_errpfx, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** InnoDB database tables
|
** InnoDB database tables
|
||||||
|
|
|
||||||
|
|
@ -771,7 +771,6 @@ String *Item_param::query_val_str(String* str)
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
return val_str(str);
|
return val_str(str);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
str->set("'", 1, default_charset());
|
str->set("'", 1, default_charset());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1472,16 +1472,12 @@ cmp_item* cmp_item::get_comparator(Item *item)
|
||||||
switch (item->result_type()) {
|
switch (item->result_type()) {
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
return new cmp_item_sort_string(item->collation.collation);
|
return new cmp_item_sort_string(item->collation.collation);
|
||||||
break;
|
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
return new cmp_item_int;
|
return new cmp_item_int;
|
||||||
break;
|
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
return new cmp_item_real;
|
return new cmp_item_real;
|
||||||
break;
|
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
return new cmp_item_row;
|
return new cmp_item_row;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1143,7 +1143,6 @@ String *Item_func_min_max::val_str(String *str)
|
||||||
// This case should never be choosen
|
// This case should never be choosen
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0; // Keep compiler happy
|
return 0; // Keep compiler happy
|
||||||
}
|
}
|
||||||
|
|
@ -2442,7 +2441,6 @@ Item_func_set_user_var::check()
|
||||||
save_result.vint= args[0]->val_int();
|
save_result.vint= args[0]->val_int();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
save_result.vstr= args[0]->val_str(&value);
|
save_result.vstr= args[0]->val_str(&value);
|
||||||
|
|
@ -2494,7 +2492,6 @@ Item_func_set_user_var::update()
|
||||||
INT_RESULT, &my_charset_bin, DERIVATION_NONE);
|
INT_RESULT, &my_charset_bin, DERIVATION_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
if (!save_result.vstr) // Null value
|
if (!save_result.vstr) // Null value
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
|
||||||
String arg_val;
|
String arg_val;
|
||||||
String *wkb= args[0]->val_str(&arg_val);
|
String *wkb= args[0]->val_str(&arg_val);
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *geom;
|
|
||||||
uint32 srid= 0;
|
uint32 srid= 0;
|
||||||
|
|
||||||
if ((arg_count == 2) && !args[1]->null_value)
|
if ((arg_count == 2) && !args[1]->null_value)
|
||||||
|
|
@ -78,7 +77,7 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
|
||||||
str->q_append(srid);
|
str->q_append(srid);
|
||||||
if ((null_value=
|
if ((null_value=
|
||||||
(args[0]->null_value ||
|
(args[0]->null_value ||
|
||||||
!(geom= Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length())) ||
|
!Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length()) ||
|
||||||
str->append(*wkb))))
|
str->append(*wkb))))
|
||||||
return 0;
|
return 0;
|
||||||
return str;
|
return str;
|
||||||
|
|
@ -126,11 +125,10 @@ String *Item_func_as_wkb::val_str(String *str)
|
||||||
String arg_val;
|
String arg_val;
|
||||||
String *swkb= args[0]->val_str(&arg_val);
|
String *swkb= args[0]->val_str(&arg_val);
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *geom;
|
|
||||||
|
|
||||||
if ((null_value=
|
if ((null_value=
|
||||||
(args[0]->null_value ||
|
(args[0]->null_value ||
|
||||||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
|
!(Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
|
||||||
swkb->length() - SRID_SIZE)))))
|
swkb->length() - SRID_SIZE)))))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -701,8 +699,8 @@ longlong Item_func_srid::val_int()
|
||||||
Geometry_buffer buffer;
|
Geometry_buffer buffer;
|
||||||
Geometry *geom;
|
Geometry *geom;
|
||||||
|
|
||||||
null_value= !swkb ||
|
null_value= (!swkb ||
|
||||||
!(geom= Geometry::create_from_wkb(&buffer,
|
!Geometry::create_from_wkb(&buffer,
|
||||||
swkb->ptr() + SRID_SIZE,
|
swkb->ptr() + SRID_SIZE,
|
||||||
swkb->length() - SRID_SIZE));
|
swkb->length() - SRID_SIZE));
|
||||||
if (null_value)
|
if (null_value)
|
||||||
|
|
|
||||||
261
sql/item_sum.cc
261
sql/item_sum.cc
|
|
@ -41,7 +41,11 @@ Item_sum::Item_sum(List<Item> &list)
|
||||||
list.empty(); // Fields are used
|
list.empty(); // Fields are used
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor used in processing select with temporary tebles
|
|
||||||
|
/*
|
||||||
|
Constructor used in processing select with temporary tebles
|
||||||
|
*/
|
||||||
|
|
||||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
Item_result_field(thd, item), quick_group(item->quick_group)
|
Item_result_field(thd, item), quick_group(item->quick_group)
|
||||||
{
|
{
|
||||||
|
|
@ -55,6 +59,7 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
args[i]= item->args[i];
|
args[i]= item->args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_sum::mark_as_sum_func()
|
void Item_sum::mark_as_sum_func()
|
||||||
{
|
{
|
||||||
current_thd->lex->current_select->with_sum_func= 1;
|
current_thd->lex->current_select->with_sum_func= 1;
|
||||||
|
|
@ -1495,10 +1500,17 @@ String *Item_sum_udf_str::val_str(String *str)
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
GROUP_CONCAT function
|
GROUP_CONCAT function
|
||||||
Syntax:
|
|
||||||
|
SQL SYNTAX:
|
||||||
GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
|
GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
|
||||||
[SEPARATOR str_const])
|
[SEPARATOR str_const])
|
||||||
|
|
||||||
concat of values from "group by" operation
|
concat of values from "group by" operation
|
||||||
|
|
||||||
|
BUGS
|
||||||
|
DISTINCT and ORDER BY only works if ORDER BY uses all fields and only fields
|
||||||
|
in expression list
|
||||||
|
Blobs doesn't work with DISTINCT or ORDER BY
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1510,22 +1522,20 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
|
||||||
byte* key2)
|
byte* key2)
|
||||||
{
|
{
|
||||||
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
||||||
|
uint *offset= item->field_offsets+ item->field_list_offset;
|
||||||
|
Item **field_item, **end;
|
||||||
|
|
||||||
for (uint i= 0; i < item->arg_count_field; i++)
|
for (field_item= item->args, end= field_item+item->arg_count_field;
|
||||||
|
field_item < end;
|
||||||
|
field_item++)
|
||||||
{
|
{
|
||||||
Item *field_item= item->args[i];
|
Field *field= (*field_item)->real_item()->get_tmp_table_field();
|
||||||
Field *field= field_item->real_item()->get_tmp_table_field();
|
|
||||||
if (field)
|
if (field)
|
||||||
{
|
{
|
||||||
uint offset= field->abs_offset;
|
int res;
|
||||||
|
if ((res= field->key_cmp(key1 + *offset, key2 + *offset)))
|
||||||
int res= field->key_cmp(key1 + offset, key2 + offset);
|
return res;
|
||||||
/*
|
offset++;
|
||||||
if key1 and key2 is not equal than field->key_cmp return offset. This
|
|
||||||
function must return value 1 for this case.
|
|
||||||
*/
|
|
||||||
if (res)
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1540,20 +1550,21 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
|
||||||
int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
|
int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
|
||||||
{
|
{
|
||||||
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
||||||
|
uint *offset= item->field_offsets;
|
||||||
|
ORDER **order_item, **end;
|
||||||
|
|
||||||
for (uint i=0; i < item->arg_count_order; i++)
|
for (order_item= item->order, end=order_item+ item->arg_count_order;
|
||||||
|
order_item < end;
|
||||||
|
order_item++)
|
||||||
{
|
{
|
||||||
ORDER *order_item= item->order[i];
|
Item *item= *(*order_item)->item;
|
||||||
Item *item= *order_item->item;
|
|
||||||
Field *field= item->real_item()->get_tmp_table_field();
|
Field *field= item->real_item()->get_tmp_table_field();
|
||||||
if (field)
|
if (field)
|
||||||
{
|
{
|
||||||
uint offset= field->abs_offset;
|
int res= field->key_cmp(key1 + *offset, key2 + *offset);
|
||||||
|
|
||||||
bool dir= order_item->asc;
|
|
||||||
int res= field->key_cmp(key1 + offset, key2 + offset);
|
|
||||||
if (res)
|
if (res)
|
||||||
return dir ? res : -res;
|
return (*order_item)->asc ? res : -res;
|
||||||
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -1566,6 +1577,11 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
|
||||||
/*
|
/*
|
||||||
function of sort for syntax:
|
function of sort for syntax:
|
||||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
||||||
|
|
||||||
|
BUG:
|
||||||
|
This doesn't work in the case when the order by contains data that
|
||||||
|
is not part of the field list because tree-insert will not notice
|
||||||
|
the duplicated values when inserting things sorted by ORDER BY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
|
int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
|
||||||
|
|
@ -1578,58 +1594,53 @@ int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
create result
|
Append data from current leaf to item->result
|
||||||
item is pointer to Item_func_group_concat
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
|
int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
|
||||||
Item_func_group_concat *group_concat_item)
|
Item_func_group_concat *item)
|
||||||
{
|
{
|
||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String tmp((char *)&buff,sizeof(buff),default_charset_info);
|
String tmp((char *)&buff,sizeof(buff),default_charset_info);
|
||||||
String tmp2((char *)&buff,sizeof(buff),default_charset_info);
|
String tmp2((char *)&buff,sizeof(buff),default_charset_info);
|
||||||
|
uint *field_offsets= (item->field_offsets +
|
||||||
|
item->field_list_offset);
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
|
|
||||||
for (uint i= 0; i < group_concat_item->arg_show_fields; i++)
|
for (uint i= 0; i < item->arg_count_field; i++)
|
||||||
{
|
{
|
||||||
Item *show_item= group_concat_item->args[i];
|
Item *show_item= item->args[i];
|
||||||
if (!show_item->const_item())
|
if (!show_item->const_item())
|
||||||
{
|
{
|
||||||
Field *f= show_item->real_item()->get_tmp_table_field();
|
Field *f= show_item->real_item()->get_tmp_table_field();
|
||||||
char *sv= f->ptr;
|
char *sv= f->ptr;
|
||||||
f->ptr= (char *)key + f->abs_offset;
|
f->ptr= (char *) key + *(field_offsets++);
|
||||||
String *res= f->val_str(&tmp,&tmp2);
|
String *res= f->val_str(&tmp,&tmp2);
|
||||||
group_concat_item->result.append(*res);
|
item->result.append(*res);
|
||||||
f->ptr= sv;
|
f->ptr= sv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String *res= show_item->val_str(&tmp);
|
String *res= show_item->val_str(&tmp);
|
||||||
if (res)
|
if (res)
|
||||||
group_concat_item->result.append(*res);
|
item->result.append(*res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (group_concat_item->tree_mode) // Last item of tree
|
if (item->tree_mode) // Last item of tree
|
||||||
{
|
{
|
||||||
group_concat_item->show_elements++;
|
item->show_elements++;
|
||||||
if (group_concat_item->show_elements <
|
if (item->show_elements < item->tree->elements_in_tree)
|
||||||
group_concat_item->tree->elements_in_tree)
|
item->result.append(*item->separator);
|
||||||
group_concat_item->result.append(*group_concat_item->separator);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
item->result.append(*item->separator);
|
||||||
|
|
||||||
|
/* stop if length of result more than group_concat_max_len */
|
||||||
|
if (item->result.length() > item->group_concat_max_len)
|
||||||
{
|
{
|
||||||
group_concat_item->result.append(*group_concat_item->separator);
|
item->count_cut_values++;
|
||||||
}
|
item->result.length(item->group_concat_max_len);
|
||||||
/*
|
item->warning_for_row= TRUE;
|
||||||
if length of result more than group_concat_max_len - stop !
|
|
||||||
*/
|
|
||||||
if (group_concat_item->result.length() >
|
|
||||||
group_concat_item->group_concat_max_len)
|
|
||||||
{
|
|
||||||
group_concat_item->count_cut_values++;
|
|
||||||
group_concat_item->result.length(group_concat_item->group_concat_max_len);
|
|
||||||
group_concat_item->warning_for_row= TRUE;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1654,53 +1665,87 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
|
||||||
separator(is_separator), tree(&tree_base), table(0),
|
separator(is_separator), tree(&tree_base), table(0),
|
||||||
order(0), tables_list(0),
|
order(0), tables_list(0),
|
||||||
show_elements(0), arg_count_order(0), arg_count_field(0),
|
show_elements(0), arg_count_order(0), arg_count_field(0),
|
||||||
arg_show_fields(0), count_cut_values(0)
|
count_cut_values(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Item *item_select;
|
||||||
|
Item **arg_ptr;
|
||||||
|
|
||||||
original= 0;
|
original= 0;
|
||||||
quick_group= 0;
|
quick_group= 0;
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
order= 0;
|
order= 0;
|
||||||
group_concat_max_len= current_thd->variables.group_concat_max_len;
|
group_concat_max_len= current_thd->variables.group_concat_max_len;
|
||||||
|
|
||||||
|
arg_count_field= is_select->elements;
|
||||||
arg_show_fields= arg_count_field= is_select->elements;
|
|
||||||
arg_count_order= is_order ? is_order->elements : 0;
|
arg_count_order= is_order ? is_order->elements : 0;
|
||||||
arg_count= arg_count_field;
|
arg_count= arg_count_field + arg_count_order;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to allocate:
|
We need to allocate:
|
||||||
args - arg_count+arg_count_order (for possible order items in temporare
|
args - arg_count_field+arg_count_order
|
||||||
tables)
|
(for possible order items in temporare tables)
|
||||||
order - arg_count_order
|
order - arg_count_order
|
||||||
|
field_offset For offset withing the key
|
||||||
*/
|
*/
|
||||||
args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order)+
|
if (!(args= (Item**) sql_alloc((sizeof(Item*) + sizeof(uint)) * arg_count +
|
||||||
sizeof(ORDER*)*arg_count_order);
|
sizeof(ORDER*)*arg_count_order)))
|
||||||
if (!args)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* fill args items of show and sort */
|
order= (ORDER**)(args + arg_count);
|
||||||
int i= 0;
|
field_offsets= (uint*) (order+ arg_count_order);
|
||||||
List_iterator_fast<Item> li(*is_select);
|
|
||||||
Item *item_select;
|
|
||||||
|
|
||||||
for ( ; (item_select= li++) ; i++)
|
/* fill args items of show and sort */
|
||||||
args[i]= item_select;
|
List_iterator_fast<Item> li(*is_select);
|
||||||
|
|
||||||
|
for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
|
||||||
|
*arg_ptr= item_select;
|
||||||
|
|
||||||
if (arg_count_order)
|
if (arg_count_order)
|
||||||
{
|
{
|
||||||
i= 0;
|
ORDER **order_ptr= order;
|
||||||
order= (ORDER**)(args + arg_count + arg_count_order);
|
|
||||||
for (ORDER *order_item= (ORDER*) is_order->first;
|
for (ORDER *order_item= (ORDER*) is_order->first;
|
||||||
order_item != NULL;
|
order_item != NULL;
|
||||||
order_item= order_item->next)
|
order_item= order_item->next)
|
||||||
{
|
{
|
||||||
order[i++]= order_item;
|
(*order_ptr++)= order_item;
|
||||||
|
*arg_ptr= *order_item->item;
|
||||||
|
order_item->item= arg_ptr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item_func_group_concat::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),
|
||||||
|
field_offsets(item->field_offsets),
|
||||||
|
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),
|
||||||
|
field_list_offset(item->field_list_offset),
|
||||||
|
count_cut_values(item->count_cut_values),
|
||||||
|
original(item)
|
||||||
|
{
|
||||||
|
quick_group= item->quick_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func_group_concat::cleanup()
|
void Item_func_group_concat::cleanup()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_group_concat::cleanup");
|
DBUG_ENTER("Item_func_group_concat::cleanup");
|
||||||
|
|
@ -1737,12 +1782,11 @@ Item_func_group_concat::~Item_func_group_concat()
|
||||||
*/
|
*/
|
||||||
if (!original)
|
if (!original)
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
|
||||||
if (warning_available)
|
if (warning_available)
|
||||||
{
|
{
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||||
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
|
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
|
||||||
warning->set_msg(thd, warn_buff);
|
warning->set_msg(current_thd, warn_buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1773,13 +1817,15 @@ void Item_func_group_concat::clear()
|
||||||
|
|
||||||
bool Item_func_group_concat::add()
|
bool Item_func_group_concat::add()
|
||||||
{
|
{
|
||||||
|
bool record_is_null;
|
||||||
|
|
||||||
if (always_null)
|
if (always_null)
|
||||||
return 0;
|
return 0;
|
||||||
copy_fields(tmp_table_param);
|
copy_fields(tmp_table_param);
|
||||||
copy_funcs(tmp_table_param->items_to_copy);
|
copy_funcs(tmp_table_param->items_to_copy);
|
||||||
|
|
||||||
bool record_is_null= TRUE;
|
record_is_null= TRUE;
|
||||||
for (uint i= 0; i < arg_show_fields; i++)
|
for (uint i= 0; i < arg_count_field; i++)
|
||||||
{
|
{
|
||||||
Item *show_item= args[i];
|
Item *show_item= args[i];
|
||||||
if (!show_item->const_item())
|
if (!show_item->const_item())
|
||||||
|
|
@ -1803,8 +1849,7 @@ bool Item_func_group_concat::add()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (result.length() <= group_concat_max_len && !warning_for_row)
|
if (result.length() <= group_concat_max_len && !warning_for_row)
|
||||||
dump_leaf_key(table->record[0] + rec_offset, 1,
|
dump_leaf_key(table->record[0] + rec_offset, 1, this);
|
||||||
(Item_func_group_concat*)this);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1832,24 +1877,19 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
thd->allow_sum_func= 0;
|
thd->allow_sum_func= 0;
|
||||||
maybe_null= 0;
|
maybe_null= 0;
|
||||||
item_thd= thd;
|
item_thd= thd;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fix fields for select list and ORDER clause
|
||||||
|
*/
|
||||||
|
|
||||||
for (i= 0 ; i < arg_count ; i++)
|
for (i= 0 ; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
|
if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
|
||||||
return 1;
|
return 1;
|
||||||
maybe_null |= args[i]->maybe_null;
|
if (i < arg_count_field && args[i]->maybe_null)
|
||||||
}
|
maybe_null= 0;
|
||||||
/*
|
|
||||||
Fix fields for order clause in function:
|
|
||||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
|
||||||
*/
|
|
||||||
for (i= 0 ; i < arg_count_order ; i++)
|
|
||||||
{
|
|
||||||
// order_item->item can be changed by fix_fields() call
|
|
||||||
ORDER *order_item= order[i];
|
|
||||||
if ((*order_item->item)->fix_fields(thd, tables, order_item->item) ||
|
|
||||||
(*order_item->item)->check_cols(1))
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result_field= 0;
|
result_field= 0;
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
max_length= group_concat_max_len;
|
max_length= group_concat_max_len;
|
||||||
|
|
@ -1864,23 +1904,29 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
|
|
||||||
bool Item_func_group_concat::setup(THD *thd)
|
bool Item_func_group_concat::setup(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_group_concat::setup");
|
|
||||||
List<Item> list;
|
List<Item> list;
|
||||||
SELECT_LEX *select_lex= thd->lex->current_select;
|
SELECT_LEX *select_lex= thd->lex->current_select;
|
||||||
|
Field **field, **field_end;
|
||||||
|
uint offset, *offsets, const_fields;
|
||||||
|
qsort_cmp2 compare_key;
|
||||||
|
DBUG_ENTER("Item_func_group_concat::setup");
|
||||||
|
|
||||||
if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
|
if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
push all not constant fields to list and create temp table
|
push all not constant fields to list and create temp table
|
||||||
*/
|
*/
|
||||||
|
const_fields= 0;
|
||||||
always_null= 0;
|
always_null= 0;
|
||||||
for (uint i= 0; i < arg_count; i++)
|
for (uint i= 0; i < arg_count_field; i++)
|
||||||
{
|
{
|
||||||
Item *item= args[i];
|
Item *item= args[i];
|
||||||
if (list.push_back(item))
|
if (list.push_back(item))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (item->const_item())
|
if (item->const_item())
|
||||||
{
|
{
|
||||||
|
const_fields++;
|
||||||
(void) item->val_int();
|
(void) item->val_int();
|
||||||
if (item->null_value)
|
if (item->null_value)
|
||||||
always_null= 1;
|
always_null= 1;
|
||||||
|
|
@ -1900,12 +1946,19 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||||
count_field_types(tmp_table_param,all_fields,0);
|
count_field_types(tmp_table_param,all_fields,0);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
We come here when we are getting the result from a temporary table,
|
||||||
|
not the original tables used in the query
|
||||||
|
*/
|
||||||
free_tmp_table(thd, table);
|
free_tmp_table(thd, table);
|
||||||
tmp_table_param->cleanup();
|
tmp_table_param->cleanup();
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
We have to create a temporary table for that we get descriptions of fields
|
We have to create a temporary table to get descriptions of fields
|
||||||
(types, sizes and so on).
|
(types, sizes and so on).
|
||||||
|
|
||||||
|
Note that in the table, we first have the ORDER BY fields, then the
|
||||||
|
field list.
|
||||||
*/
|
*/
|
||||||
if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, 0,
|
if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, 0,
|
||||||
0, 0, 0,select_lex->options | thd->options,
|
0, 0, 0,select_lex->options | thd->options,
|
||||||
|
|
@ -1914,27 +1967,27 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||||
table->file->extra(HA_EXTRA_NO_ROWS);
|
table->file->extra(HA_EXTRA_NO_ROWS);
|
||||||
table->no_rows= 1;
|
table->no_rows= 1;
|
||||||
|
|
||||||
|
|
||||||
Field** field, **field_end;
|
|
||||||
field_end= (field= table->field) + table->fields;
|
field_end= (field= table->field) + table->fields;
|
||||||
uint offset = 0;
|
offsets= field_offsets;
|
||||||
for (key_length = 0; field < field_end; ++field)
|
offset= 0;
|
||||||
|
for (key_length= 0; field < field_end; field++)
|
||||||
{
|
{
|
||||||
uint32 length= (*field)->pack_length();
|
uint32 length= (*field)->pack_length();
|
||||||
(*field)->abs_offset= offset;
|
(*offsets++)= offset;
|
||||||
offset+= length;
|
offset+= length;
|
||||||
key_length += length;
|
key_length += length;
|
||||||
}
|
}
|
||||||
rec_offset = table->reclength - key_length;
|
|
||||||
|
|
||||||
|
/* Offset to first result field in table */
|
||||||
|
field_list_offset= table->fields - (list.elements - const_fields);
|
||||||
|
/* Offset to first field */
|
||||||
|
rec_offset= (uint) (table->field[0]->ptr - table->record[0]);
|
||||||
|
|
||||||
if (tree_mode)
|
if (tree_mode)
|
||||||
delete_tree(tree);
|
delete_tree(tree);
|
||||||
/*
|
|
||||||
choise function of sort
|
/* choose function of sort */
|
||||||
*/
|
|
||||||
tree_mode= distinct || arg_count_order;
|
tree_mode= distinct || arg_count_order;
|
||||||
qsort_cmp2 compare_key;
|
|
||||||
if (tree_mode)
|
if (tree_mode)
|
||||||
{
|
{
|
||||||
if (arg_count_order)
|
if (arg_count_order)
|
||||||
|
|
@ -1946,20 +1999,19 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
compare_key= NULL;
|
||||||
if (distinct)
|
if (distinct)
|
||||||
compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct;
|
compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct;
|
||||||
else
|
|
||||||
compare_key= NULL;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Create a tree of sort. Tree is used for a sort and a remove dubl
|
Create a tree of sort. Tree is used for a sort and a remove double
|
||||||
values (according with syntax of the function). If function does't
|
values (according with syntax of the function). If function doesn't
|
||||||
contain DISTINCT and ORDER BY clauses, we don't create this tree.
|
contain DISTINCT and ORDER BY clauses, we don't create this tree.
|
||||||
*/
|
*/
|
||||||
init_tree(tree, min(thd->variables.max_heap_table_size,
|
init_tree(tree, min(thd->variables.max_heap_table_size,
|
||||||
thd->variables.sortbuff_size/16), 0,
|
thd->variables.sortbuff_size/16), 0,
|
||||||
key_length, compare_key, 0, NULL, (void*) this);
|
key_length, compare_key, 0, NULL, (void*) this);
|
||||||
max_elements_in_tree= ((key_length) ?
|
max_elements_in_tree= (key_length ?
|
||||||
thd->variables.max_heap_table_size/key_length : 1);
|
thd->variables.max_heap_table_size/key_length : 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1975,6 +2027,7 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is used by rollup to create a separate usable copy of the function */
|
/* This is used by rollup to create a separate usable copy of the function */
|
||||||
|
|
||||||
void Item_func_group_concat::make_unique()
|
void Item_func_group_concat::make_unique()
|
||||||
|
|
@ -2017,7 +2070,7 @@ void Item_func_group_concat::print(String *str)
|
||||||
str->append("group_concat(", 13);
|
str->append("group_concat(", 13);
|
||||||
if (distinct)
|
if (distinct)
|
||||||
str->append("distinct ", 9);
|
str->append("distinct ", 9);
|
||||||
for (uint i= 0; i < arg_count; i++)
|
for (uint i= 0; i < arg_count_field; i++)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
str->append(',');
|
str->append(',');
|
||||||
|
|
|
||||||
|
|
@ -204,18 +204,24 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||||
uint key_length;
|
uint key_length;
|
||||||
CHARSET_INFO *key_charset;
|
CHARSET_INFO *key_charset;
|
||||||
|
|
||||||
// calculated based on max_heap_table_size. If reached,
|
/*
|
||||||
// walk the tree and dump it into MyISAM table
|
Calculated based on max_heap_table_size. If reached,
|
||||||
|
walk the tree and dump it into MyISAM table
|
||||||
|
*/
|
||||||
uint max_elements_in_tree;
|
uint max_elements_in_tree;
|
||||||
|
|
||||||
// the first few bytes of record ( at least one)
|
/*
|
||||||
// are just markers for deleted and NULLs. We want to skip them since
|
The first few bytes of record ( at least one)
|
||||||
// they will just bloat the tree without providing any valuable info
|
are just markers for deleted and NULLs. We want to skip them since
|
||||||
|
they will just bloat the tree without providing any valuable info
|
||||||
|
*/
|
||||||
int rec_offset;
|
int rec_offset;
|
||||||
|
|
||||||
// If there are no blobs, we can use a tree, which
|
/*
|
||||||
// is faster than heap table. In that case, we still use the table
|
If there are no blobs, we can use a tree, which
|
||||||
// to help get things set up, but we insert nothing in it
|
is faster than heap table. In that case, we still use the table
|
||||||
|
to help get things set up, but we insert nothing in it
|
||||||
|
*/
|
||||||
bool use_tree;
|
bool use_tree;
|
||||||
bool always_null; // Set to 1 if the result is always NULL
|
bool always_null; // Set to 1 if the result is always NULL
|
||||||
|
|
||||||
|
|
@ -236,7 +242,8 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||||
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
|
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
|
||||||
:Item_sum_int(thd, item), table(item->table),
|
:Item_sum_int(thd, item), table(item->table),
|
||||||
used_table_cache(item->used_table_cache),
|
used_table_cache(item->used_table_cache),
|
||||||
field_lengths(item->field_lengths), tmp_table_param(item->tmp_table_param),
|
field_lengths(item->field_lengths),
|
||||||
|
tmp_table_param(item->tmp_table_param),
|
||||||
tree(item->tree), original(item), key_length(item->key_length),
|
tree(item->tree), original(item), key_length(item->key_length),
|
||||||
max_elements_in_tree(item->max_elements_in_tree),
|
max_elements_in_tree(item->max_elements_in_tree),
|
||||||
rec_offset(item->rec_offset), use_tree(item->use_tree),
|
rec_offset(item->rec_offset), use_tree(item->use_tree),
|
||||||
|
|
@ -318,8 +325,8 @@ public:
|
||||||
void fix_length_and_dec() {}
|
void fix_length_and_dec() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
/*
|
||||||
variance(a) =
|
variance(a) =
|
||||||
|
|
||||||
= sum (ai - avg(a))^2 / count(a) )
|
= sum (ai - avg(a))^2 / count(a) )
|
||||||
|
|
@ -329,7 +336,6 @@ variance(a) =
|
||||||
= (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
|
= (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
|
||||||
= (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
|
= (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
|
||||||
= (sum(ai^2) - sum(a)^2/count(a))/count(a)
|
= (sum(ai^2) - sum(a)^2/count(a))/count(a)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Item_sum_variance : public Item_sum_num
|
class Item_sum_variance : public Item_sum_num
|
||||||
|
|
@ -515,8 +521,9 @@ class Item_sum_xor :public Item_sum_bit
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** user defined aggregates
|
User defined aggregates
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
|
|
||||||
class Item_udf_sum : public Item_sum
|
class Item_udf_sum : public Item_sum
|
||||||
|
|
@ -682,7 +689,8 @@ class Item_func_group_concat : public Item_sum
|
||||||
|
|
||||||
friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
|
friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
|
||||||
byte* key2);
|
byte* key2);
|
||||||
friend int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2);
|
friend int group_concat_key_cmp_with_order(void* arg, byte* key1,
|
||||||
|
byte* key2);
|
||||||
friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
|
friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
|
||||||
byte* key1,
|
byte* key1,
|
||||||
byte* key2);
|
byte* key2);
|
||||||
|
|
@ -696,12 +704,13 @@ class Item_func_group_concat : public Item_sum
|
||||||
TREE *tree;
|
TREE *tree;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
ORDER **order;
|
ORDER **order;
|
||||||
|
uint *field_offsets;
|
||||||
TABLE_LIST *tables_list;
|
TABLE_LIST *tables_list;
|
||||||
ulong group_concat_max_len;
|
ulong group_concat_max_len;
|
||||||
uint show_elements;
|
uint show_elements;
|
||||||
uint arg_count_order;
|
uint arg_count_order;
|
||||||
uint arg_count_field;
|
uint arg_count_field;
|
||||||
uint arg_show_fields;
|
uint field_list_offset;
|
||||||
uint count_cut_values;
|
uint count_cut_values;
|
||||||
/*
|
/*
|
||||||
Following is 0 normal object and pointer to original one for copy
|
Following is 0 normal object and pointer to original one for copy
|
||||||
|
|
@ -712,38 +721,12 @@ class Item_func_group_concat : public Item_sum
|
||||||
Item_func_group_concat(bool is_distinct,List<Item> *is_select,
|
Item_func_group_concat(bool is_distinct,List<Item> *is_select,
|
||||||
SQL_LIST *is_order,String *is_separator);
|
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)
|
|
||||||
{
|
|
||||||
quick_group= item->quick_group;
|
|
||||||
};
|
|
||||||
~Item_func_group_concat();
|
~Item_func_group_concat();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
|
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
|
||||||
const char *func_name() const { return "group_concat"; }
|
const char *func_name() const { return "group_concat"; }
|
||||||
enum Type type() const { return SUM_FUNC_ITEM; }
|
|
||||||
virtual Item_result result_type () const { return STRING_RESULT; }
|
virtual Item_result result_type () const { return STRING_RESULT; }
|
||||||
void clear();
|
void clear();
|
||||||
bool add();
|
bool add();
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,6 @@ int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
LOG_INFO_EOF End of log-index-file found
|
LOG_INFO_EOF End of log-index-file found
|
||||||
LOG_INFO_SEEK Could not allocate IO cache
|
|
||||||
LOG_INFO_IO Got IO error while reading file
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ inline int ignored_error_code(int err_code)
|
||||||
pretty_print_str()
|
pretty_print_str()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
static char *pretty_print_str(char *packet, char *str, int len)
|
static char *pretty_print_str(char *packet, char *str, int len)
|
||||||
{
|
{
|
||||||
char *end= str + len;
|
char *end= str + len;
|
||||||
|
|
|
||||||
|
|
@ -2364,9 +2364,8 @@ Now disabling --log-slave-updates.");
|
||||||
{
|
{
|
||||||
if (global_system_variables.log_warnings)
|
if (global_system_variables.log_warnings)
|
||||||
sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
|
sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
|
||||||
|
locked_in_memory= 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
locked_in_memory=1;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
locked_in_memory=0;
|
locked_in_memory=0;
|
||||||
|
|
|
||||||
|
|
@ -166,10 +166,10 @@ net_printf(THD *thd, uint errcode, ...)
|
||||||
const char *format;
|
const char *format;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
const char *text_pos;
|
const char *text_pos;
|
||||||
|
int head_length= NET_HEADER_SIZE;
|
||||||
#else
|
#else
|
||||||
char text_pos[1024];
|
char text_pos[1024];
|
||||||
#endif
|
#endif
|
||||||
int head_length= NET_HEADER_SIZE;
|
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
|
|
||||||
DBUG_ENTER("net_printf");
|
DBUG_ENTER("net_printf");
|
||||||
|
|
|
||||||
|
|
@ -839,7 +839,8 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
|
||||||
{
|
{
|
||||||
char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
|
char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
|
||||||
uint new_length= (var ? var->value->str_value.length() : 0);
|
uint new_length= (var ? var->value->str_value.length() : 0);
|
||||||
if (!old_value) old_value="";
|
if (!old_value)
|
||||||
|
old_value= (char*) "";
|
||||||
if (!(res= my_strdup_with_length(old_value, new_length, MYF(0))))
|
if (!(res= my_strdup_with_length(old_value, new_length, MYF(0))))
|
||||||
return 1;
|
return 1;
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
21
sql/slave.cc
21
sql/slave.cc
|
|
@ -285,7 +285,8 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
|
||||||
In this case, we will use the same IO_CACHE pointer to
|
In this case, we will use the same IO_CACHE pointer to
|
||||||
read data as the IO thread is using to write data.
|
read data as the IO thread is using to write data.
|
||||||
*/
|
*/
|
||||||
if (my_b_tell((rli->cur_log=rli->relay_log.get_log_file())) == 0 &&
|
rli->cur_log= rli->relay_log.get_log_file();
|
||||||
|
if (my_b_tell(rli->cur_log) == 0 &&
|
||||||
check_binlog_magic(rli->cur_log, errmsg))
|
check_binlog_magic(rli->cur_log, errmsg))
|
||||||
goto err;
|
goto err;
|
||||||
rli->cur_log_old_open_count=rli->relay_log.get_open_count();
|
rli->cur_log_old_open_count=rli->relay_log.get_open_count();
|
||||||
|
|
@ -1672,7 +1673,18 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
||||||
DBUG_ENTER("init_master_info");
|
DBUG_ENTER("init_master_info");
|
||||||
|
|
||||||
if (mi->inited)
|
if (mi->inited)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We have to reset read position of relay-log-bin as we may have
|
||||||
|
already been reading from 'hotlog' when the slave was stopped
|
||||||
|
last time. If this case pos_in_file would be set and we would
|
||||||
|
get a crash when trying to read the signature for the binary
|
||||||
|
relay log.
|
||||||
|
*/
|
||||||
|
my_b_seek(mi->rli.cur_log, (my_off_t) 0);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
mi->mysql=0;
|
mi->mysql=0;
|
||||||
mi->file_id=1;
|
mi->file_id=1;
|
||||||
fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
|
fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
|
||||||
|
|
@ -3616,13 +3628,16 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||||
mi->master_log_pos+= inc_pos;
|
mi->master_log_pos+= inc_pos;
|
||||||
DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
|
DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
|
||||||
}
|
}
|
||||||
else /* write the event to the relay log */
|
else
|
||||||
|
{
|
||||||
|
/* write the event to the relay log */
|
||||||
if (likely(!(error= rli->relay_log.appendv(buf,event_len,0))))
|
if (likely(!(error= rli->relay_log.appendv(buf,event_len,0))))
|
||||||
{
|
{
|
||||||
mi->master_log_pos+= inc_pos;
|
mi->master_log_pos+= inc_pos;
|
||||||
DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
|
DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
|
||||||
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&mi->data_lock);
|
pthread_mutex_unlock(&mi->data_lock);
|
||||||
|
|
@ -4090,6 +4105,7 @@ Before assert, my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
|
||||||
if (rli->relay_log.is_active(rli->linfo.log_file_name))
|
if (rli->relay_log.is_active(rli->linfo.log_file_name))
|
||||||
{
|
{
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
|
if (global_system_variables.log_warnings)
|
||||||
sql_print_error("next log '%s' is currently active",
|
sql_print_error("next log '%s' is currently active",
|
||||||
rli->linfo.log_file_name);
|
rli->linfo.log_file_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -4119,6 +4135,7 @@ Before assert, my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
|
||||||
from hot to cold, but not from cold to hot). No need for LOCK_log.
|
from hot to cold, but not from cold to hot). No need for LOCK_log.
|
||||||
*/
|
*/
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
|
if (global_system_variables.log_warnings)
|
||||||
sql_print_error("next log '%s' is not active",
|
sql_print_error("next log '%s' is not active",
|
||||||
rli->linfo.log_file_name);
|
rli->linfo.log_file_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1860,11 +1860,11 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
|
||||||
{
|
{
|
||||||
// It is success (nobody can prevent us write data)
|
// It is success (nobody can prevent us write data)
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||||
byte *rest = (byte*) data;
|
|
||||||
Query_cache_block *block = *result_block;
|
|
||||||
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
|
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
|
||||||
ALIGN_SIZE(sizeof(Query_cache_result)));
|
ALIGN_SIZE(sizeof(Query_cache_result)));
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
Query_cache_block *block= *result_block;
|
||||||
|
byte *rest= (byte*) data;
|
||||||
// Now fill list of blocks that created by allocate_data_chain
|
// Now fill list of blocks that created by allocate_data_chain
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
int res;
|
int res;
|
||||||
select_union *derived_result;
|
select_union *derived_result;
|
||||||
TABLE_LIST *tables= (TABLE_LIST *)first_select->table_list.first;
|
|
||||||
bool is_union= first_select->next_select() &&
|
bool is_union= first_select->next_select() &&
|
||||||
first_select->next_select()->linkage == UNION_TYPE;
|
first_select->next_select()->linkage == UNION_TYPE;
|
||||||
bool is_subsel= first_select->first_inner_unit() ? 1: 0;
|
bool is_subsel= first_select->first_inner_unit() ? 1: 0;
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@
|
||||||
#include "sql_acl.h"
|
#include "sql_acl.h"
|
||||||
|
|
||||||
static int check_null_fields(THD *thd,TABLE *entry);
|
static int check_null_fields(THD *thd,TABLE *entry);
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
|
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
|
||||||
static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup,
|
static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup,
|
||||||
char *query, uint query_length, int log_on);
|
char *query, uint query_length, int log_on);
|
||||||
static void end_delayed_insert(THD *thd);
|
static void end_delayed_insert(THD *thd);
|
||||||
extern "C" pthread_handler_decl(handle_delayed_insert,arg);
|
extern "C" pthread_handler_decl(handle_delayed_insert,arg);
|
||||||
static void unlink_blobs(register TABLE *table);
|
static void unlink_blobs(register TABLE *table);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define to force use of my_malloc() if the allocated memory block is big */
|
/* Define to force use of my_malloc() if the allocated memory block is big */
|
||||||
|
|
||||||
|
|
@ -131,7 +133,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
List_iterator_fast<List_item> its(values_list);
|
List_iterator_fast<List_item> its(values_list);
|
||||||
List_item *values;
|
List_item *values;
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
char *query= thd->query;
|
char *query= thd->query;
|
||||||
|
#endif
|
||||||
thr_lock_type lock_type = table_list->lock_type;
|
thr_lock_type lock_type = table_list->lock_type;
|
||||||
TABLE_LIST *insert_table_list= (TABLE_LIST*)
|
TABLE_LIST *insert_table_list= (TABLE_LIST*)
|
||||||
thd->lex->select_lex.table_list.first;
|
thd->lex->select_lex.table_list.first;
|
||||||
|
|
|
||||||
|
|
@ -1389,7 +1389,7 @@ create_total_list_n_last_return(THD *thd_arg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
|
||||||
if (slave_list_first)
|
if (slave_list_first)
|
||||||
{
|
{
|
||||||
*new_table_list= slave_list_first;
|
*new_table_list= slave_list_first;
|
||||||
|
|
|
||||||
|
|
@ -396,6 +396,7 @@ public:
|
||||||
SQL_LIST order_list; /* ORDER clause */
|
SQL_LIST order_list; /* ORDER clause */
|
||||||
List<List_item> expr_list;
|
List<List_item> expr_list;
|
||||||
List<List_item> when_list; /* WHEN clause (expression) */
|
List<List_item> when_list; /* WHEN clause (expression) */
|
||||||
|
SQL_LIST *gorder_list;
|
||||||
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
|
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
|
||||||
// Arrays of pointers to top elements of all_fields list
|
// Arrays of pointers to top elements of all_fields list
|
||||||
Item **ref_pointer_array;
|
Item **ref_pointer_array;
|
||||||
|
|
@ -538,7 +539,6 @@ typedef struct st_lex
|
||||||
gptr yacc_yyss,yacc_yyvs;
|
gptr yacc_yyss,yacc_yyvs;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
SQL_LIST *gorder_list;
|
|
||||||
|
|
||||||
List<key_part_spec> col_list;
|
List<key_part_spec> col_list;
|
||||||
List<key_part_spec> ref_list;
|
List<key_part_spec> ref_list;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@
|
||||||
extern "C" int gethostname(char *name, int namelen);
|
extern "C" int gethostname(char *name, int namelen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
|
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
|
||||||
|
#endif
|
||||||
static void decrease_user_connections(USER_CONN *uc);
|
static void decrease_user_connections(USER_CONN *uc);
|
||||||
static bool check_db_used(THD *thd,TABLE_LIST *tables);
|
static bool check_db_used(THD *thd,TABLE_LIST *tables);
|
||||||
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
|
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
|
||||||
|
|
@ -426,6 +428,8 @@ void init_max_user_conn(void)
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
|
||||||
static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
|
|
@ -456,7 +460,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
||||||
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Decrease user connection count
|
Decrease user connection count
|
||||||
|
|
@ -545,15 +549,15 @@ bool is_update_query(enum enum_sql_command command)
|
||||||
|
|
||||||
static bool check_mqh(THD *thd, uint check_command)
|
static bool check_mqh(THD *thd, uint check_command)
|
||||||
{
|
{
|
||||||
|
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
return(0);
|
||||||
|
#else
|
||||||
bool error=0;
|
bool error=0;
|
||||||
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
|
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
|
||||||
USER_CONN *uc=thd->user_connect;
|
USER_CONN *uc=thd->user_connect;
|
||||||
DBUG_ENTER("check_mqh");
|
DBUG_ENTER("check_mqh");
|
||||||
DBUG_ASSERT(uc != 0);
|
DBUG_ASSERT(uc != 0);
|
||||||
|
|
||||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
#else
|
|
||||||
/* If more than a hour since last check, reset resource checking */
|
/* If more than a hour since last check, reset resource checking */
|
||||||
if (check_time - uc->intime >= 3600)
|
if (check_time - uc->intime >= 3600)
|
||||||
{
|
{
|
||||||
|
|
@ -3518,7 +3522,10 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
||||||
DBUG_ENTER("check_access");
|
DBUG_ENTER("check_access");
|
||||||
DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
|
DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
|
||||||
thd->master_access));
|
thd->master_access));
|
||||||
ulong db_access,dummy;
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
ulong db_access;
|
||||||
|
#endif
|
||||||
|
ulong dummy;
|
||||||
if (save_priv)
|
if (save_priv)
|
||||||
*save_priv=0;
|
*save_priv=0;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1121,9 +1121,10 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
|
||||||
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
||||||
{
|
{
|
||||||
ulong stmt_id= uint4korr(packet);
|
ulong stmt_id= uint4korr(packet);
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
uchar *packet_end= (uchar *) packet + packet_length - 1;
|
uchar *packet_end= (uchar *) packet + packet_length - 1;
|
||||||
|
#endif
|
||||||
Prepared_statement *stmt;
|
Prepared_statement *stmt;
|
||||||
|
|
||||||
DBUG_ENTER("mysql_stmt_execute");
|
DBUG_ENTER("mysql_stmt_execute");
|
||||||
|
|
||||||
packet+= 9; /* stmt_id + 5 bytes of flags */
|
packet+= 9; /* stmt_id + 5 bytes of flags */
|
||||||
|
|
|
||||||
|
|
@ -3608,7 +3608,6 @@ static void
|
||||||
make_join_readinfo(JOIN *join, uint options)
|
make_join_readinfo(JOIN *join, uint options)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
SELECT_LEX *select_lex= &join->thd->lex->select_lex;
|
|
||||||
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
|
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
|
||||||
DBUG_ENTER("make_join_readinfo");
|
DBUG_ENTER("make_join_readinfo");
|
||||||
|
|
||||||
|
|
@ -3878,9 +3877,7 @@ JOIN::join_free(bool full)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
||||||
{
|
|
||||||
tab->cleanup();
|
tab->cleanup();
|
||||||
}
|
|
||||||
table= 0;
|
table= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4815,17 +4812,19 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||||
default:
|
default:
|
||||||
// This case should never be choosen
|
// This case should never be choosen
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
|
thd->fatal_error();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thd->fatal_error();
|
/* We never come here */
|
||||||
return 0; // Error
|
|
||||||
}
|
}
|
||||||
case Item::FIELD_ITEM:
|
case Item::FIELD_ITEM:
|
||||||
case Item::DEFAULT_VALUE_ITEM:
|
case Item::DEFAULT_VALUE_ITEM:
|
||||||
return create_tmp_field_from_field(thd, (*from_field=
|
{
|
||||||
((Item_field*) item)->field),
|
Item_field *field= (Item_field*) item;
|
||||||
|
return create_tmp_field_from_field(thd, (*from_field= field->field),
|
||||||
item, table, modify_item);
|
item, table, modify_item);
|
||||||
|
}
|
||||||
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:
|
||||||
|
|
@ -8543,6 +8542,23 @@ bool JOIN::alloc_func_list()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize 'sum_funcs' array with all Item_sum objects
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
make_sum_func_list()
|
||||||
|
field_list All items
|
||||||
|
send_fields Items in select list
|
||||||
|
before_group_by Set to 1 if this is called before GROUP BY handling
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Calls ::setup() for all item_sum objects in field_list
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
|
bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
|
||||||
bool before_group_by)
|
bool before_group_by)
|
||||||
{
|
{
|
||||||
|
|
@ -9079,7 +9095,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||||
List<Item> field_list;
|
List<Item> field_list;
|
||||||
List<Item> item_list;
|
List<Item> item_list;
|
||||||
THD *thd=join->thd;
|
THD *thd=join->thd;
|
||||||
SELECT_LEX *select_lex= &join->thd->lex->select_lex;
|
|
||||||
select_result *result=join->result;
|
select_result *result=join->result;
|
||||||
Item *item_null= new Item_null();
|
Item *item_null= new Item_null();
|
||||||
CHARSET_INFO *cs= &my_charset_latin1;
|
CHARSET_INFO *cs= &my_charset_latin1;
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,11 @@ static const char *grant_names[]={
|
||||||
"select","insert","update","delete","create","drop","reload","shutdown",
|
"select","insert","update","delete","create","drop","reload","shutdown",
|
||||||
"process","file","grant","references","index","alter"};
|
"process","file","grant","references","index","alter"};
|
||||||
|
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
|
static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
|
||||||
"grant_types",
|
"grant_types",
|
||||||
grant_names};
|
grant_names};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int mysql_find_files(THD *thd,List<char> *files, const char *db,
|
static int mysql_find_files(THD *thd,List<char> *files, const char *db,
|
||||||
const char *path, const char *wild, bool dir);
|
const char *path, const char *wild, bool dir);
|
||||||
|
|
@ -367,7 +369,9 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
|
||||||
char *ext;
|
char *ext;
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
FILEINFO *file;
|
FILEINFO *file;
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
uint col_access=thd->col_access;
|
uint col_access=thd->col_access;
|
||||||
|
#endif
|
||||||
TABLE_LIST table_list;
|
TABLE_LIST table_list;
|
||||||
DBUG_ENTER("mysql_find_files");
|
DBUG_ENTER("mysql_find_files");
|
||||||
|
|
||||||
|
|
@ -829,7 +833,9 @@ int mysqld_show_create_db(THD *thd, char *dbname,
|
||||||
char path[FN_REFLEN];
|
char path[FN_REFLEN];
|
||||||
char buff[2048];
|
char buff[2048];
|
||||||
String buffer(buff, sizeof(buff), system_charset_info);
|
String buffer(buff, sizeof(buff), system_charset_info);
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
uint db_access;
|
uint db_access;
|
||||||
|
#endif
|
||||||
bool found_libchar;
|
bool found_libchar;
|
||||||
HA_CREATE_INFO create;
|
HA_CREATE_INFO create;
|
||||||
uint create_options = create_info ? create_info->options : 0;
|
uint create_options = create_info ? create_info->options : 0;
|
||||||
|
|
@ -1138,7 +1144,6 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
|
||||||
{
|
{
|
||||||
const char *name_end;
|
const char *name_end;
|
||||||
char quote_char;
|
char quote_char;
|
||||||
uint part_len;
|
|
||||||
|
|
||||||
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
|
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
|
||||||
quote_char= '\"';
|
quote_char= '\"';
|
||||||
|
|
|
||||||
|
|
@ -3066,7 +3066,7 @@ sum_expr:
|
||||||
| GROUP_CONCAT_SYM '(' opt_distinct expr_list opt_gorder_clause
|
| GROUP_CONCAT_SYM '(' opt_distinct expr_list opt_gorder_clause
|
||||||
opt_gconcat_separator ')'
|
opt_gconcat_separator ')'
|
||||||
{
|
{
|
||||||
$$=new Item_func_group_concat($3,$4,Lex->gorder_list,$6);
|
$$=new Item_func_group_concat($3,$4,Select->gorder_list,$6);
|
||||||
$4->empty();
|
$4->empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3082,16 +3082,15 @@ opt_gconcat_separator:
|
||||||
opt_gorder_clause:
|
opt_gorder_clause:
|
||||||
/* empty */
|
/* empty */
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
Select->gorder_list = NULL;
|
||||||
lex->gorder_list = NULL;
|
|
||||||
}
|
}
|
||||||
| order_clause
|
| order_clause
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
SELECT_LEX *select= Select;
|
||||||
lex->gorder_list=
|
select->gorder_list=
|
||||||
(SQL_LIST*) sql_memdup((char*) &lex->current_select->order_list,
|
(SQL_LIST*) sql_memdup((char*) &select->order_list,
|
||||||
sizeof(st_sql_list));
|
sizeof(st_sql_list));
|
||||||
lex->current_select->order_list.empty();
|
select->order_list.empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue