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
0255803b
Commit
0255803b
authored
Jul 26, 2005
by
bar@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/usr/home/bar/mysql-4.1.b10201
into mysql.com:/usr/home/bar/mysql-5.0
parents
9f2624ee
31b1bdc5
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
234 additions
and
171 deletions
+234
-171
include/config-netware.h
include/config-netware.h
+1
-0
libmysql/libmysql.def
libmysql/libmysql.def
+1
-0
mysql-test/r/func_gconcat.result
mysql-test/r/func_gconcat.result
+24
-0
mysql-test/t/func_gconcat.test
mysql-test/t/func_gconcat.test
+18
-0
sql/item.cc
sql/item.cc
+164
-0
sql/item.h
sql/item.h
+9
-0
sql/item_func.cc
sql/item_func.cc
+0
-168
sql/item_func.h
sql/item_func.h
+13
-3
sql/item_sum.cc
sql/item_sum.cc
+4
-0
No files found.
include/config-netware.h
View file @
0255803b
...
...
@@ -46,6 +46,7 @@ extern "C" {
#undef HAVE_SYS_MMAN_H
#undef HAVE_SYNCH_H
#undef HAVE_MMAP
#undef HAVE_RINT
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
#define HAVE_PTHREAD_SIGMASK 1
...
...
libmysql/libmysql.def
View file @
0255803b
...
...
@@ -148,6 +148,7 @@ EXPORTS
mysql_embedded
mysql_server_init
mysql_server_end
get_defaults_files
mysql_set_character_set
mysql_get_character_set_info
get_defaults_options
...
...
mysql-test/r/func_gconcat.result
View file @
0255803b
...
...
@@ -445,6 +445,30 @@ group_concat(distinct b order by b)
Warnings:
Warning 1260 2 line(s) were cut by GROUP_CONCAT()
drop table t1;
create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci,
b varchar(255) character set koi8r);
insert into t1 values ('xxx','yyy');
select collation(a) from t1;
collation(a)
cp1250_general_ci
select collation(group_concat(a)) from t1;
collation(group_concat(a))
cp1250_general_ci
create table t2 select group_concat(a) as a from t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` longtext character set cp1250
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select collation(group_concat(a,_koi8r'test')) from t1;
collation(group_concat(a,_koi8r'test'))
cp1250_general_ci
select collation(group_concat(a,_koi8r 0xC1C2)) from t1;
ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation 'group_concat'
select collation(group_concat(a,b)) from t1;
ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,IMPLICIT) for operation 'group_concat'
drop table t1;
drop table t2;
CREATE TABLE t1 (id int);
SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL;
gc
...
...
mysql-test/t/func_gconcat.test
View file @
0255803b
...
...
@@ -263,6 +263,24 @@ select group_concat(distinct b order by b) from t1 group by a;
drop
table
t1
;
#
# Bug#10201
#
create
table
t1
(
a
varchar
(
255
)
character
set
cp1250
collate
cp1250_general_ci
,
b
varchar
(
255
)
character
set
koi8r
);
insert
into
t1
values
(
'xxx'
,
'yyy'
);
select
collation
(
a
)
from
t1
;
select
collation
(
group_concat
(
a
))
from
t1
;
create
table
t2
select
group_concat
(
a
)
as
a
from
t1
;
show
create
table
t2
;
select
collation
(
group_concat
(
a
,
_koi8r
'test'
))
from
t1
;
--
error
1267
select
collation
(
group_concat
(
a
,
_koi8r
0xC1C2
))
from
t1
;
--
error
1267
select
collation
(
group_concat
(
a
,
b
))
from
t1
;
drop
table
t1
;
drop
table
t2
;
#
# bug #7769: group_concat returning null is checked in having
#
...
...
sql/item.cc
View file @
0255803b
...
...
@@ -1082,6 +1082,170 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
return
0
;
}
/******************************/
static
void
my_coll_agg_error
(
DTCollation
&
c1
,
DTCollation
&
c2
,
const
char
*
fname
)
{
my_error
(
ER_CANT_AGGREGATE_2COLLATIONS
,
MYF
(
0
),
c1
.
collation
->
name
,
c1
.
derivation_name
(),
c2
.
collation
->
name
,
c2
.
derivation_name
(),
fname
);
}
static
void
my_coll_agg_error
(
DTCollation
&
c1
,
DTCollation
&
c2
,
DTCollation
&
c3
,
const
char
*
fname
)
{
my_error
(
ER_CANT_AGGREGATE_3COLLATIONS
,
MYF
(
0
),
c1
.
collation
->
name
,
c1
.
derivation_name
(),
c2
.
collation
->
name
,
c2
.
derivation_name
(),
c3
.
collation
->
name
,
c3
.
derivation_name
(),
fname
);
}
static
void
my_coll_agg_error
(
Item
**
args
,
uint
count
,
const
char
*
fname
)
{
if
(
count
==
2
)
my_coll_agg_error
(
args
[
0
]
->
collation
,
args
[
1
]
->
collation
,
fname
);
else
if
(
count
==
3
)
my_coll_agg_error
(
args
[
0
]
->
collation
,
args
[
1
]
->
collation
,
args
[
2
]
->
collation
,
fname
);
else
my_error
(
ER_CANT_AGGREGATE_NCOLLATIONS
,
MYF
(
0
),
fname
);
}
bool
agg_item_collations
(
DTCollation
&
c
,
const
char
*
fname
,
Item
**
av
,
uint
count
,
uint
flags
)
{
uint
i
;
c
.
set
(
av
[
0
]
->
collation
);
for
(
i
=
1
;
i
<
count
;
i
++
)
{
if
(
c
.
aggregate
(
av
[
i
]
->
collation
,
flags
))
{
my_coll_agg_error
(
av
,
count
,
fname
);
return
TRUE
;
}
}
if
((
flags
&
MY_COLL_DISALLOW_NONE
)
&&
c
.
derivation
==
DERIVATION_NONE
)
{
my_coll_agg_error
(
av
,
count
,
fname
);
return
TRUE
;
}
return
FALSE
;
}
bool
agg_item_collations_for_comparison
(
DTCollation
&
c
,
const
char
*
fname
,
Item
**
av
,
uint
count
,
uint
flags
)
{
return
(
agg_item_collations
(
c
,
fname
,
av
,
count
,
flags
|
MY_COLL_DISALLOW_NONE
));
}
/*
Collect arguments' character sets together.
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
*/
bool
agg_item_charsets
(
DTCollation
&
coll
,
const
char
*
fname
,
Item
**
args
,
uint
nargs
,
uint
flags
)
{
Item
**
arg
,
**
last
,
*
safe_args
[
2
];
if
(
agg_item_collations
(
coll
,
fname
,
args
,
nargs
,
flags
))
return
TRUE
;
/*
For better error reporting: save the first and the second argument.
We need this only if the the number of args is 3 or 2:
- for a longer argument list, "Illegal mix of collations"
doesn't display each argument's characteristics.
- if nargs is 1, then this error cannot happen.
*/
if
(
nargs
>=
2
&&
nargs
<=
3
)
{
safe_args
[
0
]
=
args
[
0
];
safe_args
[
1
]
=
args
[
1
];
}
THD
*
thd
=
current_thd
;
Item_arena
*
arena
,
backup
;
bool
res
=
FALSE
;
/*
In case we're in statement prepare, create conversion item
in its memory: it will be reused on each execute.
*/
arena
=
thd
->
change_arena_if_needed
(
&
backup
);
for
(
arg
=
args
,
last
=
args
+
nargs
;
arg
<
last
;
arg
++
)
{
Item
*
conv
;
uint32
dummy_offset
;
if
(
!
String
::
needs_conversion
(
0
,
coll
.
collation
,
(
*
arg
)
->
collation
.
collation
,
&
dummy_offset
))
continue
;
if
(
!
(
conv
=
(
*
arg
)
->
safe_charset_converter
(
coll
.
collation
)))
{
if
(
nargs
>=
2
&&
nargs
<=
3
)
{
/* restore the original arguments for better error message */
args
[
0
]
=
safe_args
[
0
];
args
[
1
]
=
safe_args
[
1
];
}
my_coll_agg_error
(
args
,
nargs
,
fname
);
res
=
TRUE
;
break
;
// we cannot return here, we need to restore "arena".
}
conv
->
fix_fields
(
thd
,
0
,
&
conv
);
/*
If in statement prepare, then we create a converter for two
constant items, do it once and then reuse it.
If we're in execution of a prepared statement, arena is NULL,
and the conv was created in runtime memory. This can be
the case only if the argument is a parameter marker ('?'),
because for all true constants the charset converter has already
been created in prepare. In this case register the change for
rollback.
*/
if
(
arena
)
*
arg
=
conv
;
else
thd
->
change_item_tree
(
arg
,
conv
);
}
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
res
;
}
/**********************************************/
Item_field
::
Item_field
(
Field
*
f
)
:
Item_ident
(
0
,
NullS
,
*
f
->
table_name
,
f
->
field_name
),
item_equal
(
0
),
no_const_subst
(
0
),
...
...
sql/item.h
View file @
0255803b
...
...
@@ -767,6 +767,15 @@ public:
};
bool
agg_item_collations
(
DTCollation
&
c
,
const
char
*
name
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
bool
agg_item_collations_for_comparison
(
DTCollation
&
c
,
const
char
*
name
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
bool
agg_item_charsets
(
DTCollation
&
c
,
const
char
*
name
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
class
Item_num
:
public
Item
{
public:
...
...
sql/item_func.cc
View file @
0255803b
...
...
@@ -42,73 +42,6 @@ bool check_reserved_words(LEX_STRING *name)
}
static
void
my_coll_agg_error
(
DTCollation
&
c1
,
DTCollation
&
c2
,
const
char
*
fname
)
{
my_error
(
ER_CANT_AGGREGATE_2COLLATIONS
,
MYF
(
0
),
c1
.
collation
->
name
,
c1
.
derivation_name
(),
c2
.
collation
->
name
,
c2
.
derivation_name
(),
fname
);
}
static
void
my_coll_agg_error
(
DTCollation
&
c1
,
DTCollation
&
c2
,
DTCollation
&
c3
,
const
char
*
fname
)
{
my_error
(
ER_CANT_AGGREGATE_3COLLATIONS
,
MYF
(
0
),
c1
.
collation
->
name
,
c1
.
derivation_name
(),
c2
.
collation
->
name
,
c2
.
derivation_name
(),
c3
.
collation
->
name
,
c3
.
derivation_name
(),
fname
);
}
static
void
my_coll_agg_error
(
Item
**
args
,
uint
count
,
const
char
*
fname
)
{
if
(
count
==
2
)
my_coll_agg_error
(
args
[
0
]
->
collation
,
args
[
1
]
->
collation
,
fname
);
else
if
(
count
==
3
)
my_coll_agg_error
(
args
[
0
]
->
collation
,
args
[
1
]
->
collation
,
args
[
2
]
->
collation
,
fname
);
else
my_error
(
ER_CANT_AGGREGATE_NCOLLATIONS
,
MYF
(
0
),
fname
);
}
bool
Item_func
::
agg_arg_collations
(
DTCollation
&
c
,
Item
**
av
,
uint
count
,
uint
flags
)
{
uint
i
;
c
.
set
(
av
[
0
]
->
collation
);
for
(
i
=
1
;
i
<
count
;
i
++
)
{
if
(
c
.
aggregate
(
av
[
i
]
->
collation
,
flags
))
{
my_coll_agg_error
(
av
,
count
,
func_name
());
return
TRUE
;
}
}
if
((
flags
&
MY_COLL_DISALLOW_NONE
)
&&
c
.
derivation
==
DERIVATION_NONE
)
{
my_coll_agg_error
(
av
,
count
,
func_name
());
return
TRUE
;
}
return
FALSE
;
}
bool
Item_func
::
agg_arg_collations_for_comparison
(
DTCollation
&
c
,
Item
**
av
,
uint
count
,
uint
flags
)
{
return
(
agg_arg_collations
(
c
,
av
,
count
,
flags
|
MY_COLL_DISALLOW_NONE
));
}
/* return TRUE if item is a constant */
bool
...
...
@@ -118,107 +51,6 @@ eval_const_cond(COND *cond)
}
/*
Collect arguments' character sets together.
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
*/
bool
Item_func
::
agg_arg_charsets
(
DTCollation
&
coll
,
Item
**
args
,
uint
nargs
,
uint
flags
)
{
Item
**
arg
,
**
last
,
*
safe_args
[
2
];
if
(
agg_arg_collations
(
coll
,
args
,
nargs
,
flags
))
return
TRUE
;
/*
For better error reporting: save the first and the second argument.
We need this only if the the number of args is 3 or 2:
- for a longer argument list, "Illegal mix of collations"
doesn't display each argument's characteristics.
- if nargs is 1, then this error cannot happen.
*/
if
(
nargs
>=
2
&&
nargs
<=
3
)
{
safe_args
[
0
]
=
args
[
0
];
safe_args
[
1
]
=
args
[
1
];
}
THD
*
thd
=
current_thd
;
Query_arena
*
arena
,
backup
;
bool
res
=
FALSE
;
/*
In case we're in statement prepare, create conversion item
in its memory: it will be reused on each execute.
*/
arena
=
thd
->
change_arena_if_needed
(
&
backup
);
for
(
arg
=
args
,
last
=
args
+
nargs
;
arg
<
last
;
arg
++
)
{
Item
*
conv
;
uint32
dummy_offset
;
if
(
!
String
::
needs_conversion
(
0
,
coll
.
collation
,
(
*
arg
)
->
collation
.
collation
,
&
dummy_offset
))
continue
;
if
(
!
(
conv
=
(
*
arg
)
->
safe_charset_converter
(
coll
.
collation
)))
{
if
(
nargs
>=
2
&&
nargs
<=
3
)
{
/* restore the original arguments for better error message */
args
[
0
]
=
safe_args
[
0
];
args
[
1
]
=
safe_args
[
1
];
}
my_coll_agg_error
(
args
,
nargs
,
func_name
());
res
=
TRUE
;
break
;
// we cannot return here, we need to restore "arena".
}
if
((
*
arg
)
->
type
()
==
FIELD_ITEM
)
((
Item_field
*
)(
*
arg
))
->
no_const_subst
=
1
;
/*
If in statement prepare, then we create a converter for two
constant items, do it once and then reuse it.
If we're in execution of a prepared statement, arena is NULL,
and the conv was created in runtime memory. This can be
the case only if the argument is a parameter marker ('?'),
because for all true constants the charset converter has already
been created in prepare. In this case register the change for
rollback.
*/
if
(
arena
)
*
arg
=
conv
;
else
thd
->
change_item_tree
(
arg
,
conv
);
/*
We do not check conv->fixed, because Item_func_conv_charset which can
be return by safe_charset_converter can't be fixed at creation
*/
conv
->
fix_fields
(
thd
,
arg
);
}
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
res
;
}
void
Item_func
::
set_arguments
(
List
<
Item
>
&
list
)
{
allowed_arg_cols
=
1
;
...
...
sql/item_func.h
View file @
0255803b
...
...
@@ -166,12 +166,22 @@ public:
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
agg_arg_collations
(
DTCollation
&
c
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
uint
flags
=
0
)
{
return
agg_item_collations
(
c
,
func_name
(),
items
,
nitems
,
flags
);
}
bool
agg_arg_collations_for_comparison
(
DTCollation
&
c
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
uint
flags
=
0
)
{
return
agg_item_collations_for_comparison
(
c
,
func_name
(),
items
,
nitems
,
flags
);
}
bool
agg_arg_charsets
(
DTCollation
&
c
,
Item
**
items
,
uint
nitems
,
uint
flags
=
0
);
uint
flags
=
0
)
{
return
agg_item_charsets
(
c
,
func_name
(),
items
,
nitems
,
flags
);
}
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
Item
*
transform
(
Item_transformer
transformer
,
byte
*
arg
);
void
traverse_cond
(
Cond_traverser
traverser
,
...
...
sql/item_sum.cc
View file @
0255803b
...
...
@@ -2976,6 +2976,10 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
maybe_null
|=
args
[
i
]
->
maybe_null
;
}
if
(
agg_item_charsets
(
collation
,
func_name
(),
args
,
arg_count
,
MY_COLL_ALLOW_CONV
))
return
1
;
result_field
=
0
;
null_value
=
1
;
thd
->
allow_sum_func
=
1
;
...
...
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