Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
aee0d02a
Commit
aee0d02a
authored
Apr 02, 2003
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Auto merged
BitKeeper/etc/logging_ok: auto-union
parents
69b8b99a
6feda00d
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
879 additions
and
43 deletions
+879
-43
include/mysqld_error.h
include/mysqld_error.h
+2
-5
mysql-test/r/func_gconcat.result
mysql-test/r/func_gconcat.result
+161
-0
mysql-test/t/func_gconcat.test
mysql-test/t/func_gconcat.test
+79
-0
sql/field.h
sql/field.h
+1
-0
sql/item_sum.cc
sql/item_sum.cc
+456
-0
sql/item_sum.h
sql/item_sum.h
+85
-1
sql/lex.h
sql/lex.h
+2
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-2
sql/share/english/errmsg.txt
sql/share/english/errmsg.txt
+4
-7
sql/sql_class.h
sql/sql_class.h
+44
-22
sql/sql_error.cc
sql/sql_error.cc
+9
-3
sql/sql_lex.h
sql/sql_lex.h
+1
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+33
-3
No files found.
include/mysqld_error.h
View file @
aee0d02a
...
@@ -266,8 +266,5 @@
...
@@ -266,8 +266,5 @@
#define ER_SELECT_REDUCED 1247
#define ER_SELECT_REDUCED 1247
#define ER_TABLENAME_NOT_ALLOWED_HERE 1248
#define ER_TABLENAME_NOT_ALLOWED_HERE 1248
#define ER_NOT_SUPPORTED_AUTH_MODE 1249
#define ER_NOT_SUPPORTED_AUTH_MODE 1249
#define ER_SPATIAL_CANT_HAVE_NULL 1250
#define ER_CUT_VALUE_GROUP_CONCAT 1250
#define ER_COLLATION_CHARSET_MISMATCH 1251
#define ER_ERROR_MESSAGES 251
#define ER_SLAVE_WAS_RUNNING 1252
#define ER_SLAVE_WAS_NOT_RUNNING 1253
#define ER_ERROR_MESSAGES 254
mysql-test/r/func_gconcat.result
0 → 100644
View file @
aee0d02a
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
create table t1 (grp int, a bigint unsigned, c char(10) not null, d char(10) not null);
insert into t1 values (1,1,"a","a");
insert into t1 values (2,2,"b","a");
insert into t1 values (2,3,"c","b");
insert into t1 values (3,4,"E","a");
insert into t1 values (3,5,"C","b");
insert into t1 values (3,6,"D","b");
insert into t1 values (3,7,"d","d");
insert into t1 values (3,8,"d","d");
insert into t1 values (3,9,"D","c");
select grp,group_concat(c) from t1 group by grp;
grp group_concat(c)
1 a
2 b c
3 E C D d d D
select grp,group_concat(a,c) from t1 group by grp;
grp group_concat(a,c)
1 1a
2 2b 3c
3 4E 5C 6D 7d 8d 9D
select grp,group_concat("(",a,":",c,")") from t1 group by grp;
grp group_concat("(",a,":",c,")")
1 (1:a)
2 (2:b) (3:c)
3 (4:E) (5:C) (6:D) (7:d) (8:d) (9:D)
select grp,group_concat(c separator ",") from t1 group by grp;
grp group_concat(c separator ",")
1 a
2 b,c
3 E,C,D,d,d,D
select grp,group_concat(c separator "---->") from t1 group by grp;
grp group_concat(c separator "---->")
1 a
2 b---->c
3 E---->C---->D---->d---->d---->D
select grp,group_concat(c order by c) from t1 group by grp;
grp group_concat(c order by c)
1 a
2 b c
3 C D d d D E
select grp,group_concat(c order by c desc) from t1 group by grp;
grp group_concat(c order by c desc)
1 a
2 c b
3 E D d d D C
select grp,group_concat(d order by a) from t1 group by grp;
grp group_concat(d order by a)
1 a
2 a b
3 a b b d d c
select grp,group_concat(d order by a desc) from t1 group by grp;
grp group_concat(d order by a desc)
1 a
2 b a
3 c d d b b a
select grp,group_concat(a order by a,d+c) from t1 group by grp;
grp group_concat(a order by a,d+c)
1 1
2 2 3
3 4 5 6 7 8 9
select grp,group_concat(c order by 1) from t1 group by grp;
grp group_concat(c order by 1)
1 a
2 b c
3 C D d d D E
select grp,group_concat(c order by "c") from t1 group by grp;
grp group_concat(c order by "c")
1 a
2 b c
3 C D d d D E
select grp,group_concat(distinct c order by c) from t1 group by grp;
grp group_concat(distinct c order by c)
1 a
2 b c
3 C D E
select grp,group_concat(distinct c order by c desc) from t1 group by grp;
grp group_concat(distinct c order by c desc)
1 a
2 c b
3 E D C
select grp,group_concat(c order by c separator ",") from t1 group by grp;
grp group_concat(c order by c separator ",")
1 a
2 b,c
3 C,D,d,d,D,E
select grp,group_concat(c order by c desc separator ",") from t1 group by grp;
grp group_concat(c order by c desc separator ",")
1 a
2 c,b
3 E,D,d,d,D,C
select grp,group_concat(distinct c order by c separator ",") from t1 group by grp;
grp group_concat(distinct c order by c separator ",")
1 a
2 b,c
3 C,D,E
select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp;
grp group_concat(distinct c order by c desc separator ",")
1 a
2 c,b
3 E,D,C
select grp,group_concat(c order by grp desc) from t1 group by grp order by grp;
grp group_concat(c order by grp desc)
1 a
2 c b
3 D d d D C E
select grp, group_concat(a separator "")+0 from t1 group by grp;
grp group_concat(a separator "")+0
1 1
2 23
3 456789
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
grp group_concat(a separator "")+0.0
1 1.0
2 23.0
3 456789.0
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
grp ROUND(group_concat(a separator ""))
1 1
2 23
3 456789
drop table t1;
create table t1 (grp int, c char(10));
insert into t1 values (1,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;
grp group_concat(c order by c)
1 NULL
2 b
3 D D E
4
5 NULL
set group_concat_max_len = 5;
select grp,group_concat(c) from t1 group by grp;
grp group_concat(c)
1 NULL
2 b
3 E D D
4
5 NULL
Warnings:
Warning 1250 1 line(s) was(were) cut by group_concat()
show warnings;
Level Code Message
Warning 1250 1 line(s) was(were) cut by group_concat()
select group_concat(sum(a)) from t1 group by grp;
Invalid use of group function
select grp,group_concat(c order by 2) from t1 group by grp;
Unknown column '2' in 'group statement'
drop table if exists t1;
mysql-test/t/func_gconcat.test
0 → 100644
View file @
aee0d02a
#
# simple test of group_concat function
#
drop
table
if
exists
t1
;
create
table
t1
(
grp
int
,
a
bigint
unsigned
,
c
char
(
10
)
not
null
,
d
char
(
10
)
not
null
);
insert
into
t1
values
(
1
,
1
,
"a"
,
"a"
);
insert
into
t1
values
(
2
,
2
,
"b"
,
"a"
);
insert
into
t1
values
(
2
,
3
,
"c"
,
"b"
);
insert
into
t1
values
(
3
,
4
,
"E"
,
"a"
);
insert
into
t1
values
(
3
,
5
,
"C"
,
"b"
);
insert
into
t1
values
(
3
,
6
,
"D"
,
"b"
);
insert
into
t1
values
(
3
,
7
,
"d"
,
"d"
);
insert
into
t1
values
(
3
,
8
,
"d"
,
"d"
);
insert
into
t1
values
(
3
,
9
,
"D"
,
"c"
);
# Test of MySQL simple request
select
grp
,
group_concat
(
c
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
a
,
c
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
"("
,
a
,
":"
,
c
,
")"
)
from
t1
group
by
grp
;
# Test of MySQL with options
select
grp
,
group_concat
(
c
separator
","
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
separator
"---->"
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
c
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
c
desc
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
d
order
by
a
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
d
order
by
a
desc
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
a
order
by
a
,
d
+
c
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
1
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
"c"
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
distinct
c
order
by
c
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
distinct
c
order
by
c
desc
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
c
separator
","
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
c
order
by
c
desc
separator
","
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
distinct
c
order
by
c
separator
","
)
from
t1
group
by
grp
;
select
grp
,
group_concat
(
distinct
c
order
by
c
desc
separator
","
)
from
t1
group
by
grp
;
# Test of SQL_LIST objects
select
grp
,
group_concat
(
c
order
by
grp
desc
)
from
t1
group
by
grp
order
by
grp
;
# Test transfer to real values
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
,
ROUND
(
group_concat
(
a
separator
""
))
from
t1
group
by
grp
;
# Test NULL values
drop
table
t1
;
create
table
t1
(
grp
int
,
c
char
(
10
));
insert
into
t1
values
(
1
,
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
;
# Test warnings
set
group_concat_max_len
=
5
;
select
grp
,
group_concat
(
c
)
from
t1
group
by
grp
;
show
warnings
;
# Test errors
--
error
1111
select
group_concat
(
sum
(
a
))
from
t1
group
by
grp
;
--
error
1054
select
grp
,
group_concat
(
c
order
by
2
)
from
t1
group
by
grp
;
drop
table
if
exists
t1
;
sql/field.h
View file @
aee0d02a
...
@@ -224,6 +224,7 @@ public:
...
@@ -224,6 +224,7 @@ public:
friend
class
Item_sum_std
;
friend
class
Item_sum_std
;
friend
class
Item_sum_min
;
friend
class
Item_sum_min
;
friend
class
Item_sum_max
;
friend
class
Item_sum_max
;
friend
class
Item_func_group_concat
;
};
};
...
...
sql/item_sum.cc
View file @
aee0d02a
...
@@ -1329,3 +1329,459 @@ String *Item_sum_udf_str::val_str(String *str)
...
@@ -1329,3 +1329,459 @@ String *Item_sum_udf_str::val_str(String *str)
}
}
#endif
/* HAVE_DLOPEN */
#endif
/* HAVE_DLOPEN */
/*****************************************************************************
GROUP_CONCAT function
Syntax:
GROUP_CONCAT([DISTINCT] expr,... [ORDER BY col [ASC|DESC],...]
[SEPARATOR str_const])
concat of values from "group by" operation
*****************************************************************************/
/*
function of sort for syntax:
GROUP_CONCAT(DISTINCT expr,...)
*/
static
int
group_concat_key_cmp_with_distinct
(
void
*
arg
,
byte
*
key1
,
byte
*
key2
)
{
Item_func_group_concat
*
item
=
(
Item_func_group_concat
*
)
arg
;
for
(
int
i
=
0
;
i
<
item
->
arg_count_field
;
i
++
)
{
Item
*
field_item
=
item
->
expr
[
i
];
Field
*
field
=
field_item
->
tmp_table_field
();
if
(
field
)
{
uint
offset
=
field
->
offset
();
int
res
=
field
->
key_cmp
(
key1
+
offset
,
key2
+
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
;
}
/*
function of sort for syntax:
GROUP_CONCAT(expr,... ORDER BY col,... )
*/
static
int
group_concat_key_cmp_with_order
(
void
*
arg
,
byte
*
key1
,
byte
*
key2
)
{
Item_func_group_concat
*
item
=
(
Item_func_group_concat
*
)
arg
;
for
(
int
i
=
0
;
i
<
item
->
arg_count_order
;
i
++
)
{
ORDER
*
order_item
=
item
->
order
[
i
];
Item
*
item
=
*
order_item
->
item
;
Field
*
field
=
item
->
tmp_table_field
();
if
(
field
)
{
uint
offset
=
field
->
offset
();
bool
dir
=
order_item
->
asc
;
int
res
=
field
->
key_cmp
(
key1
+
offset
,
key2
+
offset
);
if
(
res
)
return
dir
?
res
:
-
res
;
}
}
/*
We can't return 0 becouse tree class remove this item as dubl value.
*/
return
1
;
}
/*
function of sort for syntax:
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
*/
static
int
group_concat_key_cmp_with_distinct_and_order
(
void
*
arg
,
byte
*
key1
,
byte
*
key2
)
{
Item_func_group_concat
*
item
=
(
Item_func_group_concat
*
)
arg
;
if
(
!
group_concat_key_cmp_with_distinct
(
arg
,
key1
,
key2
))
return
0
;
return
(
group_concat_key_cmp_with_order
(
arg
,
key1
,
key2
));
}
/*
create result
item is pointer to Item_func_group_concat
*/
static
int
dump_leaf_key
(
byte
*
key
,
uint32
count
__attribute__
((
unused
)),
Item_func_group_concat
*
group_concat_item
)
{
char
buff
[
MAX_FIELD_WIDTH
];
String
tmp
((
char
*
)
&
buff
,
sizeof
(
buff
),
default_charset_info
);
String
tmp2
((
char
*
)
&
buff
,
sizeof
(
buff
),
default_charset_info
);
tmp
.
length
(
0
);
for
(
int
i
=
0
;
i
<
group_concat_item
->
arg_show_fields
;
i
++
)
{
Item
*
show_item
=
group_concat_item
->
expr
[
i
];
if
(
!
show_item
->
const_item
())
{
Field
*
f
=
show_item
->
tmp_table_field
();
uint
offset
=
f
->
offset
();
char
*
sv
=
f
->
ptr
;
f
->
ptr
=
(
char
*
)
key
+
offset
;
String
*
res
=
f
->
val_str
(
&
tmp
,
&
tmp2
);
group_concat_item
->
result
.
append
(
*
res
);
f
->
ptr
=
sv
;
}
else
{
String
*
res
=
show_item
->
val_str
(
&
tmp
);
if
(
res
)
group_concat_item
->
result
.
append
(
*
res
);
}
}
if
(
group_concat_item
->
tree_mode
)
// Last item of tree
{
group_concat_item
->
show_elements
++
;
if
(
group_concat_item
->
show_elements
<
group_concat_item
->
tree
->
elements_in_tree
)
group_concat_item
->
result
.
append
(
*
group_concat_item
->
separator
);
}
else
{
group_concat_item
->
result
.
append
(
*
group_concat_item
->
separator
);
}
/*
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
0
;
}
/*
Constructor of Item_func_group_concat
is_distinct - distinct
is_select - list of expression for show values
is_order - list of sort columns
is_separator - string value of separator
*/
Item_func_group_concat
::
Item_func_group_concat
(
int
is_distinct
,
List
<
Item
>
*
is_select
,
SQL_LIST
*
is_order
,
String
*
is_separator
)
:
Item_sum
(),
tmp_table_param
(
0
),
warning_available
(
false
),
separator
(
is_separator
),
tree
(
&
tree_base
),
table
(
0
),
distinct
(
is_distinct
),
tree_mode
(
0
),
count_cut_values
(
0
)
{
original
=
0
;
quick_group
=
0
;
mark_as_sum_func
();
SELECT_LEX
*
select_lex
=
current_lex
->
current_select
->
select_lex
();
order
=
0
;
arg_show_fields
=
arg_count_field
=
is_select
->
elements
;
arg_count_order
=
is_order
?
is_order
->
elements
:
0
;
arg_count
=
arg_count_field
;
/*
We need to allocate:
args - arg_count+arg_count_order (for possible order items in temporare
tables)
expr - arg_count_field
order - arg_count_order
*/
args
=
(
Item
**
)
sql_alloc
(
sizeof
(
Item
*
)
*
(
arg_count
+
arg_count_order
+
arg_count_field
)
+
sizeof
(
ORDER
*
)
*
arg_count_order
);
if
(
!
args
)
{
my_error
(
ER_OUTOFMEMORY
,
MYF
(
0
));
}
expr
=
args
;
expr
+=
arg_count
+
arg_count_order
;
if
(
arg_count_order
)
{
order
=
(
ORDER
**
)(
expr
+
arg_count_field
);
}
/*
fill args items of show and sort
*/
int
i
=
0
;
List_iterator_fast
<
Item
>
li
(
*
is_select
);
Item
*
item_select
;
while
((
item_select
=
li
++
))
{
args
[
i
]
=
expr
[
i
]
=
item_select
;
i
++
;
}
if
(
order
)
{
uint
j
=
0
;
for
(
ORDER
*
order_item
=
(
ORDER
*
)
is_order
->
first
;
order_item
!=
NULL
;
order_item
=
order_item
->
next
)
{
order
[
j
++
]
=
order_item
;
}
}
}
Item_func_group_concat
::~
Item_func_group_concat
()
{
/*
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
)
{
if
(
warning_available
)
{
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
sprintf
(
warn_buff
,
ER
(
ER_CUT_VALUE_GROUP_CONCAT
),
count_cut_values
);
((
MYSQL_ERROR
*
)
warning
)
->
set_msg
((
char
*
)
&
warn_buff
);
}
if
(
table
)
free_tmp_table
(
current_thd
,
table
);
if
(
tmp_table_param
)
delete
tmp_table_param
;
if
(
tree_mode
)
delete_tree
(
tree
);
}
}
void
Item_func_group_concat
::
reset
()
{
result
.
length
(
0
);
result
.
copy
();
null_value
=
TRUE
;
warning_for_row
=
false
;
if
(
table
)
{
table
->
file
->
extra
(
HA_EXTRA_NO_CACHE
);
table
->
file
->
delete_all_rows
();
table
->
file
->
extra
(
HA_EXTRA_WRITE_CACHE
);
}
if
(
tree_mode
)
reset_tree
(
tree
);
add
();
}
bool
Item_func_group_concat
::
add
()
{
copy_fields
(
tmp_table_param
);
copy_funcs
(
tmp_table_param
->
items_to_copy
);
bool
record_is_null
=
TRUE
;
for
(
int
i
=
0
;
i
<
arg_show_fields
;
i
++
)
{
Item
*
show_item
=
expr
[
i
];
if
(
!
show_item
->
const_item
())
{
Field
*
f
=
show_item
->
tmp_table_field
();
if
(
!
f
->
is_null
())
record_is_null
=
FALSE
;
}
}
if
(
record_is_null
)
return
0
;
null_value
=
FALSE
;
if
(
tree_mode
)
{
if
(
!
tree_insert
(
tree
,
table
->
record
[
0
],
0
,
tree
->
custom_arg
))
return
1
;
}
else
{
if
(
result
.
length
()
<=
group_concat_max_len
&&
!
warning_for_row
)
dump_leaf_key
(
table
->
record
[
0
],
1
,
(
Item_func_group_concat
*
)
this
);
}
return
0
;
}
void
Item_func_group_concat
::
reset_field
()
{
if
(
tree_mode
)
reset_tree
(
tree
);
}
bool
Item_func_group_concat
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
if
(
!
thd
->
allow_sum_func
)
{
my_error
(
ER_INVALID_GROUP_FUNC_USE
,
MYF
(
0
));
return
1
;
}
thd
->
allow_sum_func
=
0
;
maybe_null
=
0
;
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
args
[
i
]
->
fix_fields
(
thd
,
tables
,
args
+
i
)
||
args
[
i
]
->
check_cols
(
1
))
return
1
;
maybe_null
|=
args
[
i
]
->
maybe_null
;
}
for
(
int
i
=
0
;
i
<
arg_count_field
;
i
++
)
{
if
(
expr
[
i
]
->
fix_fields
(
thd
,
tables
,
expr
+
i
)
||
expr
[
i
]
->
check_cols
(
1
))
return
1
;
maybe_null
|=
expr
[
i
]
->
maybe_null
;
}
/*
Fix fields for order clause in function:
GROUP_CONCAT(expr,... ORDER BY col,... )
*/
for
(
int
i
=
0
;
i
<
arg_count_order
;
i
++
)
{
ORDER
*
order_item
=
order
[
i
];
Item
*
item
=*
order_item
->
item
;
if
(
item
->
fix_fields
(
thd
,
tables
,
&
item
)
||
item
->
check_cols
(
1
))
return
1
;
}
result_field
=
0
;
null_value
=
1
;
fix_length_and_dec
();
thd
->
allow_sum_func
=
1
;
if
(
!
(
tmp_table_param
=
new
TMP_TABLE_PARAM
))
return
1
;
tables_list
=
tables
;
fixed
=
1
;
return
0
;
}
bool
Item_func_group_concat
::
setup
(
THD
*
thd
)
{
List
<
Item
>
list
;
SELECT_LEX
*
select_lex
=
current_lex
->
current_select
->
select_lex
();
if
(
select_lex
->
linkage
==
GLOBAL_OPTIONS_TYPE
)
return
1
;
/*
all not constant fields are push to list and create temp table
*/
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
Item
*
item
=
args
[
i
];
if
(
list
.
push_back
(
item
))
return
1
;
if
(
item
->
const_item
())
{
(
void
)
item
->
val_int
();
if
(
item
->
null_value
)
always_null
=
1
;
}
}
List
<
Item
>
all_fields
(
list
);
if
(
arg_count_order
)
{
bool
hidden_group_fields
;
setup_group
(
thd
,
args
,
tables_list
,
list
,
all_fields
,
*
order
,
&
hidden_group_fields
);
}
count_field_types
(
tmp_table_param
,
all_fields
,
0
);
/*
We have to create a temporary table for that we get descriptions of fields
(types, sizes and so on).
*/
if
(
!
(
table
=
create_tmp_table
(
thd
,
tmp_table_param
,
all_fields
,
0
,
0
,
0
,
0
,
select_lex
->
options
|
thd
->
options
)))
return
1
;
table
->
file
->
extra
(
HA_EXTRA_NO_ROWS
);
table
->
no_rows
=
1
;
qsort_cmp2
compare_key
;
tree_mode
=
distinct
||
arg_count_order
;
/*
choise function of sort
*/
if
(
tree_mode
)
{
if
(
arg_count_order
)
{
if
(
distinct
)
compare_key
=
(
qsort_cmp2
)
group_concat_key_cmp_with_distinct_and_order
;
else
compare_key
=
(
qsort_cmp2
)
group_concat_key_cmp_with_order
;
}
else
{
if
(
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
values (according with syntax of the function). If function does't
contain DISTINCT and ORDER BY clauses, we don't create this tree.
*/
init_tree
(
tree
,
min
(
thd
->
variables
.
max_heap_table_size
,
thd
->
variables
.
sortbuff_size
/
16
),
0
,
table
->
reclength
,
compare_key
,
0
,
NULL
,
(
void
*
)
this
);
max_elements_in_tree
=
((
table
->
reclength
)
?
thd
->
variables
.
max_heap_table_size
/
table
->
reclength
:
1
);
};
item_thd
=
thd
;
group_concat_max_len
=
thd
->
variables
.
group_concat_max_len
;
/*
Copy table and tree_mode 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
)
{
original
->
table
=
table
;
original
->
tree_mode
=
tree_mode
;
}
return
0
;
}
String
*
Item_func_group_concat
::
val_str
(
String
*
str
)
{
if
(
null_value
)
return
0
;
if
(
tree_mode
)
{
show_elements
=
0
;
tree_walk
(
tree
,
(
tree_walk_action
)
&
dump_leaf_key
,
(
void
*
)
this
,
left_root_right
);
}
else
{
if
(
!
warning_for_row
)
result
.
length
(
result
.
length
()
-
separator
->
length
());
}
if
(
count_cut_values
&&
!
warning_available
)
{
warning_available
=
TRUE
;
warning
=
push_warning
(
item_thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_CUT_VALUE_GROUP_CONCAT
,
NULL
);
}
return
&
result
;
}
sql/item_sum.h
View file @
aee0d02a
...
@@ -28,7 +28,7 @@ class Item_sum :public Item_result_field
...
@@ -28,7 +28,7 @@ class Item_sum :public Item_result_field
public:
public:
enum
Sumfunctype
{
COUNT_FUNC
,
COUNT_DISTINCT_FUNC
,
SUM_FUNC
,
AVG_FUNC
,
MIN_FUNC
,
enum
Sumfunctype
{
COUNT_FUNC
,
COUNT_DISTINCT_FUNC
,
SUM_FUNC
,
AVG_FUNC
,
MIN_FUNC
,
MAX_FUNC
,
UNIQUE_USERS_FUNC
,
STD_FUNC
,
VARIANCE_FUNC
,
SUM_BIT_FUNC
,
MAX_FUNC
,
UNIQUE_USERS_FUNC
,
STD_FUNC
,
VARIANCE_FUNC
,
SUM_BIT_FUNC
,
UDF_SUM_FUNC
};
UDF_SUM_FUNC
,
GROUP_CONCAT_FUNC
};
Item
**
args
,
*
tmp_args
[
2
];
Item
**
args
,
*
tmp_args
[
2
];
uint
arg_count
;
uint
arg_count
;
...
@@ -630,3 +630,87 @@ public:
...
@@ -630,3 +630,87 @@ public:
};
};
#endif
/* HAVE_DLOPEN */
#endif
/* HAVE_DLOPEN */
class
Item_func_group_concat
:
public
Item_sum
{
THD
*
item_thd
;
TMP_TABLE_PARAM
*
tmp_table_param
;
uint
max_elements_in_tree
;
void
*
warning
;
bool
warning_available
;
public:
String
result
;
String
*
separator
;
uint
show_elements
;
TREE
tree_base
;
TREE
*
tree
;
TABLE
*
table
;
int
arg_count_order
;
int
arg_count_field
;
int
arg_show_fields
;
int
distinct
;
Item
**
expr
;
ORDER
**
order
;
bool
tree_mode
;
int
count_cut_values
;
ulong
group_concat_max_len
;
bool
warning_for_row
;
TABLE_LIST
*
tables_list
;
bool
always_null
;
/*
Following is 0 normal object and pointer to original one for copy
(to correctly free resources)
*/
Item_func_group_concat
*
original
;
Item_func_group_concat
(
int
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_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
),
separator
(
item
.
separator
),
show_elements
(
item
.
show_elements
),
tree
(
item
.
tree
),
table
(
item
.
table
),
arg_count_order
(
item
.
arg_count_order
),
arg_count_field
(
item
.
arg_count_field
),
arg_show_fields
(
item
.
arg_show_fields
),
distinct
(
item
.
distinct
),
expr
(
item
.
expr
),
order
(
item
.
order
),
tree_mode
(
0
),
count_cut_values
(
item
.
count_cut_values
),
group_concat_max_len
(
item
.
group_concat_max_len
),
warning_for_row
(
item
.
warning_for_row
),
tables_list
(
item
.
tables_list
),
original
(
&
item
)
{
quick_group
=
0
;
};
~
Item_func_group_concat
();
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
;
}
virtual
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
void
reset
();
bool
add
();
void
reset_field
();
bool
fix_fields
(
THD
*
,
TABLE_LIST
*
,
Item
**
);
bool
setup
(
THD
*
thd
);
virtual
void
update_field
(
int
offset
)
{};
double
val
()
{
String
*
res
;
res
=
val_str
(
&
str_value
);
return
res
?
atof
(
res
->
c_ptr
())
:
0.0
;
}
longlong
val_int
()
{
String
*
res
;
res
=
val_str
(
&
str_value
);
return
res
?
strtoll
(
res
->
c_ptr
(),(
char
**
)
0
,
10
)
:
(
longlong
)
0
;
}
String
*
val_str
(
String
*
str
);
};
sql/lex.h
View file @
aee0d02a
...
@@ -335,6 +335,7 @@ static SYMBOL symbols[] = {
...
@@ -335,6 +335,7 @@ static SYMBOL symbols[] = {
{
"ROWS"
,
SYM
(
ROWS_SYM
),
0
,
0
},
{
"ROWS"
,
SYM
(
ROWS_SYM
),
0
,
0
},
{
"RTREE"
,
SYM
(
RTREE_SYM
),
0
,
0
},
{
"RTREE"
,
SYM
(
RTREE_SYM
),
0
,
0
},
{
"SECOND"
,
SYM
(
SECOND_SYM
),
0
,
0
},
{
"SECOND"
,
SYM
(
SECOND_SYM
),
0
,
0
},
{
"SEPARATOR"
,
SYM
(
SEPARATOR_SYM
),
0
,
0
},
{
"SELECT"
,
SYM
(
SELECT_SYM
),
0
,
0
},
{
"SELECT"
,
SYM
(
SELECT_SYM
),
0
,
0
},
{
"SERIAL"
,
SYM
(
SERIAL_SYM
),
0
,
0
},
{
"SERIAL"
,
SYM
(
SERIAL_SYM
),
0
,
0
},
{
"SERIALIZABLE"
,
SYM
(
SERIALIZABLE_SYM
),
0
,
0
},
{
"SERIALIZABLE"
,
SYM
(
SERIALIZABLE_SYM
),
0
,
0
},
...
@@ -503,6 +504,7 @@ static SYMBOL sql_functions[] = {
...
@@ -503,6 +504,7 @@ static SYMBOL sql_functions[] = {
{
"GEOMFROMWKB"
,
SYM
(
GEOMFROMWKB
),
0
,
0
},
{
"GEOMFROMWKB"
,
SYM
(
GEOMFROMWKB
),
0
,
0
},
{
"GLENGTH"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_glength
)},
{
"GLENGTH"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_glength
)},
{
"GREATEST"
,
SYM
(
GREATEST_SYM
),
0
,
0
},
{
"GREATEST"
,
SYM
(
GREATEST_SYM
),
0
,
0
},
{
"GROUP_CONCAT"
,
SYM
(
GROUP_CONCAT_SYM
),
0
,
0
},
{
"GROUP_UNIQUE_USERS"
,
SYM
(
GROUP_UNIQUE_USERS
),
0
,
0
},
{
"GROUP_UNIQUE_USERS"
,
SYM
(
GROUP_UNIQUE_USERS
),
0
,
0
},
{
"HEX"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_hex
)},
{
"HEX"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_hex
)},
{
"IFNULL"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_ifnull
)},
{
"IFNULL"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_ifnull
)},
...
...
sql/mysql_priv.h
View file @
aee0d02a
...
@@ -547,7 +547,7 @@ int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
...
@@ -547,7 +547,7 @@ int check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
List
<
Item
>
&
values
,
ulong
counter
);
List
<
Item
>
&
values
,
ulong
counter
);
/* sql_error.cc */
/* sql_error.cc */
void
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
const
char
*
msg
);
const
char
*
msg
);
void
push_warning_printf
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
void
push_warning_printf
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
const
char
*
format
,
...);
uint
code
,
const
char
*
format
,
...);
...
...
sql/share/english/errmsg.txt
View file @
aee0d02a
...
@@ -166,7 +166,7 @@
...
@@ -166,7 +166,7 @@
"Result string is longer than max_allowed_packet",
"Result string is longer than max_allowed_packet",
"The used table type doesn't support BLOB/TEXT columns",
"The used table type doesn't support BLOB/TEXT columns",
"The used table type doesn't support AUTO_INCREMENT columns",
"The used table type doesn't support AUTO_INCREMENT columns",
"INSERT DELAYED can't be used with table '%-.64s' because it is locked with LOCK TABLES",
"INSERT DELAYED can't be used with table '%-.64s'
,
because it is locked with LOCK TABLES",
"Incorrect column name '%-.100s'",
"Incorrect column name '%-.100s'",
"The used table handler can't index column '%-.64s'",
"The used table handler can't index column '%-.64s'",
"All tables in the MERGE table are not identically defined",
"All tables in the MERGE table are not identically defined",
...
@@ -198,7 +198,7 @@
...
@@ -198,7 +198,7 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Some non-transactional changed tables couldn't be rolled back",
"Some non-transactional changed tables couldn't be rolled back",
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again
"
,
"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again
'
,
"This operation cannot be performed with a running slave, run STOP SLAVE first",
"This operation cannot be performed with a running slave, run STOP SLAVE first",
"This operation requires a running slave, configure slave and do START SLAVE",
"This operation requires a running slave, configure slave and do START SLAVE",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
...
@@ -250,8 +250,5 @@
...
@@ -250,8 +250,5 @@
"Every derived table must have it's own alias",
"Every derived table must have it's own alias",
"Select %u was reduced during optimisation",
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
"Client does not support authentication protocol requested by server. Consider upgrading MySQL client"
"Client does not support authentication protocol requested by server. Consider upgrading MySQL client",
"All parts of a SPATIAL KEY must be NOT NULL"
"%d line(s) was(were) cut by group_concat()"
"COLLATION '%s' is not valid for CHARACTER SET '%s'"
"The slave was already running"
"The slave was already stopped"
sql/sql_class.h
View file @
aee0d02a
...
@@ -34,8 +34,6 @@ enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
...
@@ -34,8 +34,6 @@ enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
enum
enum_delay_key_write
{
DELAY_KEY_WRITE_NONE
,
DELAY_KEY_WRITE_ON
,
enum
enum_delay_key_write
{
DELAY_KEY_WRITE_NONE
,
DELAY_KEY_WRITE_ON
,
DELAY_KEY_WRITE_ALL
};
DELAY_KEY_WRITE_ALL
};
extern
char
internal_table_name
[
2
];
// log info errors
// log info errors
#define LOG_INFO_EOF -1
#define LOG_INFO_EOF -1
#define LOG_INFO_IO -2
#define LOG_INFO_IO -2
...
@@ -145,9 +143,7 @@ public:
...
@@ -145,9 +143,7 @@ public:
int
generate_new_name
(
char
*
new_name
,
const
char
*
old_name
);
int
generate_new_name
(
char
*
new_name
,
const
char
*
old_name
);
void
make_log_name
(
char
*
buf
,
const
char
*
log_ident
);
void
make_log_name
(
char
*
buf
,
const
char
*
log_ident
);
bool
is_active
(
const
char
*
log_file_name
);
bool
is_active
(
const
char
*
log_file_name
);
int
update_log_index
(
LOG_INFO
*
linfo
);
int
purge_logs
(
THD
*
thd
,
const
char
*
to_log
);
int
purge_logs
(
THD
*
thd
,
const
char
*
to_log
);
int
purge_logs_before_date
(
THD
*
thd
,
time_t
purge_time
);
int
purge_first_log
(
struct
st_relay_log_info
*
rli
);
int
purge_first_log
(
struct
st_relay_log_info
*
rli
);
bool
reset_logs
(
THD
*
thd
);
bool
reset_logs
(
THD
*
thd
);
// if we are exiting, we also want to close the index file
// if we are exiting, we also want to close the index file
...
@@ -174,6 +170,32 @@ public:
...
@@ -174,6 +170,32 @@ public:
/* character conversion tables */
/* character conversion tables */
class
CONVERT
;
CONVERT
*
get_convert_set
(
const
char
*
name_ptr
);
class
CONVERT
{
const
uchar
*
from_map
,
*
to_map
;
void
convert_array
(
const
uchar
*
mapping
,
uchar
*
buff
,
uint
length
);
public:
const
char
*
name
;
uint
numb
;
CONVERT
(
const
char
*
name_par
,
uchar
*
from_par
,
uchar
*
to_par
,
uint
number
)
:
from_map
(
from_par
),
to_map
(
to_par
),
name
(
name_par
),
numb
(
number
)
{}
friend
CONVERT
*
get_convert_set
(
const
char
*
name_ptr
);
inline
void
convert
(
char
*
a
,
uint
length
)
{
convert_array
(
from_map
,
(
uchar
*
)
a
,
length
);
}
char
*
store_dest
(
char
*
to
,
const
char
*
from
,
uint
length
)
{
for
(
const
char
*
end
=
from
+
length
;
from
!=
end
;
from
++
)
*
to
++=
to_map
[(
uchar
)
*
from
];
return
to
;
}
bool
store
(
String
*
,
const
char
*
,
uint
);
inline
uint
number
()
{
return
numb
;
}
};
typedef
struct
st_copy_info
{
typedef
struct
st_copy_info
{
ha_rows
records
;
ha_rows
records
;
...
@@ -304,6 +326,11 @@ public:
...
@@ -304,6 +326,11 @@ public:
MYSQL_ERROR
(
uint
code_arg
,
enum_warning_level
level_arg
,
MYSQL_ERROR
(
uint
code_arg
,
enum_warning_level
level_arg
,
const
char
*
msg_arg
)
const
char
*
msg_arg
)
:
code
(
code_arg
),
level
(
level_arg
)
:
code
(
code_arg
),
level
(
level_arg
)
{
if
(
msg_arg
)
msg
=
sql_strdup
(
msg_arg
);
}
inline
void
set_msg
(
const
char
*
msg_arg
)
{
{
msg
=
sql_strdup
(
msg_arg
);
msg
=
sql_strdup
(
msg_arg
);
}
}
...
@@ -333,6 +360,10 @@ class select_result;
...
@@ -333,6 +360,10 @@ class select_result;
#define THD_SENTRY_MAGIC 0xfeedd1ff
#define THD_SENTRY_MAGIC 0xfeedd1ff
#define THD_SENTRY_GONE 0xdeadbeef
#define THD_SENTRY_GONE 0xdeadbeef
#ifdef EMBEDDED_LIBRARY
typedef
struct
st_mysql
;
#endif
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
struct
system_variables
struct
system_variables
...
@@ -365,8 +396,7 @@ struct system_variables
...
@@ -365,8 +396,7 @@ struct system_variables
ulong
tmp_table_size
;
ulong
tmp_table_size
;
ulong
tx_isolation
;
ulong
tx_isolation
;
ulong
sql_mode
;
ulong
sql_mode
;
ulong
default_week_format
;
ulong
group_concat_max_len
;
/*
/*
In slave thread we need to know in behalf of which
In slave thread we need to know in behalf of which
thread the query is being run to replicate temp tables properly
thread the query is being run to replicate temp tables properly
...
@@ -375,9 +405,8 @@ struct system_variables
...
@@ -375,9 +405,8 @@ struct system_variables
my_bool
log_warnings
;
my_bool
log_warnings
;
my_bool
low_priority_updates
;
my_bool
low_priority_updates
;
my_bool
new_mode
;
my_bool
convert_result_charset
;
CONVERT
*
convert_set
;
CHARSET_INFO
*
thd_charset
;
CHARSET_INFO
*
thd_charset
;
};
};
...
@@ -424,9 +453,8 @@ public:
...
@@ -424,9 +453,8 @@ public:
db - currently selected database
db - currently selected database
ip - client IP
ip - client IP
*/
*/
char
*
host
,
*
user
,
*
priv_user
,
*
db
,
*
ip
;
char
*
host
,
*
user
,
*
priv_user
,
*
db
,
*
ip
;
/* remote (peer) port */
uint16
peer_port
;
/* Points to info-string that will show in SHOW PROCESSLIST */
/* Points to info-string that will show in SHOW PROCESSLIST */
const
char
*
proc_info
;
const
char
*
proc_info
;
/* points to host if host is available, otherwise points to ip */
/* points to host if host is available, otherwise points to ip */
...
@@ -549,7 +577,6 @@ public:
...
@@ -549,7 +577,6 @@ public:
void
init
(
void
);
void
init
(
void
);
void
change_user
(
void
);
void
change_user
(
void
);
void
init_for_queries
();
void
cleanup
(
void
);
void
cleanup
(
void
);
bool
store_globals
();
bool
store_globals
();
#ifdef SIGNAL_WITH_VIO_CLOSE
#ifdef SIGNAL_WITH_VIO_CLOSE
...
@@ -657,9 +684,7 @@ public:
...
@@ -657,9 +684,7 @@ public:
{
{
is_fatal_error
=
1
;
is_fatal_error
=
1
;
net
.
report_error
=
1
;
net
.
report_error
=
1
;
DBUG_PRINT
(
"error"
,(
"Fatal error set"
));
}
}
inline
CHARSET_INFO
*
charset
()
{
return
variables
.
thd_charset
;
}
};
};
/*
/*
...
@@ -885,11 +910,10 @@ class Table_ident :public Sql_alloc
...
@@ -885,11 +910,10 @@ class Table_ident :public Sql_alloc
LEX_STRING
db
;
LEX_STRING
db
;
LEX_STRING
table
;
LEX_STRING
table
;
SELECT_LEX_UNIT
*
sel
;
SELECT_LEX_UNIT
*
sel
;
inline
Table_ident
(
THD
*
thd
,
LEX_STRING
db_arg
,
LEX_STRING
table_arg
,
inline
Table_ident
(
LEX_STRING
db_arg
,
LEX_STRING
table_arg
,
bool
force
)
bool
force
)
:
table
(
table_arg
),
sel
((
SELECT_LEX_UNIT
*
)
0
)
:
table
(
table_arg
),
sel
((
SELECT_LEX_UNIT
*
)
0
)
{
{
if
(
!
force
&&
(
thd
->
client_capabilities
&
CLIENT_NO_SCHEMA
))
if
(
!
force
&&
(
current_
thd
->
client_capabilities
&
CLIENT_NO_SCHEMA
))
db
.
str
=
0
;
db
.
str
=
0
;
else
else
db
=
db_arg
;
db
=
db_arg
;
...
@@ -901,8 +925,7 @@ class Table_ident :public Sql_alloc
...
@@ -901,8 +925,7 @@ class Table_ident :public Sql_alloc
}
}
inline
Table_ident
(
SELECT_LEX_UNIT
*
s
)
:
sel
(
s
)
inline
Table_ident
(
SELECT_LEX_UNIT
*
s
)
:
sel
(
s
)
{
{
/* We must have a table name here as this is used with add_table_to_list */
db
.
str
=
0
;
table
.
str
=
(
char
*
)
""
;
table
.
length
=
0
;
db
.
str
=
0
;
table
.
str
=
internal_table_name
;
table
.
length
=
1
;
}
}
inline
void
change_db
(
char
*
db_name
)
inline
void
change_db
(
char
*
db_name
)
{
{
...
@@ -919,7 +942,6 @@ class user_var_entry
...
@@ -919,7 +942,6 @@ class user_var_entry
ulong
length
,
update_query_id
,
used_query_id
;
ulong
length
,
update_query_id
,
used_query_id
;
Item_result
type
;
Item_result
type
;
CHARSET_INFO
*
var_charset
;
CHARSET_INFO
*
var_charset
;
enum
Item
::
coercion
var_coercibility
;
};
};
/* Class for unique (removing of duplicates) */
/* Class for unique (removing of duplicates) */
...
@@ -978,7 +1000,7 @@ class multi_update : public select_result
...
@@ -978,7 +1000,7 @@ class multi_update : public select_result
{
{
TABLE_LIST
*
all_tables
,
*
update_tables
,
*
table_being_updated
;
TABLE_LIST
*
all_tables
,
*
update_tables
,
*
table_being_updated
;
THD
*
thd
;
THD
*
thd
;
TABLE
**
tmp_tables
,
*
main_table
,
*
table_to_update
;
TABLE
**
tmp_tables
,
*
main_table
;
TMP_TABLE_PARAM
*
tmp_table_param
;
TMP_TABLE_PARAM
*
tmp_table_param
;
ha_rows
updated
,
found
;
ha_rows
updated
,
found
;
List
<
Item
>
*
fields
,
*
values
;
List
<
Item
>
*
fields
,
*
values
;
...
...
sql/sql_error.cc
View file @
aee0d02a
...
@@ -80,14 +80,19 @@ void mysql_reset_errors(THD *thd)
...
@@ -80,14 +80,19 @@ void mysql_reset_errors(THD *thd)
level Severity of warning (note, warning, error ...)
level Severity of warning (note, warning, error ...)
code Error number
code Error number
msg Clear error message
msg Clear error message
RETURN
pointer on MYSQL_ERROR object
*/
*/
void
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
const
char
*
msg
)
uint
code
,
const
char
*
msg
)
{
{
if
(
thd
->
query_id
!=
thd
->
warn_id
)
if
(
thd
->
query_id
!=
thd
->
warn_id
)
mysql_reset_errors
(
thd
);
mysql_reset_errors
(
thd
);
MYSQL_ERROR
*
err
=
NULL
;
if
(
thd
->
warn_list
.
elements
<
thd
->
variables
.
max_error_count
)
if
(
thd
->
warn_list
.
elements
<
thd
->
variables
.
max_error_count
)
{
{
/*
/*
...
@@ -96,13 +101,14 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
...
@@ -96,13 +101,14 @@ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
*/
*/
MEM_ROOT
*
old_root
=
my_pthread_getspecific_ptr
(
MEM_ROOT
*
,
THR_MALLOC
);
MEM_ROOT
*
old_root
=
my_pthread_getspecific_ptr
(
MEM_ROOT
*
,
THR_MALLOC
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
thd
->
warn_root
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
thd
->
warn_root
);
MYSQL_ERROR
*
err
=
new
MYSQL_ERROR
(
code
,
level
,
msg
);
err
=
new
MYSQL_ERROR
(
code
,
level
,
msg
);
if
(
err
)
if
(
err
)
thd
->
warn_list
.
push_back
(
err
);
thd
->
warn_list
.
push_back
(
err
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_root
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_root
);
}
}
thd
->
warn_count
[(
uint
)
level
]
++
;
thd
->
warn_count
[(
uint
)
level
]
++
;
thd
->
total_warn_count
++
;
thd
->
total_warn_count
++
;
return
err
;
}
}
/*
/*
...
...
sql/sql_lex.h
View file @
aee0d02a
...
@@ -478,6 +478,7 @@ typedef struct st_lex
...
@@ -478,6 +478,7 @@ typedef struct st_lex
uint
slave_thd_opt
;
uint
slave_thd_opt
;
CHARSET_INFO
*
charset
;
CHARSET_INFO
*
charset
;
char
*
help_arg
;
char
*
help_arg
;
SQL_LIST
*
gorder_list
;
inline
void
uncacheable
()
inline
void
uncacheable
()
{
{
...
...
sql/sql_yacc.yy
View file @
aee0d02a
...
@@ -336,6 +336,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -336,6 +336,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ROW_SYM
%token ROW_SYM
%token RTREE_SYM
%token RTREE_SYM
%token SET
%token SET
%token SEPARATOR_SYM
%token SERIAL_SYM
%token SERIAL_SYM
%token SERIALIZABLE_SYM
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SESSION_SYM
...
@@ -462,6 +463,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -462,6 +463,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token GEOMFROMTEXT
%token GEOMFROMTEXT
%token GEOMFROMWKB
%token GEOMFROMWKB
%token GEOMETRYCOLLECTION
%token GEOMETRYCOLLECTION
%token GROUP_CONCAT_SYM
%token GROUP_UNIQUE_USERS
%token GROUP_UNIQUE_USERS
%token HOUR_MINUTE_SYM
%token HOUR_MINUTE_SYM
%token HOUR_SECOND_SYM
%token HOUR_SECOND_SYM
...
@@ -575,13 +577,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -575,13 +577,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
opt_escape
opt_escape
%type <string>
%type <string>
text_string
text_string
opt_gconcat_separator
%type <num>
%type <num>
type int_type real_type order_dir opt_field_spec lock_option
type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_var_type opt_var_ident_type
table_option opt_if_not_exists opt_var_type opt_var_ident_type
delete_option opt_temporary all_or_any
delete_option opt_temporary all_or_any
opt_distinct
%type <ulong_num>
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
ULONG_NUM raid_types merge_insert_types
...
@@ -2554,7 +2556,35 @@ sum_expr:
...
@@ -2554,7 +2556,35 @@ sum_expr:
| VARIANCE_SYM '(' in_sum_expr ')'
| VARIANCE_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_variance($3); }
{ $$=new Item_sum_variance($3); }
| SUM_SYM '(' in_sum_expr ')'
| SUM_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_sum($3); };
{ $$=new Item_sum_sum($3); }
| GROUP_CONCAT_SYM '(' opt_distinct expr_list opt_gorder_clause opt_gconcat_separator ')'
{
$$=new Item_func_group_concat($3,$4,Lex->gorder_list,$6);
$4->empty();
};
opt_distinct:
/* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; };
opt_gconcat_separator:
/* empty */ { $$ = new String(" ",1,default_charset_info); }
|SEPARATOR_SYM text_string { $$ = $2; };
opt_gorder_clause:
/* empty */
{
LEX *lex=Lex;
lex->gorder_list = NULL;
}
| order_clause
{
LEX *lex=Lex;
lex->gorder_list= (SQL_LIST*) sql_memdup((char*) &lex->current_select->order_list,sizeof(st_sql_list));
lex->current_select->order_list.empty();
};
in_sum_expr:
in_sum_expr:
opt_all
opt_all
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment