1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-12 20:49:12 +03:00

MDEV-31531 Remove my_casedn_str() and my_caseup_str()

Under terms of MDEV 27490 we'll add support for non-BMP identifiers
and upgrade casefolding information to Unicode version 14.0.0.
In Unicode-14.0.0 conversion to lower and upper cases can increase octet length
of the string, so conversion won't be possible in-place any more.

This patch removes virtual functions performing in-place casefolding:
  - my_charset_handler_st::casedn_str()
  - my_charset_handler_st::caseup_str()
and fixes the code to use the non-inplace functions instead:
  - my_charset_handler_st::casedn()
  - my_charset_handler_st::caseup()
This commit is contained in:
Alexander Barkov
2023-06-23 13:24:02 +04:00
parent de9c357284
commit 929c2e06aa
103 changed files with 1282 additions and 1248 deletions

View File

@@ -630,10 +630,6 @@ struct my_charset_handler_st
int (*ctype)(CHARSET_INFO *cs, int *ctype, int (*ctype)(CHARSET_INFO *cs, int *ctype,
const uchar *s, const uchar *e); const uchar *s, const uchar *e);
/* Functions for case and sort conversion */
size_t (*caseup_str)(CHARSET_INFO *, char *);
size_t (*casedn_str)(CHARSET_INFO *, char *);
my_charset_conv_case caseup; my_charset_conv_case caseup;
my_charset_conv_case casedn; my_charset_conv_case casedn;
@@ -849,6 +845,39 @@ struct charset_info_st
return (cset->casedn)(this, src, srclen, dst, dstlen); return (cset->casedn)(this, src, srclen, dst, dstlen);
} }
size_t opt_casedn(const char *src, size_t srclen,
char *dst, size_t dstlen, my_bool opt_casedn) const
{
if (opt_casedn)
return casedn(src, srclen, dst, dstlen);
if (srclen > dstlen)
srclen= dstlen;
memcpy(dst, src, srclen);
return srclen;
}
/* Convert to a lower-cased 0-terminated string */
size_t casedn_z(const char *src, size_t srclen,
char *dst, size_t dstlen) const
{
DBUG_ASSERT(dstlen);
DBUG_ASSERT(src != dst);
size_t len= casedn(src, srclen, dst, dstlen - 1);
dst[len]= '\0';
return len;
}
/* Convert to a upper-cased 0-terminated string */
size_t caseup_z(const char *src, size_t srclen,
char *dst, size_t dstlen) const
{
DBUG_ASSERT(dstlen);
DBUG_ASSERT(src != dst);
size_t len= caseup(src, srclen, dst, dstlen - 1);
dst[len]= '\0';
return len;
}
uint caseup_multiply() const uint caseup_multiply() const
{ {
return (cset->caseup_multiply)(this); return (cset->caseup_multiply)(this);
@@ -1513,6 +1542,14 @@ size_t my_copy_fix_mb(CHARSET_INFO *cs,
/* Functions for 8bit */ /* Functions for 8bit */
extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *); extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *);
extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *); extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *);
static inline size_t my_caseup_str_latin1(char *str)
{
return my_caseup_str_8bit(&my_charset_latin1, str);
}
static inline size_t my_casedn_str_latin1(char *str)
{
return my_casedn_str_8bit(&my_charset_latin1, str);
}
extern size_t my_caseup_8bit(CHARSET_INFO *, extern size_t my_caseup_8bit(CHARSET_INFO *,
const char *src, size_t srclen, const char *src, size_t srclen,
char *dst, size_t dstlen); char *dst, size_t dstlen);
@@ -1609,8 +1646,6 @@ int my_charlen_8bit(CHARSET_INFO *, const uchar *str, const uchar *end);
/* Functions for multibyte charsets */ /* Functions for multibyte charsets */
extern size_t my_caseup_str_mb(CHARSET_INFO *, char *);
extern size_t my_casedn_str_mb(CHARSET_INFO *, char *);
extern size_t my_caseup_mb(CHARSET_INFO *, extern size_t my_caseup_mb(CHARSET_INFO *,
const char *src, size_t srclen, const char *src, size_t srclen,
char *dst, size_t dstlen); char *dst, size_t dstlen);
@@ -1857,9 +1892,6 @@ my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e,
} }
#define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a)))
#define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a)))
/* XXX: still need to take care of this one */ /* XXX: still need to take care of this one */
#ifdef MY_CHARSET_TIS620 #ifdef MY_CHARSET_TIS620
#error The TIS620 charset is broken at the moment. Tell tim to fix it. #error The TIS620 charset is broken at the moment. Tell tim to fix it.

View File

@@ -1584,7 +1584,7 @@ ORDER BY l DESC;
id l id l
a 512 a 512
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
SET STATEMENT group_concat_max_len=1024 FOR SET STATEMENT group_concat_max_len=1024 FOR
SELECT id, CHAR_LENGTH(GROUP_CONCAT(body)) AS l SELECT id, CHAR_LENGTH(GROUP_CONCAT(body)) AS l
FROM (SELECT 'a' AS id, REPEAT('foo bar', 100) AS body FROM (SELECT 'a' AS id, REPEAT('foo bar', 100) AS body
@@ -1593,7 +1593,7 @@ SELECT 'a' AS id, REPEAT('bla bla', 100) AS body) t1;
id l id l
a 512 a 512
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
# #
# MDEV-6865 Merge Bug#18935421 RPAD DIES WITH CERTAIN PADSTR INTPUTS.. # MDEV-6865 Merge Bug#18935421 RPAD DIES WITH CERTAIN PADSTR INTPUTS..
# #

View File

@@ -1638,7 +1638,7 @@ ORDER BY l DESC;
id l id l
a 256 a 256
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
# #
# incorrect charset for val_str_ascii # incorrect charset for val_str_ascii
# #

View File

@@ -108,3 +108,12 @@ ALTER TABLE tfk ADD CONSTRAINT sid UNIQUE(c2);
ERROR 42000: Duplicate key name 'sid' ERROR 42000: Duplicate key name 'sid'
DROP TABLE tfk; DROP TABLE tfk;
DROP TABLE tpk; DROP TABLE tpk;
#
# MDEV-33223 Assertion `dst_size > 4' failed in size_t Identifier_chain2::make_sep_name_opt_casedn(char*, size_t, int, bool) const
#
CREATE DATABASE x;
USE x;
CREATE TABLE t (i INT, j INT, CONSTRAINT fk2 FOREIGN KEY(i) REFERENCES p (i)) ENGINE=InnoDB;
ERROR HY000: Can't create table `x`.`t` (errno: 150 "Foreign key constraint is incorrectly formed")
DROP DATABASE x;
USE test;

View File

@@ -142,3 +142,13 @@ DROP TABLE tfk;
DROP TABLE tpk; DROP TABLE tpk;
--echo #
--echo # MDEV-33223 Assertion `dst_size > 4' failed in size_t Identifier_chain2::make_sep_name_opt_casedn(char*, size_t, int, bool) const
--echo #
CREATE DATABASE x;
USE x;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t (i INT, j INT, CONSTRAINT fk2 FOREIGN KEY(i) REFERENCES p (i)) ENGINE=InnoDB;
DROP DATABASE x;
USE test;

View File

@@ -152,10 +152,10 @@ grp group_concat(c)
4 4
5 NULL 5 NULL
Warnings: Warnings:
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
show warnings; show warnings;
Level Code Message Level Code Message
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
set group_concat_max_len = 1024; set group_concat_max_len = 1024;
select group_concat(sum(c)) from t1 group by grp; select group_concat(sum(c)) from t1 group by grp;
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
@@ -379,29 +379,29 @@ group_concat(b)
bb,c bb,c
BB,C BB,C
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
select group_concat(distinct b) from t1 group by a; select group_concat(distinct b) from t1 group by a;
group_concat(distinct b) group_concat(distinct b)
a,bb a,bb
A,BB A,BB
Warnings: Warnings:
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
Warning 1260 Row 6 was cut by GROUP_CONCAT() Warning 1260 Row 6 was cut by group_concat()
select group_concat(b order by b) from t1 group by a; select group_concat(b order by b) from t1 group by a;
group_concat(b order by b) group_concat(b order by b)
a,bb a,bb
A,BB A,BB
Warnings: Warnings:
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
Warning 1260 Row 6 was cut by GROUP_CONCAT() Warning 1260 Row 6 was cut by group_concat()
select group_concat(distinct b order by b) from t1 group by a; select group_concat(distinct b order by b) from t1 group by a;
group_concat(distinct b order by b) group_concat(distinct b order by b)
a,bb a,bb
A,BB A,BB
Warnings: Warnings:
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
Warning 1260 Row 6 was cut by GROUP_CONCAT() Warning 1260 Row 6 was cut by group_concat()
insert into t1 values (1, concat(repeat('1', 300), '2')), insert into t1 values (1, concat(repeat('1', 300), '2')),
(1, concat(repeat('1', 300), '2')), (1, concat(repeat('0', 300), '1')), (1, concat(repeat('1', 300), '2')), (1, concat(repeat('0', 300), '1')),
(2, concat(repeat('1', 300), '2')), (2, concat(repeat('1', 300), '2')), (2, concat(repeat('1', 300), '2')), (2, concat(repeat('1', 300), '2')),
@@ -429,29 +429,29 @@ group_concat(b)
bb,ccc,a,bb,ccc,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111 bb,ccc,a,bb,ccc,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111
BB,CCC,A,BB,CCC,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111 BB,CCC,A,BB,CCC,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111
Warnings: Warnings:
Warning 1260 Row 7 was cut by GROUP_CONCAT() Warning 1260 Row 7 was cut by group_concat()
Warning 1260 Row 14 was cut by GROUP_CONCAT() Warning 1260 Row 14 was cut by group_concat()
select group_concat(distinct b) from t1 group by a; select group_concat(distinct b) from t1 group by a;
group_concat(distinct b) group_concat(distinct b)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
select group_concat(b order by b) from t1 group by a; select group_concat(b order by b) from t1 group by a;
group_concat(b order by b) group_concat(b order by b)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
select group_concat(distinct b order by b) from t1 group by a; select group_concat(distinct b order by b) from t1 group by a;
group_concat(distinct b order by b) group_concat(distinct b order by b)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
drop table t1; drop table t1;
create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci, create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci,
b varchar(255) character set koi8r); b varchar(255) character set koi8r);
@@ -758,22 +758,22 @@ SELECT GROUP_CONCAT( a ) FROM t1;
GROUP_CONCAT( a ) GROUP_CONCAT( a )
aaaaaaaaaa,bbbbbbbbb aaaaaaaaaa,bbbbbbbbb
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
SELECT GROUP_CONCAT( DISTINCT a ) FROM t1; SELECT GROUP_CONCAT( DISTINCT a ) FROM t1;
GROUP_CONCAT( DISTINCT a ) GROUP_CONCAT( DISTINCT a )
aaaaaaaaaa,bbbbbbbbb aaaaaaaaaa,bbbbbbbbb
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1; SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
GROUP_CONCAT( a ORDER BY b ) GROUP_CONCAT( a ORDER BY b )
aaaaaaaaaa,bbbbbbbbb aaaaaaaaaa,bbbbbbbbb
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1; SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1;
GROUP_CONCAT( DISTINCT a ORDER BY b ) GROUP_CONCAT( DISTINCT a ORDER BY b )
aaaaaaaaaa,bbbbbbbbb aaaaaaaaaa,bbbbbbbbb
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
SET group_concat_max_len = DEFAULT; SET group_concat_max_len = DEFAULT;
DROP TABLE t1; DROP TABLE t1;
SET group_concat_max_len= 65535; SET group_concat_max_len= 65535;
@@ -1073,15 +1073,15 @@ GROUP_CONCAT(a) b
22222 2 22222 2
33333 3 33333 3
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b;
ERROR HY000: Row 1 was cut by GROUP_CONCAT() ERROR HY000: Row 1 was cut by group_concat()
UPDATE t1 SET a = '11111' WHERE b = 1; UPDATE t1 SET a = '11111' WHERE b = 1;
UPDATE t1 SET a = '22222' WHERE b = 2; UPDATE t1 SET a = '22222' WHERE b = 2;
INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b;
ERROR HY000: Row 3 was cut by GROUP_CONCAT() ERROR HY000: Row 3 was cut by group_concat()
SET group_concat_max_len = DEFAULT; SET group_concat_max_len = DEFAULT;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
DROP TABLE t1, t2; DROP TABLE t1, t2;
@@ -1168,22 +1168,22 @@ SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1;
LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) LENGTH(GROUP_CONCAT(f1 ORDER BY f2))
1024 1024
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
SET group_concat_max_len= 499999; SET group_concat_max_len= 499999;
SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 WHERE f2 = 0; SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 WHERE f2 = 0;
LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) LENGTH(GROUP_CONCAT(f1 ORDER BY f2))
499999 499999
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 GROUP BY f2; SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 GROUP BY f2;
LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) LENGTH(GROUP_CONCAT(f1 ORDER BY f2))
499999 499999
499999 499999
499999 499999
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
INSERT INTO t1 VALUES (REPEAT('a', 499999), 3), (REPEAT('b', 500000), 4); INSERT INTO t1 VALUES (REPEAT('a', 499999), 3), (REPEAT('b', 500000), 4);
SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 GROUP BY f2; SELECT LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) FROM t1 GROUP BY f2;
LENGTH(GROUP_CONCAT(f1 ORDER BY f2)) LENGTH(GROUP_CONCAT(f1 ORDER BY f2))
@@ -1193,10 +1193,10 @@ LENGTH(GROUP_CONCAT(f1 ORDER BY f2))
499999 499999
499999 499999
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
Warning 1260 Row 5 was cut by GROUP_CONCAT() Warning 1260 Row 5 was cut by group_concat()
DROP TABLE t1; DROP TABLE t1;
SET group_concat_max_len= DEFAULT; SET group_concat_max_len= DEFAULT;
set session group_concat_max_len=1024; set session group_concat_max_len=1024;
@@ -1206,7 +1206,7 @@ FROM seq_1_to_200000;
c c
0.90910.90910.90910.90910.90910.90910.90910.9091,1.81821.81821.81821.81821.81821.81821.81821.8182,10.000010.000010.000010.000010.000010.000010.000010.0000,10.909110.909110.909110.909110.909110.909110.909110.9091,100.0000100.0000100.0000100.0000100.0000100.0000100.0000100.0000,100.9091100.9091100.9091100.9091100.9091100.9091100.9091100.9091,1000.00001000.00001000.00001000.00001000.00001000.00001000.00001000.0000,1000.90911000.90911000.90911000.90911000.90911000.90911000.90911000.9091,10000.000010000.000010000.000010000.000010000.000010000.000010000.000010000.0000,10000.909110000.909110000.909110000.909110000.909110000.909110000.909110000.9091,100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000,100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091,100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182,100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273,100003.6364100003. 0.90910.90910.90910.90910.90910.90910.90910.9091,1.81821.81821.81821.81821.81821.81821.81821.8182,10.000010.000010.000010.000010.000010.000010.000010.0000,10.909110.909110.909110.909110.909110.909110.909110.9091,100.0000100.0000100.0000100.0000100.0000100.0000100.0000100.0000,100.9091100.9091100.9091100.9091100.9091100.9091100.9091100.9091,1000.00001000.00001000.00001000.00001000.00001000.00001000.00001000.0000,1000.90911000.90911000.90911000.90911000.90911000.90911000.90911000.9091,10000.000010000.000010000.000010000.000010000.000010000.000010000.000010000.0000,10000.909110000.909110000.909110000.909110000.909110000.909110000.909110000.9091,100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000100000.0000,100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091100000.9091,100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182100001.8182,100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273100002.7273,100003.6364100003.
Warnings: Warnings:
Warning 1260 Row 15 was cut by GROUP_CONCAT() Warning 1260 Row 15 was cut by group_concat()
set max_session_mem_used=default; set max_session_mem_used=default;
set session group_concat_max_len=default; set session group_concat_max_len=default;
SET group_concat_max_len= 8; SET group_concat_max_len= 8;
@@ -1225,7 +1225,7 @@ GROUP BY f;
f gc f gc
2 2019-12- 2 2019-12-
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
SET group_concat_max_len= default; SET group_concat_max_len= default;
# #

View File

@@ -1599,7 +1599,7 @@ select json_arrayagg(a) from t1;
json_arrayagg(a) json_arrayagg(a)
["x64-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] ["x64-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
Warnings: Warnings:
Warning 1260 Row 1 was cut by JSON_ARRAYAGG() Warning 1260 Row 1 was cut by json_arrayagg()
drop table t1; drop table t1;
SET group_concat_max_len= default; SET group_concat_max_len= default;
create table t1 (col1 json); create table t1 (col1 json);

View File

@@ -944,29 +944,29 @@ group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a; select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a; select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
drop table t1, t2; drop table t1, t2;
set group_concat_max_len=default; set group_concat_max_len=default;
create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y)); create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y));

View File

@@ -951,29 +951,29 @@ group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a; select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a; select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a;
group_concat(t1.b,t2.c) group_concat(t1.b,t2.c)
aaaaa aaaaa
bbbbb bbbbb
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
drop table t1, t2; drop table t1, t2;
set group_concat_max_len=default; set group_concat_max_len=default;
create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y)); create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y));

View File

@@ -864,7 +864,7 @@ select group_concat(a) FROM t1 group by b;
group_concat(a) group_concat(a)
1234567890 1234567890
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
set group_concat_max_len=1024; set group_concat_max_len=1024;
select group_concat(a) FROM t1 group by b; select group_concat(a) FROM t1 group by b;
group_concat(a) group_concat(a)

View File

@@ -795,9 +795,9 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2); where a1 in (select group_concat(b1) from t2_512 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_512 from t1_512
@@ -812,9 +812,9 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2); where a1 in (select group_concat(b1) from t2_512 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_512, t2_512, t3_512; drop table t1_512, t2_512, t3_512;
set @blob_len = 1024; set @blob_len = 1024;
set @suffix_len = @blob_len - @prefix_len; set @suffix_len = @blob_len - @prefix_len;
@@ -896,9 +896,9 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2); where a1 in (select group_concat(b1) from t2_1024 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_1024 from t1_1024
@@ -913,9 +913,9 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2); where a1 in (select group_concat(b1) from t2_1024 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_1024, t2_1024, t3_1024; drop table t1_1024, t2_1024, t3_1024;
set @blob_len = 1025; set @blob_len = 1025;
set @suffix_len = @blob_len - @prefix_len; set @suffix_len = @blob_len - @prefix_len;
@@ -997,9 +997,9 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2); where a1 in (select group_concat(b1) from t2_1025 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_1025 from t1_1025
@@ -1014,9 +1014,9 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2); where a1 in (select group_concat(b1) from t2_1025 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_1025, t2_1025, t3_1025; drop table t1_1025, t2_1025, t3_1025;
create table t1bit (a1 bit(3), a2 bit(3)); create table t1bit (a1 bit(3), a2 bit(3));
create table t2bit (b1 bit(3), b2 bit(3)); create table t2bit (b1 bit(3), b2 bit(3));

View File

@@ -813,9 +813,9 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2); where a1 in (select group_concat(b1) from t2_512 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_512 from t1_512
@@ -831,9 +831,9 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2); where a1 in (select group_concat(b1) from t2_512 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_512, t2_512, t3_512; drop table t1_512, t2_512, t3_512;
set @blob_len = 1024; set @blob_len = 1024;
set @suffix_len = @blob_len - @prefix_len; set @suffix_len = @blob_len - @prefix_len;
@@ -916,9 +916,9 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2); where a1 in (select group_concat(b1) from t2_1024 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_1024 from t1_1024
@@ -934,9 +934,9 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2); where a1 in (select group_concat(b1) from t2_1024 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_1024, t2_1024, t3_1024; drop table t1_1024, t2_1024, t3_1024;
set @blob_len = 1025; set @blob_len = 1025;
set @suffix_len = @blob_len - @prefix_len; set @suffix_len = @blob_len - @prefix_len;
@@ -1019,9 +1019,9 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2); where a1 in (select group_concat(b1) from t2_1025 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
set @@group_concat_max_len = 256; set @@group_concat_max_len = 256;
explain extended select left(a1,7), left(a2,7) explain extended select left(a1,7), left(a2,7)
from t1_1025 from t1_1025
@@ -1037,9 +1037,9 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2); where a1 in (select group_concat(b1) from t2_1025 group by b2);
left(a1,7) left(a2,7) left(a1,7) left(a2,7)
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
drop table t1_1025, t2_1025, t3_1025; drop table t1_1025, t2_1025, t3_1025;
create table t1bit (a1 bit(3), a2 bit(3)); create table t1bit (a1 bit(3), a2 bit(3));
create table t2bit (b1 bit(3), b2 bit(3)); create table t2bit (b1 bit(3), b2 bit(3));

View File

@@ -0,0 +1,22 @@
#
# MDEV-33020 The database part is not case sensitive in SP names in PERFORMANCE_SCHEMA
#
CREATE OR REPLACE DATABASE DB1;
CREATE OR REPLACE DATABASE db1;
CREATE PROCEDURE DB1.sp() SELECT 'This is DB1.sp';
CREATE PROCEDURE db1.sp() SELECT 'This is db1.sp';
CALL DB1.sp();
This is DB1.sp
This is DB1.sp
CREATE PROCEDURE DB1.sp2() SELECT 'This is DB1.sp2';
CALL db1.sp();
This is db1.sp
This is db1.sp
SELECT object_type, object_schema, object_name, count_star, count_statements, sum_rows_sent
FROM performance_schema.events_statements_summary_by_program
WHERE object_type='procedure' AND LOWER(object_schema)='db1';
object_type object_schema object_name count_star count_statements sum_rows_sent
PROCEDURE DB1 sp 1 1 1
PROCEDURE db1 sp 1 1 1
DROP DATABASE db1;
DROP DATABASE DB1;

View File

@@ -0,0 +1,27 @@
#
# Specific tests for case sensitive file systems
# i.e. lower_case_filesystem=OFF
#
--source include/have_case_sensitive_file_system.inc
--source include/have_perfschema.inc
--source include/not_embedded.inc
--echo #
--echo # MDEV-33020 The database part is not case sensitive in SP names in PERFORMANCE_SCHEMA
--echo #
CREATE OR REPLACE DATABASE DB1;
CREATE OR REPLACE DATABASE db1;
CREATE PROCEDURE DB1.sp() SELECT 'This is DB1.sp';
CREATE PROCEDURE db1.sp() SELECT 'This is db1.sp';
CALL DB1.sp();
# This is needed to reset the SP cache (a MDEV-33019 workaround)
CREATE PROCEDURE DB1.sp2() SELECT 'This is DB1.sp2';
CALL db1.sp();
SELECT object_type, object_schema, object_name, count_star, count_statements, sum_rows_sent
FROM performance_schema.events_statements_summary_by_program
WHERE object_type='procedure' AND LOWER(object_schema)='db1';
DROP DATABASE db1;
DROP DATABASE DB1;

View File

@@ -42,10 +42,10 @@ id rollno GROUP_CONCAT(name)
4 3 Reco 4 3 Reco
7 4 Reco 7 4 Reco
Warnings: Warnings:
Warning 1260 Row 1 was cut by GROUP_CONCAT() Warning 1260 Row 1 was cut by group_concat()
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
Warning 1260 Row 4 was cut by GROUP_CONCAT() Warning 1260 Row 4 was cut by group_concat()
## Changing session value of variable and verifying its behavior, ## ## Changing session value of variable and verifying its behavior, ##
## warning should come here ## ## warning should come here ##
SET @@session.group_concat_max_len = 10; SET @@session.group_concat_max_len = 10;
@@ -56,9 +56,9 @@ id rollno GROUP_CONCAT(name)
4 3 Record_4,R 4 3 Record_4,R
7 4 Record_7,R 7 4 Record_7,R
Warnings: Warnings:
Warning 1260 Row 2 was cut by GROUP_CONCAT() Warning 1260 Row 2 was cut by group_concat()
Warning 1260 Row 5 was cut by GROUP_CONCAT() Warning 1260 Row 5 was cut by group_concat()
Warning 1260 Row 7 was cut by GROUP_CONCAT() Warning 1260 Row 7 was cut by group_concat()
'#--------------------FN_DYNVARS_034_03-------------------------#' '#--------------------FN_DYNVARS_034_03-------------------------#'
connection test_con2; connection test_con2;
## Verifying initial value of variable. It should be 4 ## ## Verifying initial value of variable. It should be 4 ##
@@ -77,7 +77,7 @@ id rollno GROUP_CONCAT(name)
4 3 Record_4,Record_6 4 3 Record_4,Record_6
7 4 Record_7,Record_8 7 4 Record_7,Record_8
Warnings: Warnings:
Warning 1260 Row 3 was cut by GROUP_CONCAT() Warning 1260 Row 3 was cut by group_concat()
'#--------------------FN_DYNVARS_034_04-------------------------#' '#--------------------FN_DYNVARS_034_04-------------------------#'
## Setting session value of variable to 26. No warning should appear here ## ## Setting session value of variable to 26. No warning should appear here ##
## because the value after concatination is less than 30 ## ## because the value after concatination is less than 30 ##

View File

@@ -83,7 +83,7 @@ JSON_CONTAINS(@json_doc, '"COMMIT"', '$[0].statements_executed[1].sql_text')
SET @sys.ps_thread_trx_info.max_length = 100; SET @sys.ps_thread_trx_info.max_length = 100;
SELECT sys.ps_thread_trx_info(@ps_thread_id); SELECT sys.ps_thread_trx_info(@ps_thread_id);
sys.ps_thread_trx_info(@ps_thread_id) sys.ps_thread_trx_info(@ps_thread_id)
{ "error": "Trx info truncated: Row 1X was cut by GROUP_CONCAT()" } { "error": "Trx info truncated: Row 1X was cut by group_concat()" }
SET @sys.ps_thread_trx_info.max_length = NULL; SET @sys.ps_thread_trx_info.max_length = NULL;
SELECT JSON_VALID(sys.ps_thread_trx_info(@ps_thread_id)); SELECT JSON_VALID(sys.ps_thread_trx_info(@ps_thread_id));
JSON_VALID(sys.ps_thread_trx_info(@ps_thread_id)) JSON_VALID(sys.ps_thread_trx_info(@ps_thread_id))

View File

@@ -1302,7 +1302,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=COALESCE(CAST('0.0.0.1' AS INET4)) AND
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.1' and `test`.`t1`.`id` > 0 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.1' and `test`.`t1`.`id` > 0
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal field propagation # Optimizer: equal field propagation
@@ -1315,14 +1315,14 @@ AND LENGTH(CONCAT(a,RAND()))>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.1' and octet_length(concat(INET4'0.0.0.1',rand())) > 1 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.1' and octet_length(concat(inet4'0.0.0.1',rand())) > 1
EXPLAIN EXTENDED SELECT * FROM t1 EXPLAIN EXTENDED SELECT * FROM t1
WHERE a=COALESCE(CAST('0.0.0.1' AS INET4)) WHERE a=COALESCE(CAST('0.0.0.1' AS INET4))
AND LENGTH(a)>1; AND LENGTH(a)>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.1' Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.1'
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal expression propagation # Optimizer: equal expression propagation

View File

@@ -85,7 +85,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('0.0.0.255' AS INET4);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 5 const 1 100.00 Using where; Using index 1 SIMPLE t1 ref a a 5 const 1 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.255' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.255'
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item

View File

@@ -152,7 +152,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('0.0.0.255' AS INET4);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 5 const 2 100.00 Using where 1 SIMPLE t1 ref a a 5 const 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.255' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.255'
DROP TABLE t1; DROP TABLE t1;
# #
# End of 10.10 tests # End of 10.10 tests

View File

@@ -85,7 +85,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('0.0.0.255' AS INET4);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 5 const 1 100.00 Using where; Using index 1 SIMPLE t1 ref a a 5 const 1 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET4'0.0.0.255' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet4'0.0.0.255'
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item

View File

@@ -1295,7 +1295,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=COALESCE(CAST('::1' AS INET6)) AND id>
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::1' and `test`.`t1`.`id` > 0 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::1' and `test`.`t1`.`id` > 0
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal field propagation # Optimizer: equal field propagation
@@ -1308,14 +1308,14 @@ AND LENGTH(CONCAT(a,RAND()))>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::1' and octet_length(concat(INET6'::1',rand())) > 1 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::1' and octet_length(concat(inet6'::1',rand())) > 1
EXPLAIN EXTENDED SELECT * FROM t1 EXPLAIN EXTENDED SELECT * FROM t1
WHERE a=COALESCE(CAST('::1' AS INET6)) WHERE a=COALESCE(CAST('::1' AS INET6))
AND LENGTH(a)>1; AND LENGTH(a)>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::1' Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::1'
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal expression propagation # Optimizer: equal expression propagation

View File

@@ -85,7 +85,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('::ff' AS INET6);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index 1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::ff'
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item

View File

@@ -152,7 +152,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('::ff' AS INET6);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 2 100.00 Using where 1 SIMPLE t1 ref a a 17 const 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::ff'
DROP TABLE t1; DROP TABLE t1;
# #
# End of 10.5 tests # End of 10.5 tests

View File

@@ -85,7 +85,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('::ff' AS INET6);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index 1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = inet6'::ff'
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item

View File

@@ -2477,7 +2477,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=COALESCE(CAST('00000000-0000-0000-0000
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-000000000001' and `test`.`t1`.`id` > 0 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-000000000001' and `test`.`t1`.`id` > 0
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal field propagation # Optimizer: equal field propagation
@@ -2492,14 +2492,14 @@ AND LENGTH(CONCAT(a,RAND()))>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-000000000001' and octet_length(concat(UUID'00000000-0000-0000-0000-000000000001',rand())) > 1 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-000000000001' and octet_length(concat(uuid'00000000-0000-0000-0000-000000000001',rand())) > 1
EXPLAIN EXTENDED SELECT * FROM t1 EXPLAIN EXTENDED SELECT * FROM t1
WHERE a=COALESCE(CAST('00000000-0000-0000-0000-000000000001' AS UUID)) WHERE a=COALESCE(CAST('00000000-0000-0000-0000-000000000001' AS UUID))
AND LENGTH(a)>1; AND LENGTH(a)>1;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-000000000001' Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-000000000001'
DROP TABLE t1; DROP TABLE t1;
# #
# Optimizer: equal expression propagation # Optimizer: equal expression propagation

View File

@@ -113,7 +113,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-00000000
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index 1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-0000000000ff'
DROP TABLE t1; DROP TABLE t1;
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a)); CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;

View File

@@ -180,7 +180,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-00000000
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 2 100.00 Using where 1 SIMPLE t1 ref a a 17 const 2 100.00 Using where
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-0000000000ff'
DROP TABLE t1; DROP TABLE t1;
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a)); CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;

View File

@@ -113,7 +113,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-00000000
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref a a 17 const 7 100.00 Using where; Using index 1 SIMPLE t1 ref a a 17 const 7 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff' Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = uuid'00000000-0000-0000-0000-0000000000ff'
DROP TABLE t1; DROP TABLE t1;
CREATE OR REPLACE TABLE t1 (a UUID,KEY(a)); CREATE OR REPLACE TABLE t1 (a UUID,KEY(a));
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;

View File

@@ -46,12 +46,17 @@ public:
{ {
return buff_sz; // The maximum data size, without the trailing '\0' byte. return buff_sz; // The maximum data size, without the trailing '\0' byte.
} }
size_t available_size() const
{
DBUG_ASSERT(is_sane());
return buff_sz - m_length;
}
CharBuffer() CharBuffer()
:m_length(0) :m_length(0)
{ {
m_buff[0]= '\0'; m_buff[0]= '\0';
} }
CharBuffer<buff_sz> & copy_bin(const LEX_CSTRING &str) CharBuffer<buff_sz> & copy(const LEX_CSTRING &str)
{ {
DBUG_ASSERT(!buffer_overlaps(str)); DBUG_ASSERT(!buffer_overlaps(str));
m_length= MY_MIN(buff_sz, str.length); m_length= MY_MIN(buff_sz, str.length);
@@ -71,25 +76,92 @@ public:
m_buff[m_length]= '\0'; m_buff[m_length]= '\0';
return *this; return *this;
} }
CharBuffer<buff_sz> & copy_caseup(CHARSET_INFO *cs, const LEX_CSTRING &str)
{
DBUG_ASSERT(!buffer_overlaps(str));
m_length= cs->cset->caseup(cs, str.str, str.length, m_buff, buff_sz);
DBUG_ASSERT(is_sane());
m_buff[m_length]= '\0'; // See comments in copy_casedn()
return *this;
}
CharBuffer<buff_sz> & copy_casedn(CHARSET_INFO *cs, const LEX_CSTRING &str, CharBuffer<buff_sz> & copy_casedn(CHARSET_INFO *cs, const LEX_CSTRING &str,
bool casedn) bool casedn)
{ {
casedn ? copy_casedn(cs, str) : copy_bin(str); casedn ? copy_casedn(cs, str) : copy(str);
return *this; return *this;
} }
// Append one character
CharBuffer<buff_sz> & append_char(char ch)
{
DBUG_ASSERT(is_sane());
if (available_size())
{
m_buff[m_length++]= ch;
m_buff[m_length]= '\0';
}
DBUG_ASSERT(is_sane());
return *this;
}
// Append a string
CharBuffer<buff_sz> & append(const LEX_CSTRING &str)
{
DBUG_ASSERT(is_sane());
DBUG_ASSERT(!buffer_overlaps(str));
size_t len= MY_MIN(available_size(), str.length);
memcpy(m_buff + m_length, str.str, len);
m_length+= len;
DBUG_ASSERT(is_sane());
m_buff[m_length]= '\0';
return *this;
}
// Append a string with casedn conversion // Append a string with casedn conversion
CharBuffer<buff_sz> & append_casedn(CHARSET_INFO *cs, const LEX_CSTRING &str) CharBuffer<buff_sz> & append_casedn(CHARSET_INFO *cs, const LEX_CSTRING &str)
{ {
DBUG_ASSERT(is_sane()); DBUG_ASSERT(is_sane());
DBUG_ASSERT(!buffer_overlaps(str)); DBUG_ASSERT(!buffer_overlaps(str));
size_t casedn_length= cs->casedn(str.str, str.length, size_t casedn_length= cs->casedn(str.str, str.length,
m_buff + m_length, buff_sz - m_length); m_buff + m_length, available_size());
m_length+= casedn_length; m_length+= casedn_length;
DBUG_ASSERT(is_sane()); DBUG_ASSERT(is_sane());
m_buff[m_length]= '\0'; m_buff[m_length]= '\0';
return *this; return *this;
} }
CharBuffer<buff_sz> & append_opt_casedn(CHARSET_INFO *cs,
const LEX_CSTRING &str,
bool casedn)
{
return casedn ? append_casedn(cs, str) : append(str);
}
// Append a string with caseup conversion
CharBuffer<buff_sz> & append_caseup(CHARSET_INFO *cs, const LEX_CSTRING &str)
{
DBUG_ASSERT(is_sane());
DBUG_ASSERT(!buffer_overlaps(str));
size_t casedn_length= cs->caseup(str.str, str.length,
m_buff + m_length, available_size());
m_length+= casedn_length;
DBUG_ASSERT(is_sane());
m_buff[m_length]= '\0';
return *this;
}
CharBuffer<buff_sz> & truncate(size_t length)
{
DBUG_ASSERT(is_sane());
if (m_length > length)
{
m_length= length;
m_buff[m_length]= '\0';
DBUG_ASSERT(is_sane());
}
return *this;
}
LEX_CSTRING to_lex_cstring() const LEX_CSTRING to_lex_cstring() const
{ {
return LEX_CSTRING{m_buff, m_length}; return LEX_CSTRING{m_buff, m_length};
@@ -97,6 +169,7 @@ public:
const char *ptr() const { return m_buff; } const char *ptr() const { return m_buff; }
size_t length() const { return m_length; } size_t length() const { return m_length; }
const char *end() const { return m_buff + m_length; }
}; };

View File

@@ -3146,7 +3146,7 @@ public:
const Lex_cstring &db_and_table) const Lex_cstring &db_and_table)
{ {
DBUG_ASSERT(homedir.length + db_and_table.length <= max_data_size()); DBUG_ASSERT(homedir.length + db_and_table.length <= max_data_size());
copy_bin(homedir); copy(homedir);
append_casedn(db_and_table_charset, db_and_table); append_casedn(db_and_table_charset, db_and_table);
return *this; return *this;
} }

View File

@@ -68,8 +68,8 @@ class Create_sp_func : public Create_qfunc
{ {
public: public:
virtual Item *create_with_db(THD *thd, virtual Item *create_with_db(THD *thd,
const LEX_CSTRING *db, const Lex_ident_db_normalized &db,
const LEX_CSTRING *name, const LEX_CSTRING &name,
bool use_explicit_name, List<Item> *item_list); bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton; static Create_sp_func s_singleton;
@@ -2828,8 +2828,6 @@ Item*
Create_qfunc::create_func(THD *thd, const LEX_CSTRING *name, Create_qfunc::create_func(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list) List<Item> *item_list)
{ {
LEX_CSTRING db;
if (unlikely(! thd->db.str && ! thd->lex->sphead)) if (unlikely(! thd->db.str && ! thd->lex->sphead))
{ {
/* /*
@@ -2848,10 +2846,11 @@ Create_qfunc::create_func(THD *thd, const LEX_CSTRING *name,
return NULL; return NULL;
} }
if (thd->lex->copy_db_to(&db)) Lex_ident_db_normalized db= thd->lex->copy_db_normalized();
return NULL; if (!db.str)
return NULL; /*No db or EOM, error was already sent */
return create_with_db(thd, &db, name, false, item_list); return create_with_db(thd, db, *name, false, item_list);
} }
@@ -2971,8 +2970,8 @@ Create_sp_func Create_sp_func::s_singleton;
Item* Item*
Create_sp_func::create_with_db(THD *thd, Create_sp_func::create_with_db(THD *thd,
const LEX_CSTRING *db, const Lex_ident_db_normalized &db,
const LEX_CSTRING *name, const LEX_CSTRING &name,
bool use_explicit_name, List<Item> *item_list) bool use_explicit_name, List<Item> *item_list)
{ {
int arg_count= 0; int arg_count= 0;
@@ -2993,7 +2992,7 @@ Create_sp_func::create_with_db(THD *thd,
because it can refer to a User Defined Function call. because it can refer to a User Defined Function call.
For a Stored Function however, this has no semantic. For a Stored Function however, this has no semantic.
*/ */
my_error(ER_WRONG_PARAMETERS_TO_STORED_FCT, MYF(0), name->str); my_error(ER_WRONG_PARAMETERS_TO_STORED_FCT, MYF(0), name.str);
return NULL; return NULL;
} }

View File

@@ -239,8 +239,8 @@ public:
@return An item representing the parsed function call @return An item representing the parsed function call
*/ */
virtual Item *create_with_db(THD *thd, virtual Item *create_with_db(THD *thd,
const LEX_CSTRING *db, const Lex_ident_db_normalized &db,
const LEX_CSTRING *name, const LEX_CSTRING &name,
bool use_explicit_name, bool use_explicit_name,
List<Item> *item_list) = 0; List<Item> *item_list) = 0;

View File

@@ -3776,18 +3776,10 @@ int group_concat_key_cmp_with_order_with_nulls(void *arg, const void *key1_arg,
static void report_cut_value_error(THD *thd, uint row_count, const char *fname) static void report_cut_value_error(THD *thd, uint row_count, const char *fname)
{ {
size_t fn_len= strlen(fname);
char *fname_upper= (char *) my_alloca(fn_len + 1);
if (!fname_upper)
fname_upper= (char*) fname; // Out of memory
else
memcpy(fname_upper, fname, fn_len+1);
my_caseup_str(&my_charset_latin1, fname_upper);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_CUT_VALUE_GROUP_CONCAT, ER_CUT_VALUE_GROUP_CONCAT,
ER_THD(thd, ER_CUT_VALUE_GROUP_CONCAT), ER_THD(thd, ER_CUT_VALUE_GROUP_CONCAT),
row_count, fname_upper); row_count, fname);
my_afree(fname_upper);
} }

View File

@@ -19,6 +19,7 @@
*/ */
#include "char_buffer.h" #include "char_buffer.h"
#include "lex_string.h"
/* /*
@@ -45,6 +46,10 @@ public:
bool is_in_lower_case() const; bool is_in_lower_case() const;
bool ok_for_lower_case_names() const; bool ok_for_lower_case_names() const;
#endif #endif
bool check_db_name_quick() const
{
return !length || length > NAME_LEN || str[length-1] == ' ';
}
}; };
@@ -56,6 +61,10 @@ public:
*/ */
class Lex_ident_db: public Lex_ident_fs class Lex_ident_db: public Lex_ident_fs
{ {
bool is_null() const
{
return length == 0 && str == NULL;
}
// {empty_c_string,0} is used by derived tables // {empty_c_string,0} is used by derived tables
bool is_empty() const bool is_empty() const
{ {
@@ -68,7 +77,7 @@ public:
Lex_ident_db(const char *str, size_t length) Lex_ident_db(const char *str, size_t length)
:Lex_ident_fs(str, length) :Lex_ident_fs(str, length)
{ {
DBUG_SLOW_ASSERT(is_empty() || !check_db_name()); DBUG_SLOW_ASSERT(is_null() || is_empty() || !check_db_name());
} }
}; };
@@ -81,6 +90,8 @@ public:
class Lex_ident_db_normalized: public Lex_ident_db class Lex_ident_db_normalized: public Lex_ident_db
{ {
public: public:
Lex_ident_db_normalized()
{ }
Lex_ident_db_normalized(const char *str, size_t length) Lex_ident_db_normalized(const char *str, size_t length)
:Lex_ident_db(str, length) :Lex_ident_db(str, length)
{ {
@@ -160,4 +171,172 @@ public:
}; };
class Identifier_chain2
{
LEX_CSTRING m_name[2];
public:
Identifier_chain2()
:m_name{Lex_cstring(), Lex_cstring()}
{ }
Identifier_chain2(const LEX_CSTRING &a, const LEX_CSTRING &b)
:m_name{a, b}
{ }
const LEX_CSTRING& operator [] (size_t i) const
{
return m_name[i];
}
static Identifier_chain2 split(const LEX_CSTRING &txt)
{
DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input
const char *dot= strchr(txt.str, '.');
if (!dot)
return Identifier_chain2(Lex_cstring(), txt);
size_t length0= dot - txt.str;
Lex_cstring name0(txt.str, length0);
Lex_cstring name1(txt.str + length0 + 1, txt.length - length0 - 1);
return Identifier_chain2(name0, name1);
}
// The minimum possible buffer size for the make_sep_name*() functions
static constexpr size_t min_sep_name_size()
{
/*
The minimal possible buffer is 4 bytes: 'd/t\0'
where 'd' is the database name, 't' is the table name.
Callers should never pass a smaller buffer.
*/
return 4;
}
// Export as a qualified name string: 'db.name'
size_t make_sep_name(char *dst, size_t dstlen, int sep) const
{
DBUG_ASSERT(dstlen >= min_sep_name_size());
return my_snprintf(dst, dstlen, "%.*s%c%.*s",
(int) m_name[0].length, m_name[0].str, sep,
(int) m_name[1].length, m_name[1].str);
}
// Export as a qualified name string 'db.name', lower-casing 'db' and 'name'
size_t make_sep_name_casedn(char *dst, size_t dst_size, int sep) const
{
DBUG_ASSERT(dst_size >= min_sep_name_size());
CHARSET_INFO *cs= &my_charset_utf8mb3_general_ci;
char *ptr= dst, *end= dst + dst_size;
ptr+= cs->casedn(m_name[0].str, m_name[0].length, ptr, end - ptr - 2);
*ptr++= (char) sep;
ptr+= cs->casedn_z(m_name[1].str, m_name[1].length, ptr, end - ptr);
return ptr - dst;
}
// Export as a qualified name, optionally lower-casing only the 'name' part
size_t make_sep_name_casedn_part1(char *dst, size_t dst_size, int sep) const
{
DBUG_ASSERT(dst_size >= min_sep_name_size());
CHARSET_INFO *cs= &my_charset_utf8mb3_general_ci;
char *ptr= dst, *end= dst + dst_size;
ptr+= cs->opt_casedn(m_name[0].str, m_name[0].length,
ptr, end - ptr - 2, false);
*ptr++= (char) sep;
ptr+= cs->casedn_z(m_name[1].str, m_name[1].length, ptr, end - ptr);
return ptr - dst;
}
/*
Export as a qualified name, e.g. 'db.name', 0-terminated,
optionally lower-casing both 'db' and 'name' parts.
@param [OUT] dst - the destination
@param dst_size - number of bytes available in dst
@param sep - the separator character
@param casedn - whether to convert components to lower case
@return - number of bytes written to "dst", not counting
the trailing '\0' byte.
*/
size_t make_sep_name_opt_casedn(char *dst, size_t dst_size,
int sep, bool casedn) const
{
DBUG_ASSERT(m_name[0].length + m_name[1].length + 2 < FN_REFLEN - 1);
return casedn ? make_sep_name_casedn(dst, dst_size, sep) :
make_sep_name(dst, dst_size, sep);
}
/*
Export as a qualified name string 'db.name',
using the dot character as a separator,
optionally cover-casing the 'name' part.
*/
size_t make_sep_name_opt_casedn_part1(char *dst, size_t dst_size,
int sep,
bool casedn_part1) const
{
return casedn_part1 ? make_sep_name_casedn_part1(dst, dst_size, sep) :
make_sep_name(dst, dst_size, sep);
}
/*
Export as a qualified name string, allocated on mem_root,
using the dot character as a separator,
optionally lower-casing the 'name' part.
*/
LEX_CSTRING make_sep_name_opt_casedn_part1(MEM_ROOT *mem_root,
int sep,
bool casedn_part1) const
{
LEX_STRING dst;
/* format: [pkg + dot] + name + '\0' */
size_t dst_size= m_name[0].length + 1 /*dot*/ + m_name[1].length + 1/*\0*/;
if (unlikely(!(dst.str= (char*) alloc_root(mem_root, dst_size))))
return {NULL, 0};
if (!m_name[0].length)
{
DBUG_ASSERT(!casedn_part1); // Should not be called this way
dst.length= my_snprintf(dst.str, dst_size, "%.*s",
(int) m_name[1].length, m_name[1].str);
return {dst.str, dst.length};
}
dst.length= make_sep_name_opt_casedn_part1(dst.str, dst_size,
sep, casedn_part1);
return {dst.str, dst.length};
}
/*
Export as a qualified name string 'db.name',
using the dot character as a separator,
lower-casing the 'name' part.
*/
size_t make_qname_casedn_part1(char *dst, size_t dst_size) const
{
return make_sep_name_casedn_part1(dst, dst_size, '.');
}
// Export as a qualified name string: 'db.name' using the dot character.
size_t make_qname(char *dst, size_t dstlen) const
{
return make_sep_name(dst, dstlen, '.');
}
/*
Export as a qualified name string 'db.name', allocated on mem_root,
using the dot character as a separator.
*/
LEX_CSTRING make_qname(MEM_ROOT *mem_root) const
{
return make_sep_name_opt_casedn_part1(mem_root, '.', false);
}
/*
Export as a qualified name string 'db.name', allocated on mem_root,
using the dot character as a separator,
lower-casing the 'name' part.
*/
LEX_CSTRING make_qname_casedn_part1(MEM_ROOT *mem_root) const
{
return make_sep_name_opt_casedn_part1(mem_root, '.', true);
}
};
#endif // LEX_IDENT_INCLUDED #endif // LEX_IDENT_INCLUDED

View File

@@ -5800,6 +5800,12 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi)
RPL_TABLE_LIST *table_list; RPL_TABLE_LIST *table_list;
char *db_mem, *tname_mem, *ptr; char *db_mem, *tname_mem, *ptr;
size_t dummy_len, db_mem_length, tname_mem_length; size_t dummy_len, db_mem_length, tname_mem_length;
/*
The database name can be changed to a longer name after get_rewrite_db().
Allocate the maximum possible size.
*/
const size_t db_mem_alloced= NAME_LEN + 1;
const size_t tname_mem_alloced= NAME_LEN + 1;
void *memory; void *memory;
Rpl_filter *filter; Rpl_filter *filter;
Relay_log_info const *rli= rgi->rli; Relay_log_info const *rli= rgi->rli;
@@ -5810,17 +5816,23 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi)
if (!(memory= my_multi_malloc(PSI_INSTRUMENT_ME, MYF(MY_WME), if (!(memory= my_multi_malloc(PSI_INSTRUMENT_ME, MYF(MY_WME),
&table_list, (uint) sizeof(RPL_TABLE_LIST), &table_list, (uint) sizeof(RPL_TABLE_LIST),
&db_mem, (uint) NAME_LEN + 1, &db_mem, (uint) db_mem_alloced,
&tname_mem, (uint) NAME_LEN + 1, &tname_mem, (uint) tname_mem_alloced,
NullS))) NullS)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
db_mem_length= strmov(db_mem, m_dbnam) - db_mem;
tname_mem_length= strmov(tname_mem, m_tblnam) - tname_mem;
if (lower_case_table_names) if (lower_case_table_names)
{ {
my_casedn_str(files_charset_info, (char*)tname_mem); db_mem_length= files_charset_info->casedn_z(m_dbnam, m_dblen,
my_casedn_str(files_charset_info, (char*)db_mem); db_mem, db_mem_alloced);
tname_mem_length= files_charset_info->casedn_z(m_tblnam, m_tbllen,
tname_mem,
tname_mem_alloced);
}
else
{
db_mem_length= strmov(db_mem, m_dbnam) - db_mem;
tname_mem_length= strmov(tname_mem, m_tblnam) - tname_mem;
} }
/* call from mysql_client_binlog_statement() will not set rli->mi */ /* call from mysql_client_binlog_statement() will not set rli->mi */

View File

@@ -967,12 +967,6 @@ extern "C" void unireg_clear(int exit_code);
#define unireg_abort(exit_code) do { unireg_clear(exit_code); DBUG_RETURN(exit_code); } while(0) #define unireg_abort(exit_code) do { unireg_clear(exit_code); DBUG_RETURN(exit_code); } while(0)
#endif #endif
inline void table_case_convert(char * name, uint length)
{
if (lower_case_table_names)
files_charset_info->casedn(name, length, name, length);
}
extern void set_server_version(char *buf, size_t size); extern void set_server_version(char *buf, size_t size);
#define current_thd _current_thd() #define current_thd _current_thd()

View File

@@ -56,16 +56,22 @@ Master_info::Master_info(LEX_CSTRING *connection_name_arg,
Store connection name and lower case connection name Store connection name and lower case connection name
It's safe to ignore any OMM errors as this is checked by error() It's safe to ignore any OMM errors as this is checked by error()
*/ */
connection_name.length= cmp_connection_name.length= connection_name.length= connection_name_arg->length;
connection_name_arg->length; size_t cmp_connection_name_nbytes= connection_name_arg->length *
system_charset_info->casedn_multiply() +
1;
if ((connection_name.str= tmp= (char*) if ((connection_name.str= tmp= (char*)
my_malloc(PSI_INSTRUMENT_ME, connection_name_arg->length*2+2, MYF(MY_WME)))) my_malloc(PSI_INSTRUMENT_ME, connection_name_arg->length + 1 +
cmp_connection_name_nbytes,
MYF(MY_WME))))
{ {
strmake(tmp, connection_name_arg->str, connection_name.length); strmake(tmp, connection_name_arg->str, connection_name.length);
tmp+= connection_name_arg->length+1; tmp+= connection_name_arg->length+1;
cmp_connection_name.str= tmp; cmp_connection_name.str= tmp;
memcpy(tmp, connection_name_arg->str, connection_name.length+1); cmp_connection_name.length=
my_casedn_str(system_charset_info, tmp); system_charset_info->casedn_z(connection_name_arg->str,
connection_name_arg->length,
tmp, cmp_connection_name_nbytes);
} }
/* /*
When MySQL restarted, all Rpl_filter settings which aren't in the my.cnf When MySQL restarted, all Rpl_filter settings which aren't in the my.cnf

View File

@@ -1802,9 +1802,8 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr)
++auto_engines) ++auto_engines)
{ {
void *hton= plugin_hton(*auto_engines); void *hton= plugin_hton(*auto_engines);
char buf[FN_REFLEN+1]; CharBuffer<FN_REFLEN> buf;
LEX_CSTRING table_name; LEX_CSTRING table_name;
char *p;
rpl_slave_state::gtid_pos_table *entry, **next_ptr; rpl_slave_state::gtid_pos_table *entry, **next_ptr;
/* See if this engine is already in the list. */ /* See if this engine is already in the list. */
@@ -1821,13 +1820,12 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr)
continue; continue;
/* Add an auto-create entry for this engine at end of list. */ /* Add an auto-create entry for this engine at end of list. */
p= strmake(buf, rpl_gtid_slave_state_table_name.str, FN_REFLEN); buf.append_opt_casedn(files_charset_info, rpl_gtid_slave_state_table_name,
p= strmake(p, "_", FN_REFLEN - (p - buf)); lower_case_table_names)
p= strmake(p, plugin_name(*auto_engines)->str, FN_REFLEN - (p - buf)); .append({STRING_WITH_LEN("_")})
table_name.str= buf; .append_opt_casedn(files_charset_info, *plugin_name(*auto_engines),
table_name.length= p - buf; lower_case_table_names);
table_case_convert(const_cast<char*>(table_name.str), table_name= buf.to_lex_cstring();
static_cast<uint>(table_name.length));
entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table
(&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE); (&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE);
if (!entry) if (!entry)

View File

@@ -1075,7 +1075,6 @@ static void store_var(Field *field, sys_var *var, enum_var_type scope,
int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond) int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
char name_buffer[NAME_CHAR_LEN];
bool res= 1; bool res= 1;
CHARSET_INFO *scs= system_charset_info; CHARSET_INFO *scs= system_charset_info;
StringBuffer<STRING_BUFFER_USUAL_SIZE> strbuf(scs); StringBuffer<STRING_BUFFER_USUAL_SIZE> strbuf(scs);
@@ -1091,15 +1090,14 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond)
for (uint i= 0; i < system_variable_hash.records; i++) for (uint i= 0; i < system_variable_hash.records; i++)
{ {
sys_var *var= (sys_var*) my_hash_element(&system_variable_hash, i); sys_var *var= (sys_var*) my_hash_element(&system_variable_hash, i);
CharBuffer<NAME_CHAR_LEN> name_buffer;
strmake_buf(name_buffer, var->name.str); name_buffer.copy_caseup(scs, var->name);
my_caseup_str(system_charset_info, name_buffer);
/* this must be done before evaluating cond */ /* this must be done before evaluating cond */
restore_record(tables->table, s->default_values); restore_record(tables->table, s->default_values);
fields[0]->store(name_buffer, strlen(name_buffer), scs); fields[0]->store(name_buffer.to_lex_cstring(), scs);
if ((wild && wild_case_compare(system_charset_info, name_buffer, wild)) if ((wild && wild_case_compare(scs, name_buffer.ptr(), wild))
|| (cond && !cond->val_int())) || (cond && !cond->val_int()))
continue; continue;

View File

@@ -2281,12 +2281,20 @@ Sp_handler::sp_exist_routines(THD *thd, TABLE_LIST *routines) const
for (routine= routines; routine; routine= routine->next_global) for (routine= routines; routine; routine= routine->next_global)
{ {
sp_name *name; sp_name *name;
LEX_CSTRING lex_db; LEX_CSTRING lex_db= thd->make_ident_opt_casedn(routine->db,
LEX_CSTRING lex_name; lower_case_table_names);
thd->make_lex_string(&lex_db, routine->db.str, routine->db.length); if (!lex_db.str)
thd->make_lex_string(&lex_name, routine->table_name.str, DBUG_RETURN(TRUE); // EOM, error was already sent
routine->table_name.length); LEX_CSTRING lex_name= thd->strmake_lex_cstring(routine->table_name);
name= new sp_name(&lex_db, &lex_name, true); if (!lex_name.str)
DBUG_RETURN(TRUE); // EOM, error was already sent
/*
routine->db was earlier tested with check_db_name().
Now it's lower-cased according to lower_case_table_names.
It's safe to make a Lex_ident_db_normalized.
*/
name= new (thd->mem_root) sp_name(Lex_ident_db_normalized(lex_db),
lex_name, true);
sp_object_found= sp_find_routine(thd, name, false) != NULL; sp_object_found= sp_find_routine(thd, name, false) != NULL;
thd->get_stmt_da()->clear_warning_info(thd->query_id); thd->get_stmt_da()->clear_warning_info(thd->query_id);
if (! sp_object_found) if (! sp_object_found)
@@ -2915,7 +2923,16 @@ Sp_handler::sp_cache_package_routine(THD *thd,
{ {
DBUG_ENTER("sp_cache_package_routine"); DBUG_ENTER("sp_cache_package_routine");
DBUG_ASSERT(type() == SP_TYPE_FUNCTION || type() == SP_TYPE_PROCEDURE); DBUG_ASSERT(type() == SP_TYPE_FUNCTION || type() == SP_TYPE_PROCEDURE);
sp_name pkgname(&name->m_db, &pkgname_cstr, false); LEX_CSTRING db= lower_case_table_names ? thd->make_ident_casedn(name->m_db) :
name->m_db;
if (!db.str)
DBUG_RETURN(true); // EOM, error was already sent
/*
name->m_db was earlier tested with check_db_name().
Now it's lower-cased according to lower_case_table_names.
It's safe to make a Lex_ident_db_normalized.
*/
sp_name pkgname(Lex_ident_db_normalized(db), pkgname_cstr, false);
sp_head *ph= NULL; sp_head *ph= NULL;
int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname, int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname,
lookup_only, lookup_only,
@@ -3079,7 +3096,21 @@ Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table,
const AUTHID definer= {{STRING_WITH_LEN("")}, {STRING_WITH_LEN("")}}; const AUTHID definer= {{STRING_WITH_LEN("")}, {STRING_WITH_LEN("")}};
sp_head *sp; sp_head *sp;
sp_cache **spc= get_cache(thd); sp_cache **spc= get_cache(thd);
sp_name sp_name_obj(&db, &name, true); // This can change "name" DBUG_ASSERT(db.str);
LEX_CSTRING dbn= lower_case_table_names ? thd->make_ident_casedn(db) : db;
if (!dbn.str)
return 0; // EOM, error was already sent
if (Lex_ident_fs(dbn).check_db_name())
{
my_error(ER_SP_WRONG_NAME, MYF(0), dbn.str);
return 0;
}
/*
db was earlier tested with check_db_name().
Now it's lower-cased according to lower_case_table_names.
It's safe make a Lex_ident_db_normalized.
*/
sp_name sp_name_obj(Lex_ident_db_normalized(dbn), name, true);
*free_sp_head= 0; *free_sp_head= 0;
sp= sp_cache_lookup(spc, &sp_name_obj); sp= sp_cache_lookup(spc, &sp_name_obj);

View File

@@ -195,7 +195,8 @@ sp_head *sp_cache_lookup(sp_cache **cp, const Database_qualified_name *name)
sp_cache *c= *cp; sp_cache *c= *cp;
if (! c) if (! c)
return NULL; return NULL;
return c->lookup(buf, name->make_qname(buf, sizeof(buf), true)); return c->lookup(buf, name->to_identifier_chain2().
make_qname_casedn_part1(buf, sizeof(buf)));
} }

View File

@@ -113,12 +113,16 @@ class sp_name : public Sql_alloc,
public: public:
bool m_explicit_name; /**< Prepend the db name? */ bool m_explicit_name; /**< Prepend the db name? */
sp_name(const LEX_CSTRING *db, const LEX_CSTRING *name, sp_name(const Lex_ident_db_normalized &db, const LEX_CSTRING &name,
bool use_explicit_name) bool use_explicit_name)
: Database_qualified_name(db, name), m_explicit_name(use_explicit_name) : Database_qualified_name(db, name), m_explicit_name(use_explicit_name)
{ {
if (lower_case_table_names && m_db.length) /*
m_db.length= my_casedn_str(files_charset_info, (char*) m_db.str); "db" can be {NULL,0} in case of a "DROP FUNCTION udf" statement.
Otherwise, a valid normalized non-NULL database name is expected.
*/
DBUG_ASSERT((!db.str && !db.length) ||
!Lex_ident_fs(db).check_db_name_quick());
} }
/** Create temporary sp_name object from MDL key. Store in qname_buff */ /** Create temporary sp_name object from MDL key. Store in qname_buff */

View File

@@ -627,8 +627,6 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, const char *username,
} }
#define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3) #define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3)
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
1 + USERNAME_LENGTH + 1)
#if defined(HAVE_OPENSSL) #if defined(HAVE_OPENSSL)
/* /*
@@ -2548,6 +2546,37 @@ static void push_new_user(const ACL_USER &user)
} }
/**
Make a database name on mem_root from a String,
apply lower-case conversion if lower_case_table_names says so.
Perform database name length limit validation.
@param thd - the THD, to get the warning text from
@param mem_root - allocate the result on this memory root
@param dbstr - the String, e.g. with Field::val_str() result
@return - {NULL,0} in case of EOM or a bad database name,
or a good database name otherwise.
*/
static LEX_STRING make_and_check_db_name(MEM_ROOT *mem_root,
const String &dbstr)
{
LEX_STRING dbls= lower_case_table_names ?
lex_string_casedn_root(mem_root, files_charset_info,
dbstr.ptr(), dbstr.length()) :
lex_string_strmake_root(mem_root,
dbstr.ptr(), dbstr.length());
if (!dbls.str)
return LEX_STRING{NULL, 0}; // EOM
if (dbls.length > SAFE_NAME_LEN)
{
sql_print_warning(ER_DEFAULT(ER_WRONG_DB_NAME), dbls.str);
return LEX_STRING{NULL, 0}; // Bad name
}
return dbls; // Good name
}
/* /*
Initialize structures responsible for user/db-level privilege checking Initialize structures responsible for user/db-level privilege checking
and load information about grants from open privilege tables. and load information about grants from open privilege tables.
@@ -2567,7 +2596,6 @@ static void push_new_user(const ACL_USER &user)
static bool acl_load(THD *thd, const Grant_tables& tables) static bool acl_load(THD *thd, const Grant_tables& tables)
{ {
READ_RECORD read_record_info; READ_RECORD read_record_info;
char tmp_name[SAFE_NAME_LEN+1];
Sql_mode_save old_mode_save(thd); Sql_mode_save old_mode_save(thd);
DBUG_ENTER("acl_load"); DBUG_ENTER("acl_load");
@@ -2585,28 +2613,25 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
{ {
ACL_HOST host; ACL_HOST host;
update_hostname(&host.host, get_field(&acl_memroot, host_table.host())); update_hostname(&host.host, get_field(&acl_memroot, host_table.host()));
host.db= get_field(&acl_memroot, host_table.db()); StringBuffer<SAFE_NAME_LEN> dbstr;
if (lower_case_table_names && host.db) host_table.db()->val_str(&dbstr);
if (dbstr.length())
{ {
const LEX_STRING dbls= make_and_check_db_name(&acl_memroot, dbstr);
if (!(host.db= dbls.str))
continue; // EOM or a bad database name
/* /*
convert db to lower case and give a warning if the db wasn't Issue a warning if lower case conversion happened
already in lower case and it changed the database name.
*/ */
char *end = strnmov(tmp_name, host.db, sizeof(tmp_name)); if (lower_case_table_names && cmp(dbls, dbstr.to_lex_cstring()))
if (end >= tmp_name + sizeof(tmp_name))
{
sql_print_warning(ER_THD(thd, ER_WRONG_DB_NAME), host.db);
continue;
}
my_casedn_str(files_charset_info, host.db);
if (strcmp(host.db, tmp_name) != 0)
sql_print_warning("'host' entry '%s|%s' had database in mixed " sql_print_warning("'host' entry '%s|%s' had database in mixed "
"case that has been forced to lowercase because " "case that has been forced to lowercase because "
"lower_case_table_names is set. It will not be " "lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.", "possible to remove this privilege using REVOKE.",
host.host.hostname, host.db); host.host.hostname, host.db);
} }
else if (!host.db) else
host.db= const_cast<char*>(host_not_specified.str); host.db= const_cast<char*>(host_not_specified.str);
host.access= host_table.get_access(); host.access= host_table.get_access();
host.access= fix_rights_for_db(host.access); host.access= fix_rights_for_db(host.access);
@@ -2733,18 +2758,35 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
while (!(read_record_info.read_record())) while (!(read_record_info.read_record()))
{ {
ACL_DB db; ACL_DB db;
char *db_name;
db.user=safe_str(get_field(&acl_memroot, db_table.user())); db.user=safe_str(get_field(&acl_memroot, db_table.user()));
const char *hostname= get_field(&acl_memroot, db_table.host()); const char *hostname= get_field(&acl_memroot, db_table.host());
if (!hostname && find_acl_role(db.user, true)) if (!hostname && find_acl_role(db.user, true))
hostname= ""; hostname= "";
update_hostname(&db.host, hostname); update_hostname(&db.host, hostname);
db.db= db_name= get_field(&acl_memroot, db_table.db());
if (!db.db) StringBuffer<SAFE_NAME_LEN> dbstr;
db_table.db()->val_str(&dbstr);
if (!dbstr.length())
{ {
sql_print_warning("Found an entry in the 'db' table with empty database name; Skipped"); sql_print_warning("Found an entry in the 'db' table with empty database name; Skipped");
continue; continue;
} }
const LEX_STRING dbls= make_and_check_db_name(&acl_memroot, dbstr);
if (!(db.db= dbls.str)) // EOM or a bad database name
continue;
/*
Issue a warning if lower case conversion happened
and it changed the database name.
*/
if (lower_case_table_names && cmp(dbls, dbstr.to_lex_cstring()))
{
sql_print_warning("'db' entry '%s %s@%s' had database in mixed "
"case that has been forced to lowercase because "
"lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.",
db.db, db.user, safe_str(db.host.hostname));
}
if (opt_skip_name_resolve && hostname_requires_resolving(db.host.hostname)) if (opt_skip_name_resolve && hostname_requires_resolving(db.host.hostname))
{ {
sql_print_warning("'db' entry '%s %s@%s' " sql_print_warning("'db' entry '%s %s@%s' "
@@ -2755,28 +2797,6 @@ static bool acl_load(THD *thd, const Grant_tables& tables)
db.access= db_table.get_access(); db.access= db_table.get_access();
db.access=fix_rights_for_db(db.access); db.access=fix_rights_for_db(db.access);
db.initial_access= db.access; db.initial_access= db.access;
if (lower_case_table_names)
{
/*
convert db to lower case and give a warning if the db wasn't
already in lower case
*/
char *end = strnmov(tmp_name, db.db, sizeof(tmp_name));
if (end >= tmp_name + sizeof(tmp_name))
{
sql_print_warning(ER_THD(thd, ER_WRONG_DB_NAME), db.db);
continue;
}
my_casedn_str(files_charset_info, db_name);
if (strcmp(db_name, tmp_name) != 0)
{
sql_print_warning("'db' entry '%s %s@%s' had database in mixed "
"case that has been forced to lowercase because "
"lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.",
db.db, db.user, safe_str(db.host.hostname));
}
}
db.sort=get_magic_sort("hdu", db.host.hostname, db.db, db.user); db.sort=get_magic_sort("hdu", db.host.hostname, db.db, db.user);
#ifndef TO_BE_REMOVED #ifndef TO_BE_REMOVED
if (db_table.num_fields() <= 9) if (db_table.num_fields() <= 9)
@@ -3696,26 +3716,34 @@ privilege_t acl_get(const char *host, const char *ip,
{ {
privilege_t host_access(ALL_KNOWN_ACL), db_access(NO_ACL); privilege_t host_access(ALL_KNOWN_ACL), db_access(NO_ACL);
uint i; uint i;
size_t key_length; const char *tmp_db;
char key[ACL_KEY_LENGTH],*tmp_db,*end;
acl_entry *entry; acl_entry *entry;
DBUG_ENTER("acl_get"); DBUG_ENTER("acl_get");
tmp_db= strmov(strmov(key, safe_str(ip)) + 1, user) + 1; // Key length, without the trailing '\0' byte
end= strnmov(tmp_db, db, key + sizeof(key) - tmp_db); constexpr size_t key_data_size= IP_ADDR_STRLEN + 1/*'\0'*/ +
USERNAME_LENGTH + 1/*'\0'*/ +
NAME_LEN/*database*/;
/*
Let's reserve extra MY_CS_MBMAXLEN bytes in the buffer.
This is to catch cases when a too long database name gets truncated:
key.length() will return a length in the range:
[key_data_size + 1, key_data_size + MY_CS_MBMAXLEN].
*/
CharBuffer<key_data_size + MY_CS_MBMAXLEN> key;
key.append(Lex_cstring_strlen(safe_str(ip))).append_char('\0')
.append(Lex_cstring_strlen(user)).append_char('\0');
tmp_db= key.end();
key.append_opt_casedn(files_charset_info, Lex_cstring_strlen(db),
lower_case_table_names);
db= tmp_db;
if (end >= key + sizeof(key)) // db name was truncated if (key.length() > key_data_size) // db name was truncated
DBUG_RETURN(NO_ACL); // no privileges for an invalid db name DBUG_RETURN(NO_ACL); // no privileges for an invalid db name
if (lower_case_table_names)
{
my_casedn_str(files_charset_info, tmp_db);
db=tmp_db;
}
key_length= (size_t) (end-key);
mysql_mutex_lock(&acl_cache->lock); mysql_mutex_lock(&acl_cache->lock);
if (!db_is_pattern && (entry=acl_cache->search((uchar*) key, key_length))) if (!db_is_pattern &&
(entry= acl_cache->search((uchar*) key.ptr(), key.length())))
{ {
db_access=entry->access; db_access=entry->access;
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
@@ -3760,12 +3788,13 @@ exit:
/* Save entry in cache for quick retrieval */ /* Save entry in cache for quick retrieval */
if (!db_is_pattern && if (!db_is_pattern &&
(entry= (acl_entry*) my_malloc(key_memory_acl_cache, (entry= (acl_entry*) my_malloc(key_memory_acl_cache,
sizeof(acl_entry)+key_length, MYF(MY_WME)))) sizeof(acl_entry) + key.length(),
MYF(MY_WME))))
{ {
entry->access=(db_access & host_access); entry->access=(db_access & host_access);
DBUG_ASSERT(key_length < 0xffff); DBUG_ASSERT(key.length() < 0xffff);
entry->length=(uint16)key_length; entry->length= (uint16) key.length();
memcpy((uchar*) entry->key,key,key_length); memcpy((uchar*) entry->key, key.ptr(), key.length());
acl_cache->add(entry); acl_cache->add(entry);
} }
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
@@ -5472,17 +5501,21 @@ void GRANT_NAME::set_user_details(const char *h, const char *d,
update_hostname(&host, strdup_root(&grant_memroot, h)); update_hostname(&host, strdup_root(&grant_memroot, h));
if (db != d) if (db != d)
{ {
db= strdup_root(&grant_memroot, d); DBUG_ASSERT(d);
if (lower_case_table_names) db= lower_case_table_names ?
my_casedn_str(files_charset_info, db); lex_string_casedn_root(&grant_memroot, files_charset_info,
d, strlen(d)).str :
strdup_root(&grant_memroot, d);
} }
user = strdup_root(&grant_memroot,u); user = strdup_root(&grant_memroot,u);
sort= get_magic_sort("hdu", host.hostname, db, user); sort= get_magic_sort("hdu", host.hostname, db, user);
if (tname != t) if (tname != t)
{ {
tname= strdup_root(&grant_memroot, t); DBUG_ASSERT(t);
if (lower_case_table_names || is_routine) tname= lower_case_table_names || is_routine ?
my_casedn_str(files_charset_info, tname); lex_string_casedn_root(&grant_memroot, files_charset_info,
t, strlen(t)).str :
strdup_root(&grant_memroot, t);
} }
key_length= strlen(d) + strlen(u)+ strlen(t)+3; key_length= strlen(d) + strlen(u)+ strlen(t)+3;
hash_key= (char*) alloc_root(&grant_memroot,key_length); hash_key= (char*) alloc_root(&grant_memroot,key_length);
@@ -5529,11 +5562,15 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine)
sort= get_magic_sort("hdu", host.hostname, db, user); sort= get_magic_sort("hdu", host.hostname, db, user);
if (lower_case_table_names) if (lower_case_table_names)
{ {
my_casedn_str(files_charset_info, db); DBUG_ASSERT(db);
db= lex_string_casedn_root(&grant_memroot, files_charset_info,
db, strlen(db)).str;
} }
if (lower_case_table_names || is_routine) if (lower_case_table_names || is_routine)
{ {
my_casedn_str(files_charset_info, tname); DBUG_ASSERT(tname);
tname= lex_string_casedn_root(&grant_memroot, files_charset_info,
tname, strlen(tname)).str;
} }
key_length= (strlen(db) + strlen(user) + strlen(tname) + 3); key_length= (strlen(db) + strlen(user) + strlen(tname) + 3);
hash_key= (char*) alloc_root(&grant_memroot, key_length); hash_key= (char*) alloc_root(&grant_memroot, key_length);
@@ -5657,28 +5694,25 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
const char *user, const char *tname, const char *user, const char *tname,
bool exact, bool name_tolower) bool exact, bool name_tolower)
{ {
char helping[SAFE_NAME_LEN*2+USERNAME_LENGTH+3]; constexpr size_t key_data_size= SAFE_NAME_LEN * 2 + USERNAME_LENGTH + 1;
char *hend = helping + sizeof(helping); // See earlier comments on MY_CS_MBMAXLEN above
uint len; CharBuffer<key_data_size + MY_CS_MBMAXLEN> key;
GRANT_NAME *grant_name,*found=0; GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state; HASH_SEARCH_STATE state;
char *db_ptr= strmov(helping, user) + 1; key.append(Lex_cstring_strlen(user)).append_char('\0')
char *tname_ptr= strnmov(db_ptr, db, hend - db_ptr) + 1; .append(Lex_cstring_strlen(db)).append_char('\0')
if (tname_ptr > hend) .append_opt_casedn(files_charset_info, Lex_cstring_strlen(tname),
return 0; // invalid name = not found name_tolower);
char *end= strnmov(tname_ptr, tname, hend - tname_ptr) + 1; key.append_char('\0');
if (end > hend) if (key.length() > key_data_size)
return 0; // invalid name = not found return 0; // invalid name = not found
len = (uint) (end - helping); for (grant_name= (GRANT_NAME*) my_hash_first(name_hash, (uchar*) key.ptr(),
if (name_tolower) key.length(), &state);
my_casedn_str(files_charset_info, tname_ptr);
for (grant_name= (GRANT_NAME*) my_hash_first(name_hash, (uchar*) helping,
len, &state);
grant_name ; grant_name ;
grant_name= (GRANT_NAME*) my_hash_next(name_hash,(uchar*) helping, grant_name= (GRANT_NAME*) my_hash_next(name_hash, (uchar*) key.ptr(),
len, &state)) key.length(), &state))
{ {
if (exact) if (exact)
{ {
@@ -8848,33 +8882,28 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
bool check_grant_db(THD *thd, const char *db) bool check_grant_db(THD *thd, const char *db)
{ {
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2], *end; constexpr size_t key_data_size= SAFE_NAME_LEN + USERNAME_LENGTH + 1;
char helping2 [SAFE_NAME_LEN + USERNAME_LENGTH+2], *tmp_db; // See earlier comments on MY_CS_MBMAXLEN above
uint len, UNINIT_VAR(len2); CharBuffer<key_data_size + MY_CS_MBMAXLEN> key, key2;
bool error= TRUE; bool error= TRUE;
tmp_db= strmov(helping, sctx->priv_user) + 1; key.append(Lex_cstring_strlen(sctx->priv_user)).append_char('\0')
end= strnmov(tmp_db, db, helping + sizeof(helping) - tmp_db); .append_opt_casedn(files_charset_info, Lex_cstring_strlen(db),
lower_case_table_names)
.append_char('\0');
if (end >= helping + sizeof(helping)) // db name was truncated if (key.length() > key_data_size) // db name was truncated
return 1; // no privileges for an invalid db name return 1; // no privileges for an invalid db name
if (lower_case_table_names)
{
end = tmp_db + my_casedn_str(files_charset_info, tmp_db);
db=tmp_db;
}
len= (uint) (end - helping) + 1;
/* /*
If a role is set, we need to check for privileges here as well. If a role is set, we need to check for privileges here as well.
*/ */
if (sctx->priv_role[0]) if (sctx->priv_role[0])
{ {
end= strmov(helping2, sctx->priv_role) + 1; key2.append(Lex_cstring_strlen(sctx->priv_role)).append_char('\0')
end= strnmov(end, db, helping2 + sizeof(helping2) - end); .append_opt_casedn(files_charset_info, Lex_cstring_strlen(db),
len2= (uint) (end - helping2) + 1; lower_case_table_names)
.append_char('\0');
} }
@@ -8884,16 +8913,16 @@ bool check_grant_db(THD *thd, const char *db)
{ {
GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash, GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash,
idx); idx);
if (len < grant_table->key_length && if (key.length() < grant_table->key_length &&
!memcmp(grant_table->hash_key, helping, len) && !memcmp(grant_table->hash_key, key.ptr(), key.length()) &&
compare_hostname(&grant_table->host, sctx->host, sctx->ip)) compare_hostname(&grant_table->host, sctx->host, sctx->ip))
{ {
error= FALSE; /* Found match. */ error= FALSE; /* Found match. */
break; break;
} }
if (sctx->priv_role[0] && if (sctx->priv_role[0] &&
len2 < grant_table->key_length && key2.length() < grant_table->key_length &&
!memcmp(grant_table->hash_key, helping2, len2) && !memcmp(grant_table->hash_key, key2.ptr(), key2.length()) &&
(!grant_table->host.hostname || !grant_table->host.hostname[0])) (!grant_table->host.hostname || !grant_table->host.hostname[0]))
{ {
error= FALSE; /* Found role match */ error= FALSE; /* Found role match */

View File

@@ -424,16 +424,15 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
if (lower_case_table_names == 1) // Convert new_name/new_alias to lower if (lower_case_table_names == 1) // Convert new_name/new_alias to lower
{ {
new_name.length= my_casedn_str(files_charset_info, (char*) new_name.str); new_name= new_name_buff.copy_casedn(files_charset_info, new_name).
to_lex_cstring();
new_alias= new_name; new_alias= new_name;
} }
else if (lower_case_table_names == 2) // Convert new_name to lower case else if (lower_case_table_names == 2) // Convert new_name to lower case
{ {
new_alias.str= new_alias_buff; new_alias= new_name;
new_alias.length= new_name.length; new_name= new_name_buff.copy_casedn(files_charset_info, new_name).
strmov(new_alias_buff, new_name.str); to_lex_cstring();
new_name.length= my_casedn_str(files_charset_info, (char*) new_name.str);
} }
else else
new_alias= new_name; // LCTN=0 => case sensitive + case preserving new_alias= new_name; // LCTN=0 => case sensitive + case preserving
@@ -461,7 +460,10 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list,
tmp_file_prefix, current_pid, thd->thread_id); tmp_file_prefix, current_pid, thd->thread_id);
/* Safety fix for InnoDB */ /* Safety fix for InnoDB */
if (lower_case_table_names) if (lower_case_table_names)
tmp_name.length= my_casedn_str(files_charset_info, tmp_name_buff); {
// Ok to latin1, as the file name is in the form '#sql-alter-abc-def'
tmp_name.length= my_casedn_str_latin1(tmp_name_buff);
}
if (table_list->table->s->tmp_table == NO_TMP_TABLE) if (table_list->table->s->tmp_table == NO_TMP_TABLE)
{ {

View File

@@ -437,7 +437,7 @@ public:
private: private:
char new_filename[FN_REFLEN + 1]; char new_filename[FN_REFLEN + 1];
char new_alias_buff[NAME_LEN + 1]; CharBuffer<NAME_LEN> new_name_buff;
char tmp_name_buff[NAME_LEN + 1]; char tmp_name_buff[NAME_LEN + 1];
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
char new_path[FN_REFLEN + 1]; char new_path[FN_REFLEN + 1];

View File

@@ -4039,26 +4039,27 @@ Query_arena::Type Statement::type() const
/* /*
Return an internal database name: Return a valid database name:
- validated with Lex_ident_db::check_db_name() - validated with Lex_ident_db::check_db_name()
- optionally converted to lower-case when lower_case_table_names==1 - optionally converted to lower-case
The lower-cased copy is made on mem_root when needed. The lower-cased copy is made on mem_root when needed.
An error is raised in case of EOM or a bad database name. An error is raised in case of EOM or a bad database name.
@param src - the database name @param src - the database name
@param casedn - if the name should be lower-cased
@returns - {NULL,0} on EOM or a bad database name, @returns - {NULL,0} on EOM or a bad database name,
or a good database name otherwise or a good database name otherwise
*/ */
Lex_ident_db Lex_ident_db
Query_arena::to_ident_db_internal_with_error(const LEX_CSTRING &src) Query_arena::to_ident_db_opt_casedn_with_error(const LEX_CSTRING &src,
bool casedn)
{ {
DBUG_ASSERT(src.str); DBUG_ASSERT(src.str);
if (src.str == any_db.str) // e.g. JSON table if (src.str == any_db.str) // e.g. JSON table
return any_db; // preserve any_db - it has a special meaning return any_db; // preserve any_db - it has a special meaning
bool casedn= lower_case_table_names == 1;
const LEX_CSTRING tmp= casedn ? make_ident_casedn(src) : src; const LEX_CSTRING tmp= casedn ? make_ident_casedn(src) : src;
if (!tmp.str /*EOM*/ || if (!tmp.str /*EOM*/ ||
Lex_ident_fs(tmp).check_db_name_with_error()) Lex_ident_fs(tmp).check_db_name_with_error())

View File

@@ -1287,13 +1287,17 @@ public:
Methods to copy a string to the memory root Methods to copy a string to the memory root
and return the value as a LEX_CSTRING. and return the value as a LEX_CSTRING.
*/ */
LEX_CSTRING strmake_lex_cstring(const char *str, size_t length) const LEX_STRING strmake_lex_string(const char *str, size_t length) const
{ {
const char *tmp= strmake_root(mem_root, str, length); char *tmp= strmake_root(mem_root, str, length);
if (!tmp) if (!tmp)
return {0,0}; return {0,0};
return {tmp, length}; return {tmp, length};
} }
LEX_CSTRING strmake_lex_cstring(const char *str, size_t length) const
{
return strmake_lex_string(str, length);
}
LEX_CSTRING strmake_lex_cstring(const LEX_CSTRING &from) const LEX_CSTRING strmake_lex_cstring(const LEX_CSTRING &from) const
{ {
return strmake_lex_cstring(from.str, from.length); return strmake_lex_cstring(from.str, from.length);
@@ -1415,6 +1419,21 @@ public:
lex_string_strmake_root(mem_root, src.str, src.length); lex_string_strmake_root(mem_root, src.str, src.length);
} }
/*
Convert a LEX_CSTRING to a valid database name:
- validated with Lex_ident_fs::check_db_name()
- optionally lower-cased
The lower-cased copy is created on Query_arena::mem_root, when needed.
@param name - The name to normalize. Must not be {NULL,0}.
@param casedn - If the name should be lower-cased.
@return - {NULL,0} on EOM or a bad database name
(with an errror is raised,
or a good database name otherwise.
*/
Lex_ident_db to_ident_db_opt_casedn_with_error(const LEX_CSTRING &name,
bool casedn);
/* /*
Convert a LEX_CSTRING to a valid internal database name: Convert a LEX_CSTRING to a valid internal database name:
- validated with Lex_ident_fs::check_db_name() - validated with Lex_ident_fs::check_db_name()
@@ -1426,7 +1445,29 @@ public:
(with an errror is raised, (with an errror is raised,
or a good database name otherwise. or a good database name otherwise.
*/ */
Lex_ident_db to_ident_db_internal_with_error(const LEX_CSTRING &name); Lex_ident_db to_ident_db_internal_with_error(const LEX_CSTRING &name)
{
return to_ident_db_opt_casedn_with_error(name, lower_case_table_names == 1);
}
/*
Convert a LEX_CSTRING to a valid normalized database name:
- validated with Lex_ident_fs::check_db_name()
- optionally lower-cased when lower_case_table_names>0
The lower-cased copy is created on Query_arena::mem_root, when needed.
@param name - The name to normalize. Must not be {NULL,0}.
@return - {NULL,0} on EOM or a bad database name
(with an errror is raised,
or a good database name otherwise.
*/
Lex_ident_db_normalized to_ident_db_normalized_with_error(
const LEX_CSTRING &name)
{
Lex_ident_db tmp= to_ident_db_opt_casedn_with_error(name,
lower_case_table_names > 0);
return Lex_ident_db_normalized(tmp);
}
void set_query_arena(Query_arena *set); void set_query_arena(Query_arena *set);
@@ -4927,14 +4968,7 @@ public:
/** Set the current database, without copying */ /** Set the current database, without copying */
void reset_db(const LEX_CSTRING *new_db); void reset_db(const LEX_CSTRING *new_db);
/* bool check_if_current_db_is_set_with_error() const
Copy the current database to the argument. Use the current arena to
allocate memory for a deep copy: current database may be freed after
a statement is parsed but before it's executed.
Can only be called by owner of thd (no mutex protection)
*/
bool copy_db_to(LEX_CSTRING *to)
{ {
if (db.str == NULL) if (db.str == NULL)
{ {
@@ -4950,11 +4984,46 @@ public:
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
return TRUE; return TRUE;
} }
return false;
}
/*
Copy the current database to the argument. Use the current arena to
allocate memory for a deep copy: current database may be freed after
a statement is parsed but before it's executed.
Can only be called by owner of thd (no mutex protection)
*/
bool copy_db_to(LEX_CSTRING *to)
{
if (check_if_current_db_is_set_with_error())
return true;
to->str= strmake(db.str, db.length); to->str= strmake(db.str, db.length);
to->length= db.length; to->length= db.length;
return to->str == NULL; /* True on error */ return to->str == NULL; /* True on error */
} }
/*
Make a normalized copy of the current database.
Raise an error if no current database is set.
Note, in case of lower_case_table_names==2, thd->db can contain the
name in arbitrary case typed by the user, so it must be lower-cased.
For other lower_case_table_names values the name is already in
its normalized case, so it's copied as is.
*/
Lex_ident_db_normalized copy_db_normalized()
{
if (check_if_current_db_is_set_with_error())
return Lex_ident_db_normalized();
LEX_CSTRING ident= make_ident_opt_casedn(db, lower_case_table_names == 2);
/*
A non-empty thd->db is always known to satisfy check_db_name().
So after optional lower-casing above it's safe to
make Lex_ident_db_normalized.
*/
return Lex_ident_db_normalized(ident);
}
/* Get db name or "". Use for printing current db */ /* Get db name or "". Use for printing current db */
const char *get_db() const char *get_db()
{ return safe_str(db.str); } { return safe_str(db.str); }
@@ -7233,7 +7302,7 @@ public:
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 */ /* We must have a table name here as this is used with add_table_to_list */
db.str= empty_c_string; /* a subject to casedn_str */ db.str= empty_c_string;
db.length= 0; db.length= 0;
table.str= internal_table_name; table.str= internal_table_name;
table.length=1; table.length=1;
@@ -8021,66 +8090,6 @@ public:
}; };
class Identifier_chain2
{
LEX_CSTRING m_name[2];
public:
Identifier_chain2()
:m_name{Lex_cstring(), Lex_cstring()}
{ }
Identifier_chain2(const LEX_CSTRING &a, const LEX_CSTRING &b)
:m_name{a, b}
{ }
const LEX_CSTRING& operator [] (size_t i) const
{
return m_name[i];
}
static Identifier_chain2 split(const LEX_CSTRING &txt)
{
DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input
const char *dot= strchr(txt.str, '.');
if (!dot)
return Identifier_chain2(Lex_cstring(), txt);
size_t length0= dot - txt.str;
Lex_cstring name0(txt.str, length0);
Lex_cstring name1(txt.str + length0 + 1, txt.length - length0 - 1);
return Identifier_chain2(name0, name1);
}
// Export as a qualified name string: 'db.name'
size_t make_qname(char *dst, size_t dstlen, bool casedn_part1) const
{
size_t res= my_snprintf(dst, dstlen, "%.*s.%.*s",
(int) m_name[0].length, m_name[0].str,
(int) m_name[1].length, m_name[1].str);
if (casedn_part1 && dstlen > m_name[0].length)
my_casedn_str(system_charset_info, dst + m_name[0].length + 1);
return res;
}
// Export as a qualified name string, allocate on mem_root.
LEX_CSTRING make_qname(MEM_ROOT *mem_root, bool casedn_part1) const
{
LEX_STRING dst;
/* format: [pkg + dot] + name + '\0' */
size_t dst_size= m_name[0].length + 1 /*dot*/ + m_name[1].length + 1/*\0*/;
if (unlikely(!(dst.str= (char*) alloc_root(mem_root, dst_size))))
return {NULL, 0};
if (!m_name[0].length)
{
DBUG_ASSERT(!casedn_part1); // Should not be called this way
dst.length= my_snprintf(dst.str, dst_size, "%.*s",
(int) m_name[1].length, m_name[1].str);
return {dst.str, dst.length};
}
dst.length= make_qname(dst.str, dst_size, casedn_part1);
return {dst.str, dst.length};
}
};
/** /**
This class resembles the SQL Standard schema qualified object name: This class resembles the SQL Standard schema qualified object name:
<schema qualified name> ::= [ <schema name> <period> ] <qualified identifier> <schema qualified name> ::= [ <schema name> <period> ] <qualified identifier>
@@ -8105,6 +8114,11 @@ public:
m_name.length= name_length; m_name.length= name_length;
} }
Identifier_chain2 to_identifier_chain2() const
{
return Identifier_chain2(m_db, m_name);
}
bool eq(const Database_qualified_name *other) const bool eq(const Database_qualified_name *other) const
{ {
CHARSET_INFO *cs= lower_case_table_names ? CHARSET_INFO *cs= lower_case_table_names ?
@@ -8126,17 +8140,6 @@ public:
bool copy_sp_name_internal(MEM_ROOT *mem_root, const LEX_CSTRING &db, bool copy_sp_name_internal(MEM_ROOT *mem_root, const LEX_CSTRING &db,
const LEX_CSTRING &name); const LEX_CSTRING &name);
// Export db and name as a qualified name string: 'db.name'
size_t make_qname(char *dst, size_t dstlen, bool casedn_name) const
{
return Identifier_chain2(m_db, m_name).make_qname(dst, dstlen, casedn_name);
}
// Export db and name as a qualified name string, allocate on mem_root.
LEX_CSTRING make_qname(MEM_ROOT *mem_root, bool casedn_name) const
{
return Identifier_chain2(m_db, m_name).make_qname(mem_root, casedn_name);
}
bool make_package_routine_name(MEM_ROOT *mem_root, bool make_package_routine_name(MEM_ROOT *mem_root,
const LEX_CSTRING &package, const LEX_CSTRING &package,
const LEX_CSTRING &routine) const LEX_CSTRING &routine)
@@ -8145,8 +8148,7 @@ public:
size_t length= package.length + 1 + routine.length + 1; size_t length= package.length + 1 + routine.length + 1;
if (unlikely(!(tmp= (char *) alloc_root(mem_root, length)))) if (unlikely(!(tmp= (char *) alloc_root(mem_root, length))))
return true; return true;
m_name.length= Identifier_chain2(package, routine).make_qname(tmp, length, m_name.length= Identifier_chain2(package, routine).make_qname(tmp, length);
false);
m_name.str= tmp; m_name.str= tmp;
return false; return false;
} }
@@ -8175,7 +8177,8 @@ public:
{ } { }
LEX_CSTRING lex_cstring() const override LEX_CSTRING lex_cstring() const override
{ {
size_t length= m_name->make_qname(err_buffer, sizeof(err_buffer), false); size_t length= m_name->to_identifier_chain2().make_qname(err_buffer,
sizeof(err_buffer));
return {err_buffer, length}; return {err_buffer, length};
} }
}; };

View File

@@ -1340,17 +1340,16 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
if (!table_list) if (!table_list)
DBUG_RETURN(true); DBUG_RETURN(true);
table_list->db= db; table_list->db= db;
table_list->table_name= *table;
table_list->open_type= OT_BASE_ONLY;
/* /*
On the case-insensitive file systems table is opened On the case-insensitive file systems table is opened
with the lowercased file name. So we should lowercase with the lowercased file name. So we should lowercase
as well to look up the cache properly. as well to look up the cache properly.
*/ */
if (lower_case_file_system) table_list->table_name= lower_case_file_system ?
table_list->table_name.length= my_casedn_str(files_charset_info, thd->make_ident_casedn(*table) :
(char*) table_list->table_name.str); *table;
table_list->open_type= OT_BASE_ONLY;
table_list->alias= table_list->table_name; // If lower_case_table_names=2 table_list->alias= table_list->table_name; // If lower_case_table_names=2
MDL_REQUEST_INIT(&table_list->mdl_request, MDL_key::TABLE, MDL_REQUEST_INIT(&table_list->mdl_request, MDL_key::TABLE,

View File

@@ -4279,7 +4279,8 @@ bool LEX::copy_db_to(LEX_CSTRING *to)
{ {
if (sphead && sphead->m_name.str) if (sphead && sphead->m_name.str)
{ {
DBUG_ASSERT(sphead->m_db.str && sphead->m_db.length); DBUG_ASSERT(sphead->m_db.str);
DBUG_ASSERT(sphead->m_db.length);
/* /*
It is safe to assign the string by-pointer, both sphead and It is safe to assign the string by-pointer, both sphead and
its statements reside in the same memory root. its statements reside in the same memory root.
@@ -4290,6 +4291,19 @@ bool LEX::copy_db_to(LEX_CSTRING *to)
return thd->copy_db_to(to); return thd->copy_db_to(to);
} }
Lex_ident_db_normalized LEX::copy_db_normalized()
{
if (sphead && sphead->m_name.str)
{
DBUG_ASSERT(sphead->m_db.str);
DBUG_ASSERT(sphead->m_db.length);
return thd->to_ident_db_normalized_with_error(sphead->m_db);
}
return thd->copy_db_normalized();
}
/** /**
Initialize offset and limit counters. Initialize offset and limit counters.
@@ -7431,10 +7445,10 @@ bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name) sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name)
{ {
sp_name *res; sp_name *res;
LEX_CSTRING db; Lex_ident_db_normalized db;
if (unlikely(check_routine_name(&name)) || if (unlikely(check_routine_name(&name)) ||
unlikely(copy_db_to(&db)) || unlikely(!(db= copy_db_normalized()).str) ||
unlikely((!(res= new (thd->mem_root) sp_name(&db, &name, false))))) unlikely((!(res= new (thd->mem_root) sp_name(db, name, false)))))
return NULL; return NULL;
return res; return res;
} }
@@ -7471,10 +7485,11 @@ sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name1,
{ {
DBUG_ASSERT(name1.str); DBUG_ASSERT(name1.str);
sp_name *res; sp_name *res;
const Lex_ident_db norm_name1= thd->to_ident_db_internal_with_error(name1); const Lex_ident_db_normalized norm_name1=
thd->to_ident_db_normalized_with_error(name1);
if (unlikely(!norm_name1.str) || if (unlikely(!norm_name1.str) ||
unlikely(check_routine_name(&name2)) || unlikely(check_routine_name(&name2)) ||
unlikely(!(res= new (thd->mem_root) sp_name(&norm_name1, &name2, true)))) unlikely(!(res= new (thd->mem_root) sp_name(norm_name1, name2, true))))
return NULL; return NULL;
return res; return res;
} }
@@ -7530,7 +7545,9 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
name->m_name); name->m_name);
else else
sp->init_sp_name(name); sp->init_sp_name(name);
if (!(sp->m_qname= sp->make_qname(sp->get_main_mem_root(), true)).str) if (!(sp->m_qname=
sp->to_identifier_chain2().
make_qname_casedn_part1(sp->get_main_mem_root())).str)
return NULL; return NULL;
} }
sphead= sp; sphead= sp;
@@ -9432,17 +9449,17 @@ bool LEX::call_statement_start(THD *thd,
sql_command= SQLCOM_CALL; sql_command= SQLCOM_CALL;
const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(*db); const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(*db);
if (!db_int.str || if (!dbn.str ||
check_routine_name(pkg) || check_routine_name(pkg) ||
check_routine_name(proc)) check_routine_name(proc))
return true; return true;
// Concat `pkg` and `name` to `pkg.name` // Concat `pkg` and `name` to `pkg.name`
LEX_CSTRING pkg_dot_proc; LEX_CSTRING pkg_dot_proc;
if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root, false)).str || if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root)).str ||
check_ident_length(&pkg_dot_proc) || check_ident_length(&pkg_dot_proc) ||
!(spname= new (thd->mem_root) sp_name(&db_int, &pkg_dot_proc, true))) !(spname= new (thd->mem_root) sp_name(dbn, pkg_dot_proc, true)))
return true; return true;
sp_handler_package_function.add_used_routine(thd->lex, thd, spname); sp_handler_package_function.add_used_routine(thd->lex, thd, spname);
@@ -9507,7 +9524,8 @@ sp_package *LEX::create_package_start(THD *thd,
return NULL; return NULL;
pkg->reset_thd_mem_root(thd); pkg->reset_thd_mem_root(thd);
pkg->init(this); pkg->init(this);
if (!(pkg->m_qname= pkg->make_qname(pkg->get_main_mem_root(), true)).str) if (!(pkg->m_qname= pkg->to_identifier_chain2().
make_qname_casedn_part1(pkg->get_main_mem_root())).str)
return NULL; return NULL;
pkg->set_c_chistics(chistics); pkg->set_c_chistics(chistics);
sphead= pkg; sphead= pkg;
@@ -9801,12 +9819,7 @@ Item *LEX::make_item_func_call_generic(THD *thd,
- MySQL.version() is the SQL 2003 syntax for the native function - MySQL.version() is the SQL 2003 syntax for the native function
version() (a vendor can specify any schema). version() (a vendor can specify any schema).
*/ */
return make_item_func_call_generic(thd, db, name, args);
const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db);
if (!db_int.str || check_routine_name(&name))
return NULL;
return make_item_func_call_generic(thd, Lex_ident_sys(db_int.str, db_int.length), name, args);
} }
@@ -9821,7 +9834,12 @@ Item *LEX::make_item_func_call_generic(THD *thd,
Create_qfunc *builder= find_qualified_function_builder(thd); Create_qfunc *builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder); DBUG_ASSERT(builder);
return builder->create_with_db(thd, &db, &name, true, args);
const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(db);
if (!dbn.str || check_routine_name(&name))
return NULL;
return builder->create_with_db(thd, dbn, name, true, args);
} }
@@ -9845,17 +9863,17 @@ Item *LEX::make_item_func_call_generic(THD *thd,
if (db.is_null() || pkg.is_null() || func.is_null()) if (db.is_null() || pkg.is_null() || func.is_null())
return NULL; // EOM return NULL; // EOM
const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db); const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(db);
if (!db_int.str || if (!dbn.str ||
check_routine_name(&pkg) || check_routine_name(&pkg) ||
check_routine_name(&func)) check_routine_name(&func))
return NULL; return NULL;
// Concat `pkg` and `name` to `pkg.name` // Concat `pkg` and `name` to `pkg.name`
LEX_CSTRING pkg_dot_func; LEX_CSTRING pkg_dot_func;
if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root, false)).str || if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root)).str ||
check_ident_length(&pkg_dot_func) || check_ident_length(&pkg_dot_func) ||
!(qname= new (thd->mem_root) sp_name(&db_int, &pkg_dot_func, true))) !(qname= new (thd->mem_root) sp_name(dbn, pkg_dot_func, true)))
return NULL; return NULL;
sp_handler_package_function.add_used_routine(thd->lex, thd, qname); sp_handler_package_function.add_used_routine(thd->lex, thd, qname);
@@ -11838,11 +11856,11 @@ bool LEX::stmt_drop_routine(const Sp_handler *sph,
if (check_routine_name(&name)) if (check_routine_name(&name))
return true; return true;
enum_sql_command sqlcom= sph->sqlcom_drop(); enum_sql_command sqlcom= sph->sqlcom_drop();
LEX_CSTRING db_int= {0, 0}; Lex_ident_db_normalized dbn;
if (db.str) if (db.str)
{ {
// An explicit database name is given // An explicit database name is given
if (!(db_int= thd->to_ident_db_internal_with_error(db)).str) if (!(dbn= thd->to_ident_db_normalized_with_error(db)).str)
return true; return true;
} }
else if (thd->db.str || sqlcom != SQLCOM_DROP_FUNCTION) else if (thd->db.str || sqlcom != SQLCOM_DROP_FUNCTION)
@@ -11856,9 +11874,9 @@ bool LEX::stmt_drop_routine(const Sp_handler *sph,
- DROP PACKAGE - DROP PACKAGE
- DROP PACKAGE BODY - DROP PACKAGE BODY
- DROP PROCEDURE - DROP PROCEDURE
copy_db_to() raises ER_NO_DB_ERROR. copy_db_normalized() raises ER_NO_DB_ERROR.
*/ */
if (copy_db_to(&db_int)) if (!(dbn= copy_db_normalized()).str)
return true; return true;
} }
else else
@@ -11868,11 +11886,11 @@ bool LEX::stmt_drop_routine(const Sp_handler *sph,
There is no an explicit database name given. There is no an explicit database name given.
The current database is not set. The current database is not set.
It can still be a valid DROP FUNCTION - for an UDF. It can still be a valid DROP FUNCTION - for an UDF.
Keep db_int=={NULL,0}. Keep dbn=={NULL,0}.
*/ */
} }
set_command(sqlcom, options); set_command(sqlcom, options);
spname= new (thd->mem_root) sp_name(&db_int, &name, db.str != NULL); spname= new (thd->mem_root) sp_name(dbn, name, db.str != NULL);
return false; return false;
} }

View File

@@ -3826,6 +3826,7 @@ public:
} }
bool copy_db_to(LEX_CSTRING *to); bool copy_db_to(LEX_CSTRING *to);
Lex_ident_db_normalized copy_db_normalized();
void inc_select_stack_outer_barrier() void inc_select_stack_outer_barrier()
{ {

View File

@@ -126,7 +126,7 @@ static int show_create_db(THD *thd, LEX *lex);
static bool alter_routine(THD *thd, LEX *lex); static bool alter_routine(THD *thd, LEX *lex);
static bool drop_routine(THD *thd, LEX *lex); static bool drop_routine(THD *thd, LEX *lex);
const Lex_ident_db any_db(STRING_WITH_LEN("*any*")); const Lex_ident_db_normalized any_db(STRING_WITH_LEN("*any*"));
const LEX_CSTRING command_name[257]={ const LEX_CSTRING command_name[257]={
{ STRING_WITH_LEN("Sleep") }, //0 { STRING_WITH_LEN("Sleep") }, //0
@@ -2045,8 +2045,8 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD *
/* Must be before we init the table list. */ /* Must be before we init the table list. */
if (lower_case_table_names) if (lower_case_table_names)
{ {
table_name.length= my_casedn_str(files_charset_info, table_name.str); table_name= thd->make_ident_casedn(table_name);
db.length= my_casedn_str(files_charset_info, (char*) db.str); db= thd->make_ident_casedn(db);
} }
table_list.init_one_table(&db, (LEX_CSTRING*) &table_name, 0, TL_READ); table_list.init_one_table(&db, (LEX_CSTRING*) &table_name, 0, TL_READ);
/* /*

View File

@@ -129,7 +129,7 @@ bool check_stack_overrun(THD *thd, long margin, uchar *dummy);
/* Variables */ /* Variables */
extern const Lex_ident_db any_db; extern const Lex_ident_db_normalized any_db;
extern uint sql_command_flags[]; extern uint sql_command_flags[];
extern uint server_command_flags[]; extern uint server_command_flags[];
extern const LEX_CSTRING command_name[]; extern const LEX_CSTRING command_name[];

View File

@@ -657,7 +657,10 @@ bool Sql_cmd_alter_table_exchange_partition::
my_snprintf(temp_name, sizeof(temp_name), "%s-exchange-%lx-%llx", my_snprintf(temp_name, sizeof(temp_name), "%s-exchange-%lx-%llx",
tmp_file_prefix, current_pid, thd->thread_id); tmp_file_prefix, current_pid, thd->thread_id);
if (lower_case_table_names) if (lower_case_table_names)
my_casedn_str(files_charset_info, temp_name); {
// Ok to use latin1 as the file name is in the form '#sql-exchange-abc-def'
my_casedn_str_latin1(temp_name);
}
build_table_filename(temp_file_name, sizeof(temp_file_name), build_table_filename(temp_file_name, sizeof(temp_file_name),
table_list->next_local->db.str, table_list->next_local->db.str,
temp_name, "", FN_IS_TMP); temp_name, "", FN_IS_TMP);

View File

@@ -3865,7 +3865,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1); plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1);
strcpy(plugin_name_ptr, plugin_name); strcpy(plugin_name_ptr, plugin_name);
my_casedn_str(&my_charset_latin1, plugin_name_ptr); my_casedn_str_latin1(plugin_name_ptr); // Plugin names are pure ASCII
convert_underscore_to_dash(plugin_name_ptr, plugin_name_len); convert_underscore_to_dash(plugin_name_ptr, plugin_name_len);
plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root, plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root,
plugin_name_len + plugin_name_len +
@@ -4234,7 +4234,8 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
len= tmp->name.length + strlen(o->name) + 2; len= tmp->name.length + strlen(o->name) + 2;
varname= (char*) alloc_root(mem_root, len); varname= (char*) alloc_root(mem_root, len);
strxmov(varname, tmp->name.str, "-", o->name, NullS); strxmov(varname, tmp->name.str, "-", o->name, NullS);
my_casedn_str(&my_charset_latin1, varname); // Ok to use latin1, as the variable name is pure ASCII
my_casedn_str_latin1(varname);
convert_dash_to_underscore(varname, len-1); convert_dash_to_underscore(varname, len-1);
} }
if (o->flags & PLUGIN_VAR_NOSYSVAR) if (o->flags & PLUGIN_VAR_NOSYSVAR)

View File

@@ -3831,24 +3831,27 @@ static bool show_status_array(THD *thd, const char *wild,
SHOW_VAR *variables, SHOW_VAR *variables,
enum enum_var_type scope, enum enum_var_type scope,
struct system_status_var *status_var, struct system_status_var *status_var,
const char *prefix, TABLE *table, const LEX_CSTRING &prefix, TABLE *table,
bool ucase_names, bool ucase_names,
COND *cond) COND *cond)
{ {
my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer; my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer;
char * const buff= buffer.data; char * const buff= buffer.data;
char *prefix_end; CharBuffer<NAME_CHAR_LEN> name_buffer;
char name_buffer[NAME_CHAR_LEN];
int len;
SHOW_VAR tmp, *var; SHOW_VAR tmp, *var;
bool res= FALSE; bool res= FALSE;
CHARSET_INFO *charset= system_charset_info; CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array"); DBUG_ENTER("show_status_array");
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1); if (prefix.length)
if (*prefix) {
*prefix_end++= '_'; if (ucase_names)
len=(int)(name_buffer + sizeof(name_buffer) - prefix_end); name_buffer.copy_caseup(system_charset_info, prefix);
else
name_buffer.copy_casedn(system_charset_info, prefix);
name_buffer.append(Lex_cstring("_", 1));
}
size_t prefix_length= name_buffer.length();
#ifdef WITH_WSREP #ifdef WITH_WSREP
bool is_wsrep_var= FALSE; bool is_wsrep_var= FALSE;
@@ -3858,7 +3861,7 @@ static bool show_status_array(THD *thd, const char *wild,
for status variables defined under wsrep plugin. for status variables defined under wsrep plugin.
TODO: remove once lp:1306875 has been addressed. TODO: remove once lp:1306875 has been addressed.
*/ */
if (*prefix && !my_strcasecmp(system_charset_info, prefix, "wsrep")) if (prefix.length && !my_strcasecmp(system_charset_info, prefix.str, "wsrep"))
{ {
is_wsrep_var= TRUE; is_wsrep_var= TRUE;
} }
@@ -3867,8 +3870,8 @@ static bool show_status_array(THD *thd, const char *wild,
for (; variables->name; variables++) for (; variables->name; variables++)
{ {
bool wild_checked= false; bool wild_checked= false;
strnmov(prefix_end, variables->name, len); Lex_cstring_strlen var_name(variables->name);
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ name_buffer.truncate(prefix_length);
#ifdef WITH_WSREP #ifdef WITH_WSREP
/* /*
@@ -3877,30 +3880,31 @@ static bool show_status_array(THD *thd, const char *wild,
names until lp:1306875 has been fixed. names until lp:1306875 has been fixed.
TODO: remove once lp:1306875 has been addressed. TODO: remove once lp:1306875 has been addressed.
*/ */
if (!(*prefix) && !strncasecmp(name_buffer, "wsrep", strlen("wsrep"))) if (!prefix.length &&
!strncasecmp(name_buffer.ptr(), "wsrep", strlen("wsrep")))
{ {
is_wsrep_var= TRUE; is_wsrep_var= TRUE;
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (ucase_names) if (ucase_names)
my_caseup_str(system_charset_info, name_buffer); name_buffer.append_caseup(system_charset_info, var_name);
else else
{ {
my_casedn_str(system_charset_info, name_buffer); name_buffer.append_casedn(system_charset_info, var_name);
DBUG_ASSERT(name_buffer[0] >= 'a');
DBUG_ASSERT(name_buffer[0] <= 'z');
// WSREP_TODO: remove once lp:1306875 has been addressed. // WSREP_TODO: remove once lp:1306875 has been addressed.
if (IF_WSREP(is_wsrep_var == FALSE, 1) && if (IF_WSREP(is_wsrep_var == FALSE, 1) &&
status_var) status_var)
name_buffer[0]-= 'a' - 'A'; {
char *ptr= (char*) name_buffer.ptr();
if (ptr[0] >= 'a' && ptr[0] <= 'z')
ptr[0]-= 'a' - 'A';
}
} }
restore_record(table, s->default_values); restore_record(table, s->default_values);
table->field[0]->store(name_buffer, strlen(name_buffer), table->field[0]->store(name_buffer.to_lex_cstring(), system_charset_info);
system_charset_info);
/* /*
Compare name for types that can't return arrays. We do this to not Compare name for types that can't return arrays. We do this to not
@@ -3909,7 +3913,7 @@ static bool show_status_array(THD *thd, const char *wild,
if ((variables->type != SHOW_FUNC && variables->type != SHOW_ARRAY)) if ((variables->type != SHOW_FUNC && variables->type != SHOW_ARRAY))
{ {
if (wild && wild[0] && wild_case_compare(system_charset_info, if (wild && wild[0] && wild_case_compare(system_charset_info,
name_buffer, wild)) name_buffer.ptr(), wild))
continue; continue;
wild_checked= 1; // Avoid checking it again wild_checked= 1; // Avoid checking it again
} }
@@ -3927,13 +3931,15 @@ static bool show_status_array(THD *thd, const char *wild,
if (show_type == SHOW_ARRAY) if (show_type == SHOW_ARRAY)
{ {
show_status_array(thd, wild, (SHOW_VAR *) var->value, scope, show_status_array(thd, wild, (SHOW_VAR *) var->value, scope,
status_var, name_buffer, table, ucase_names, cond); status_var, name_buffer.to_lex_cstring(),
table, ucase_names, cond);
} }
else else
{ {
if ((wild_checked || if ((wild_checked ||
!(wild && wild[0] && wild_case_compare(system_charset_info, !(wild && wild[0] && wild_case_compare(system_charset_info,
name_buffer, wild))) && name_buffer.ptr(),
wild))) &&
(!cond || cond->val_int())) (!cond || cond->val_int()))
{ {
const char *pos; // We assign a lot of const's const char *pos; // We assign a lot of const's
@@ -4376,18 +4382,15 @@ bool get_lookup_field_values(THD *thd, COND *cond, bool fix_table_name_case,
if (lower_case_table_names && !rc) if (lower_case_table_names && !rc)
{ {
/*
We can safely do in-place upgrades here since all of the above cases
are allocating a new memory buffer for these strings.
*/
if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0]) if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0])
my_casedn_str(system_charset_info, lookup_field_values->db_value= thd->make_ident_casedn(
(char*) lookup_field_values->db_value.str); lookup_field_values->db_value);
if (fix_table_name_case && if (fix_table_name_case &&
lookup_field_values->table_value.str && lookup_field_values->table_value.str &&
lookup_field_values->table_value.str[0]) lookup_field_values->table_value.str[0])
my_casedn_str(system_charset_info, lookup_field_values->table_value= thd->make_ident_casedn(
(char*) lookup_field_values->table_value.str); lookup_field_values->table_value);
} }
return rc; return rc;
@@ -8443,7 +8446,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
sync_dynamic_session_variables(thd, true); sync_dynamic_session_variables(thd, true);
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope), res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope),
scope, NULL, "", tables->table, scope, NULL, empty_clex_str, tables->table,
upper_case_names, partial_cond); upper_case_names, partial_cond);
mysql_prlock_unlock(&LOCK_system_variables_hash); mysql_prlock_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res); DBUG_RETURN(res);
@@ -8543,7 +8546,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
mysql_rwlock_rdlock(&LOCK_all_status_vars); mysql_rwlock_rdlock(&LOCK_all_status_vars);
res= show_status_array(thd, wild, res= show_status_array(thd, wild,
(SHOW_VAR *)all_status_vars.buffer, (SHOW_VAR *)all_status_vars.buffer,
scope, tmp1, "", tables->table, scope, tmp1, empty_clex_str, tables->table,
upper_case_names, partial_cond); upper_case_names, partial_cond);
mysql_rwlock_unlock(&LOCK_all_status_vars); mysql_rwlock_unlock(&LOCK_all_status_vars);
DBUG_RETURN(res); DBUG_RETURN(res);
@@ -10760,11 +10763,7 @@ TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
if (!(table= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST)))) if (!(table= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
return NULL; return NULL;
db= trg_name->m_db; db= thd->make_ident_opt_casedn(trg_name->m_db, lower_case_table_names);
db.str= thd->strmake(db.str, db.length);
if (lower_case_table_names)
db.length= my_casedn_str(files_charset_info, (char*) db.str);
tbl_name.str= thd->strmake(tbl_name.str, tbl_name.length); tbl_name.str= thd->strmake(tbl_name.str, tbl_name.length);

View File

@@ -1030,6 +1030,24 @@ public:
set_charset(tocs); set_charset(tocs);
return false; return false;
} }
bool copy_casedn(CHARSET_INFO *cs, const LEX_CSTRING &str)
{
size_t nbytes= str.length * cs->casedn_multiply();
DBUG_ASSERT(nbytes + 1 <= UINT_MAX32);
if (alloc(nbytes))
return true;
str_length= (uint32) cs->casedn_z(str.str, str.length, Ptr, nbytes + 1);
return false;
}
bool copy_caseup(CHARSET_INFO *cs, const LEX_CSTRING &str)
{
size_t nbytes= str.length * cs->caseup_multiply();
DBUG_ASSERT(nbytes + 1 <= UINT_MAX32);
if (alloc(nbytes))
return true;
str_length= (uint32) cs->caseup_z(str.str, str.length, Ptr, nbytes + 1);
return false;
}
// Append without character set conversion // Append without character set conversion
bool append(const String &s) bool append(const String &s)
{ {

View File

@@ -657,7 +657,7 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
if (lower_case_table_names) if (lower_case_table_names)
{ {
/* Convert all except tmpdir to lower case */ /* Convert all except tmpdir to lower case */
my_casedn_str(files_charset_info, p); my_casedn_str_latin1(p);
} }
size_t length= unpack_filename(buff, buff); size_t length= unpack_filename(buff, buff);

View File

@@ -282,9 +282,7 @@ public:
void print(String *str, enum_query_type query_type) override void print(String *str, enum_query_type query_type) override
{ {
StringBuffer<FbtImpl::max_char_length()+64> tmp; StringBuffer<FbtImpl::max_char_length()+64> tmp;
tmp.append(singleton()->name().lex_cstring()); str->append(singleton()->name().lex_cstring());
my_caseup_str(&my_charset_latin1, tmp.c_ptr());
str->append(tmp);
str->append('\''); str->append('\'');
m_value.to_string(&tmp); m_value.to_string(&tmp);
str->append(tmp); str->append(tmp);

View File

@@ -15790,12 +15790,7 @@ user_maybe_role:
MYSQL_YYABORT; MYSQL_YYABORT;
if ($$->host.str[0]) if ($$->host.str[0])
{ {
/* $$->host= thd->make_ident_casedn($$->host);
Convert hostname part of username to lowercase.
It's OK to use in-place lowercase as long as
the character set is utf8.
*/
my_casedn_str(system_charset_info, (char*) $$->host.str);
} }
else else
{ {

View File

@@ -45,8 +45,6 @@
#include "catalog.h" #include "catalog.h"
#include "ha_connect.h" #include "ha_connect.h"
#define my_strupr(p) my_caseup_str(default_charset_info, (p));
#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
#define my_stricmp(a, b) my_strcasecmp(default_charset_info, (a), (b)) #define my_stricmp(a, b) my_strcasecmp(default_charset_info, (a), (b))
/***********************************************************************/ /***********************************************************************/

View File

@@ -156,8 +156,6 @@
#include "tabpivot.h" #include "tabpivot.h"
#include "tabfix.h" #include "tabfix.h"
#define my_strupr(p) my_caseup_str(default_charset_info, (p));
#define my_strlwr(p) my_casedn_str(default_charset_info, (p));
#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b)) #define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b))

View File

@@ -1459,28 +1459,23 @@ static void fill_server(MEM_ROOT *mem_root, FEDERATEDX_SERVER *server,
char buffer[STRING_BUFFER_USUAL_SIZE]; char buffer[STRING_BUFFER_USUAL_SIZE];
const char *socket_arg= share->socket ? share->socket : ""; const char *socket_arg= share->socket ? share->socket : "";
const char *password_arg= share->password ? share->password : ""; const char *password_arg= share->password ? share->password : "";
const Lex_cstring_strlen ls_database(share->database);
const Lex_cstring_strlen ls_socket(socket_arg);
String key(buffer, sizeof(buffer), &my_charset_bin); String key(buffer, sizeof(buffer), &my_charset_bin);
String scheme(share->scheme, strlen(share->scheme), &my_charset_latin1); String scheme, hostname;
String hostname(share->hostname, strlen(share->hostname), &my_charset_latin1); String database(ls_database.str, ls_database.length, system_charset_info);
String database(share->database, strlen(share->database), system_charset_info);
String username(share->username, strlen(share->username), system_charset_info); String username(share->username, strlen(share->username), system_charset_info);
String socket(socket_arg, strlen(socket_arg), files_charset_info); String socket(ls_socket.str, ls_socket.length, files_charset_info);
String password(password_arg, strlen(password_arg), &my_charset_bin); String password(password_arg, strlen(password_arg), &my_charset_bin);
DBUG_ENTER("fill_server"); DBUG_ENTER("fill_server");
/* Do some case conversions */ /* Do some case conversions */
scheme.reserve(scheme.length()); scheme.copy_casedn(&my_charset_latin1, Lex_cstring_strlen(share->scheme));
scheme.length(my_casedn_str(&my_charset_latin1, scheme.c_ptr_safe())); hostname.copy_casedn(&my_charset_latin1, Lex_cstring_strlen(share->hostname));
hostname.reserve(hostname.length());
hostname.length(my_casedn_str(&my_charset_latin1, hostname.c_ptr_safe()));
if (lower_case_table_names) if (lower_case_table_names)
{ database.copy_casedn(system_charset_info, ls_database);
database.reserve(database.length());
database.length(my_casedn_str(system_charset_info, database.c_ptr_safe()));
}
#ifndef _WIN32 #ifndef _WIN32
/* /*
@@ -1488,10 +1483,7 @@ static void fill_server(MEM_ROOT *mem_root, FEDERATEDX_SERVER *server,
revised about using sockets in such environment. revised about using sockets in such environment.
*/ */
if (lower_case_file_system && socket.length()) if (lower_case_file_system && socket.length())
{ socket.copy_casedn(files_charset_info, ls_socket);
socket.reserve(socket.length());
socket.length(my_casedn_str(files_charset_info, socket.c_ptr_safe()));
}
#endif #endif
/* start with all bytes zeroed */ /* start with all bytes zeroed */

View File

@@ -1599,19 +1599,13 @@ dict_table_rename_in_cache(
foreign->referenced_table->referenced_set.erase(foreign); foreign->referenced_table->referenced_set.erase(foreign);
} }
if (strlen(foreign->foreign_table_name) /* Allocate a name buffer;
< strlen(table->name.m_name)) {
/* Allocate a longer name buffer;
TODO: store buf len to save memory */ TODO: store buf len to save memory */
foreign->foreign_table_name = mem_heap_strdup( foreign->foreign_table_name = mem_heap_strdup(
foreign->heap, table->name.m_name); foreign->heap, table->name.m_name);
dict_mem_foreign_table_name_lookup_set(foreign, TRUE); foreign->foreign_table_name_lookup_set();
} else {
strcpy(foreign->foreign_table_name,
table->name.m_name);
dict_mem_foreign_table_name_lookup_set(foreign, FALSE);
}
if (strchr(foreign->id, '/')) { if (strchr(foreign->id, '/')) {
/* This is a >= 4.0.18 format id */ /* This is a >= 4.0.18 format id */
@@ -1772,24 +1766,13 @@ dict_table_rename_in_cache(
foreign = *it; foreign = *it;
if (strlen(foreign->referenced_table_name) /* Allocate a name buffer;
< strlen(table->name.m_name)) {
/* Allocate a longer name buffer;
TODO: store buf len to save memory */ TODO: store buf len to save memory */
foreign->referenced_table_name = mem_heap_strdup( foreign->referenced_table_name = mem_heap_strdup(
foreign->heap, table->name.m_name); foreign->heap, table->name.m_name);
dict_mem_referenced_table_name_lookup_set( foreign->referenced_table_name_lookup_set();
foreign, TRUE);
} else {
/* Use the same buffer */
strcpy(foreign->referenced_table_name,
table->name.m_name);
dict_mem_referenced_table_name_lookup_set(
foreign, FALSE);
}
} }
return(DB_SUCCESS); return(DB_SUCCESS);
@@ -3237,7 +3220,6 @@ dict_get_referenced_table(
mem_heap_t* heap, /*!< in/out: heap memory */ mem_heap_t* heap, /*!< in/out: heap memory */
CHARSET_INFO* from_cs) /*!< in: table name charset */ CHARSET_INFO* from_cs) /*!< in: table name charset */
{ {
char* ref;
char db_name[MAX_DATABASE_NAME_LEN]; char db_name[MAX_DATABASE_NAME_LEN];
char tbl_name[MAX_TABLE_NAME_LEN]; char tbl_name[MAX_TABLE_NAME_LEN];
CHARSET_INFO* to_cs = &my_charset_filename; CHARSET_INFO* to_cs = &my_charset_filename;
@@ -3283,31 +3265,22 @@ dict_get_referenced_table(
} }
/* Copy database_name, '/', table_name, '\0' */ /* Copy database_name, '/', table_name, '\0' */
const size_t len = database_name_len + table_name_len + 1; Identifier_chain2 ident({database_name, database_name_len},
ref = static_cast<char*>(mem_heap_alloc(heap, len + 1)); {table_name, table_name_len});
memcpy(ref, database_name, database_name_len); size_t ref_nbytes= (database_name_len + table_name_len) *
ref[database_name_len] = '/'; system_charset_info->casedn_multiply() + 2;
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); char *ref = static_cast<char*>(mem_heap_alloc(heap, ref_nbytes));
/* Values; 0 = Store and compare as given; case sensitive /* Values; 0 = Store and compare as given; case sensitive
1 = Store and compare in lower; case insensitive 1 = Store and compare in lower; case insensitive
2 = Store as given, compare in lower; case semi-sensitive */ 2 = Store as given, compare in lower; case semi-sensitive */
if (lower_case_table_names == 2) {
innobase_casedn_str(ref);
*table = dict_sys.load_table({ref, len});
memcpy(ref, database_name, database_name_len);
ref[database_name_len] = '/';
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
} else { size_t len= ident.make_sep_name_opt_casedn(ref, ref_nbytes,
#ifndef _WIN32 '/', lower_case_table_names > 0);
if (lower_case_table_names == 1) {
innobase_casedn_str(ref);
}
#else
innobase_casedn_str(ref);
#endif /* !_WIN32 */
*table = dict_sys.load_table({ref, len}); *table = dict_sys.load_table({ref, len});
if (lower_case_table_names == 2) {
ident.make_sep_name_opt_casedn(ref, ref_nbytes, '/', false);
} }
return(ref); return(ref);

View File

@@ -2976,7 +2976,7 @@ err_exit:
foreign->foreign_table_name = mem_heap_strdupl( foreign->foreign_table_name = mem_heap_strdupl(
foreign->heap, (char*) field, len); foreign->heap, (char*) field, len);
dict_mem_foreign_table_name_lookup_set(foreign, TRUE); foreign->foreign_table_name_lookup_set();
const size_t foreign_table_name_len = len; const size_t foreign_table_name_len = len;
const size_t table_name_len = strlen(table_name); const size_t table_name_len = strlen(table_name);
@@ -2997,7 +2997,7 @@ err_exit:
foreign->referenced_table_name = mem_heap_strdupl( foreign->referenced_table_name = mem_heap_strdupl(
foreign->heap, (const char*) field, len); foreign->heap, (const char*) field, len);
dict_mem_referenced_table_name_lookup_set(foreign, TRUE); foreign->referenced_table_name_lookup_set();
mtr.commit(); mtr.commit();
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {

View File

@@ -816,27 +816,15 @@ lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
will point to foreign_table_name. If 2, then another string is will point to foreign_table_name. If 2, then another string is
allocated from foreign->heap and set to lower case. */ allocated from foreign->heap and set to lower case. */
void void
dict_mem_foreign_table_name_lookup_set( dict_foreign_t::foreign_table_name_lookup_set()
/*===================================*/
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{ {
if (lower_case_table_names == 2) { if (lower_case_table_names == 2) {
if (do_alloc) { LEX_STRING str= mem_heap_alloc_casedn_z(heap,
ulint len; system_charset_info,
Lex_cstring_strlen(foreign_table_name));
len = strlen(foreign->foreign_table_name) + 1; foreign_table_name_lookup= str.str;
foreign->foreign_table_name_lookup =
static_cast<char*>(
mem_heap_alloc(foreign->heap, len));
}
strcpy(foreign->foreign_table_name_lookup,
foreign->foreign_table_name);
innobase_casedn_str(foreign->foreign_table_name_lookup);
} else { } else {
foreign->foreign_table_name_lookup foreign_table_name_lookup = foreign_table_name;
= foreign->foreign_table_name;
} }
} }
@@ -846,27 +834,15 @@ lower_case_table_names. If that is 0 or 1, referenced_table_name_lookup
will point to referenced_table_name. If 2, then another string is will point to referenced_table_name. If 2, then another string is
allocated from foreign->heap and set to lower case. */ allocated from foreign->heap and set to lower case. */
void void
dict_mem_referenced_table_name_lookup_set( dict_foreign_t::referenced_table_name_lookup_set()
/*======================================*/
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{ {
if (lower_case_table_names == 2) { if (lower_case_table_names == 2) {
if (do_alloc) { LEX_STRING str= mem_heap_alloc_casedn_z(heap,
ulint len; system_charset_info,
Lex_cstring_strlen(referenced_table_name));
len = strlen(foreign->referenced_table_name) + 1; referenced_table_name_lookup = str.str;
foreign->referenced_table_name_lookup =
static_cast<char*>(
mem_heap_alloc(foreign->heap, len));
}
strcpy(foreign->referenced_table_name_lookup,
foreign->referenced_table_name);
innobase_casedn_str(foreign->referenced_table_name_lookup);
} else { } else {
foreign->referenced_table_name_lookup referenced_table_name_lookup = referenced_table_name;
= foreign->referenced_table_name;
} }
} }

View File

@@ -4427,7 +4427,6 @@ fts_add_token(
fts_string_t t_str; fts_string_t t_str;
fts_token_t* token; fts_token_t* token;
ib_rbt_bound_t parent; ib_rbt_bound_t parent;
ulint newlen;
heap = static_cast<mem_heap_t*>(result_doc->self_heap->arg); heap = static_cast<mem_heap_t*>(result_doc->self_heap->arg);
@@ -4443,24 +4442,19 @@ fts_add_token(
if (my_binary_compare(result_doc->charset)) { if (my_binary_compare(result_doc->charset)) {
memcpy(t_str.f_str, str.f_str, str.f_len); memcpy(t_str.f_str, str.f_str, str.f_len);
t_str.f_str[str.f_len]= 0; t_str.f_str[str.f_len]= 0;
newlen= str.f_len; t_str.f_len= str.f_len;
} else { } else {
newlen = innobase_fts_casedn_str( t_str.f_len= result_doc->charset->casedn_z(
result_doc->charset, (char*) str.f_str, str.f_len, (const char*) str.f_str, str.f_len,
(char*) t_str.f_str, t_str.f_len); (char *) t_str.f_str, t_str.f_len);
} }
t_str.f_len = newlen;
t_str.f_str[newlen] = 0;
/* Add the word to the document statistics. If the word /* Add the word to the document statistics. If the word
hasn't been seen before we create a new entry for it. */ hasn't been seen before we create a new entry for it. */
if (rbt_search(result_doc->tokens, &parent, &t_str) != 0) { if (rbt_search(result_doc->tokens, &parent, &t_str) != 0) {
fts_token_t new_token; fts_token_t new_token;
new_token.text.f_len = newlen; new_token.text = t_str;
new_token.text.f_str = t_str.f_str;
new_token.text.f_n_char = t_str.f_n_char;
new_token.positions = ib_vector_create( new_token.positions = ib_vector_create(
result_doc->self_heap, sizeof(ulint), 32); result_doc->self_heap, sizeof(ulint), 32);

View File

@@ -1641,9 +1641,10 @@ fts_query_match_phrase_terms(
token = static_cast<const fts_string_t*>( token = static_cast<const fts_string_t*>(
ib_vector_get_const(tokens, i)); ib_vector_get_const(tokens, i));
fts_string_dup(&cmp_str, &match, heap); cmp_str = fts_string_dup_casedn(phrase->charset,
match, heap);
result = innobase_fts_text_case_cmp( result = innobase_fts_text_cmp(
phrase->charset, token, &cmp_str); phrase->charset, token, &cmp_str);
/* Skip the rest of the tokens if this one doesn't /* Skip the rest of the tokens if this one doesn't
@@ -1797,9 +1798,9 @@ fts_query_match_phrase_add_word_for_parser(
token = static_cast<const fts_string_t*>( token = static_cast<const fts_string_t*>(
ib_vector_get_const(tokens, phrase_param->token_index)); ib_vector_get_const(tokens, phrase_param->token_index));
fts_string_dup(&cmp_str, &match, heap); cmp_str = fts_string_dup_casedn(phrase->charset, match, heap);
result = innobase_fts_text_case_cmp( result = innobase_fts_text_cmp(
phrase->charset, token, &cmp_str); phrase->charset, token, &cmp_str);
if (result == 0) { if (result == 0) {
@@ -1938,9 +1939,10 @@ fts_query_match_phrase(
break; break;
} }
fts_string_dup(&cmp_str, &match, heap); cmp_str = fts_string_dup_casedn(phrase->charset,
match, heap);
if (innobase_fts_text_case_cmp( if (innobase_fts_text_cmp(
phrase->charset, first, &cmp_str) == 0) { phrase->charset, first, &cmp_str) == 0) {
/* This is the case for the single word /* This is the case for the single word
@@ -4053,15 +4055,13 @@ fts_query(
lc_query_str[query_len]= 0; lc_query_str[query_len]= 0;
result_len= query_len; result_len= query_len;
} else { } else {
result_len = innobase_fts_casedn_str( result_len = charset->casedn_z(
charset, (char*)( query_str), query_len, (const char*) query_str, query_len,
(char*)(lc_query_str), lc_query_str_len); (char*) lc_query_str, lc_query_str_len);
} }
ut_ad(result_len < lc_query_str_len); ut_ad(result_len < lc_query_str_len);
lc_query_str[result_len] = 0;
query.heap = mem_heap_create(128); query.heap = mem_heap_create(128);
/* Create the rb tree for the doc id (current) set. */ /* Create the rb tree for the doc id (current) set. */

View File

@@ -39,6 +39,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <innodb_priv.h> #include <innodb_priv.h>
#include <strfunc.h> #include <strfunc.h>
#include <sql_acl.h> #include <sql_acl.h>
#include <lex_ident.h>
#include <sql_class.h> #include <sql_class.h>
#include <sql_show.h> #include <sql_show.h>
#include <sql_table.h> #include <sql_table.h>
@@ -1294,18 +1295,19 @@ static void innodb_drop_database(handlerton*, char *path)
len++; len++;
ptr++; ptr++;
size_t casedn_nbytes= len * system_charset_info->casedn_multiply();
char *namebuf= static_cast<char*> char *namebuf= static_cast<char*>
(my_malloc(PSI_INSTRUMENT_ME, len + 2, MYF(0))); (my_malloc(PSI_INSTRUMENT_ME, casedn_nbytes + 2, MYF(0)));
if (!namebuf) if (!namebuf)
return; return;
#ifndef _WIN32
memcpy(namebuf, ptr, len); memcpy(namebuf, ptr, len);
#else /*_WIN32*/
len= system_charset_info->casedn(ptr, len, namebuf, casedn_nbytes);
#endif /* _WIN32 */
namebuf[len] = '/'; namebuf[len] = '/';
namebuf[len + 1] = '\0'; namebuf[len + 1] = '\0';
#ifdef _WIN32
innobase_casedn_str(namebuf);
#endif /* _WIN32 */
THD * const thd= current_thd; THD * const thd= current_thd;
trx_t *trx= innobase_trx_allocate(thd); trx_t *trx= innobase_trx_allocate(thd);
dberr_t err= DB_SUCCESS; dberr_t err= DB_SUCCESS;
@@ -1904,8 +1906,17 @@ static int innobase_wsrep_set_checkpoint(handlerton *hton, const XID *xid);
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid); static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
#define normalize_table_name(a,b) \
normalize_table_name_c_low(a,b,IF_WIN(true,false)) static inline size_t
normalize_table_name(
char* norm_name,
size_t norm_name_size,
const char* name)
{
return normalize_table_name_c_low(norm_name, norm_name_size,
name, IF_WIN(true,false));
}
ulonglong ha_innobase::table_version() const ulonglong ha_innobase::table_version() const
{ {
@@ -1931,7 +1942,7 @@ static int innodb_check_version(handlerton *hton, const char *path,
DBUG_RETURN(0); DBUG_RETURN(0);
char norm_path[FN_REFLEN]; char norm_path[FN_REFLEN];
normalize_table_name(norm_path, path); normalize_table_name(norm_path, sizeof(norm_path), path);
if (dict_table_t *table= dict_table_open_on_name(norm_path, false, if (dict_table_t *table= dict_table_open_on_name(norm_path, false,
DICT_ERR_IGNORE_NONE)) DICT_ERR_IGNORE_NONE))
@@ -2462,16 +2473,6 @@ innobase_basename(
return((name) ? name : "null"); return((name) ? name : "null");
} }
/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
void
innobase_casedn_str(
/*================*/
char* a) /*!< in/out: string to put in lower case */
{
my_casedn_str(system_charset_info, a);
}
/** Determines the current SQL statement. /** Determines the current SQL statement.
Thread unsafe, can only be called from the thread owning the THD. Thread unsafe, can only be called from the thread owning the THD.
@param[in] thd MySQL thread handle @param[in] thd MySQL thread handle
@@ -3280,7 +3281,7 @@ innobase_query_caching_of_table_permitted(
} }
/* Normalize the table name to InnoDB format */ /* Normalize the table name to InnoDB format */
normalize_table_name(norm_name, full_name); normalize_table_name(norm_name, sizeof(norm_name), full_name);
innobase_register_trx(innodb_hton_ptr, thd, trx); innobase_register_trx(innodb_hton_ptr, thd, trx);
@@ -5197,21 +5198,22 @@ table name always to lower case if "set_lower_case" is set to TRUE.
@param[out] norm_name Normalized name, null-terminated. @param[out] norm_name Normalized name, null-terminated.
@param[in] name Name to normalize. @param[in] name Name to normalize.
@param[in] set_lower_case True if we also should fold to lower case. */ @param[in] set_lower_case True if we also should fold to lower case. */
void size_t
normalize_table_name_c_low( normalize_table_name_c_low(
/*=======================*/ /*=======================*/
char* norm_name, /* out: normalized name as a char* norm_name, /* out: normalized name as a
null-terminated string */ null-terminated string */
size_t norm_name_size, /*!< in: number of bytes available
in norm_name*/
const char* name, /* in: table name string */ const char* name, /* in: table name string */
bool set_lower_case) /* in: TRUE if we want to set bool set_lower_case) /* in: TRUE if we want to set
name to lower case */ name to lower case */
{ {
char* name_ptr; const char* name_ptr;
ulint name_len; ulint name_len;
char* db_ptr; const char* db_ptr;
ulint db_len; ulint db_len;
char* ptr; const char* ptr;
ulint norm_len;
/* Scan name from the end */ /* Scan name from the end */
@@ -5241,28 +5243,15 @@ normalize_table_name_c_low(
} }
db_ptr = ptr + 1; db_ptr = ptr + 1;
return Identifier_chain2({db_ptr, db_len}, {name_ptr, name_len}).
norm_len = db_len + name_len + sizeof "/"; make_sep_name_opt_casedn(norm_name, norm_name_size, '/',
ut_a(norm_len < FN_REFLEN - 1); set_lower_case);
memcpy(norm_name, db_ptr, db_len);
norm_name[db_len] = '/';
/* Copy the name and null-byte. */
memcpy(norm_name + db_len + 1, name_ptr, name_len + 1);
if (set_lower_case) {
innobase_casedn_str(norm_name);
}
} }
create_table_info_t::create_table_info_t( create_table_info_t::create_table_info_t(
THD* thd, THD* thd,
const TABLE* form, const TABLE* form,
HA_CREATE_INFO* create_info, HA_CREATE_INFO* create_info,
char* table_name,
char* remote_path,
bool file_per_table, bool file_per_table,
trx_t* trx) trx_t* trx)
: m_thd(thd), : m_thd(thd),
@@ -5270,11 +5259,12 @@ create_table_info_t::create_table_info_t(
m_form(form), m_form(form),
m_default_row_format(innodb_default_row_format), m_default_row_format(innodb_default_row_format),
m_create_info(create_info), m_create_info(create_info),
m_table_name(table_name), m_table(NULL), m_table(NULL),
m_remote_path(remote_path),
m_innodb_file_per_table(file_per_table), m_innodb_file_per_table(file_per_table),
m_creating_stub(thd_ddl_options(thd)->import_tablespace()) m_creating_stub(thd_ddl_options(thd)->import_tablespace())
{ {
m_table_name[0]= '\0';
m_remote_path[0]= '\0';
} }
#if !defined(DBUG_OFF) #if !defined(DBUG_OFF)
@@ -5332,7 +5322,7 @@ test_normalize_table_name_low()
test_data[i][0], test_data[i][1]); test_data[i][0], test_data[i][1]);
normalize_table_name_c_low( normalize_table_name_c_low(
norm_name, test_data[i][0], FALSE); norm_name, sizeof(norm_name), test_data[i][0], FALSE);
if (strcmp(norm_name, test_data[i][1]) == 0) { if (strcmp(norm_name, test_data[i][1]) == 0) {
printf("ok\n"); printf("ok\n");
@@ -5880,7 +5870,7 @@ ha_innobase::open(const char* name, int, uint)
DBUG_ENTER("ha_innobase::open"); DBUG_ENTER("ha_innobase::open");
normalize_table_name(norm_name, name); normalize_table_name(norm_name, sizeof(norm_name), name);
m_user_thd = NULL; m_user_thd = NULL;
@@ -6213,15 +6203,17 @@ ha_innobase::open_dict_table(
/* Check for the table using lower /* Check for the table using lower
case name, including the partition case name, including the partition
separator "P" */ separator "P" */
strcpy(par_case_name, norm_name); system_charset_info->casedn_z(
innobase_casedn_str(par_case_name); norm_name, strlen(norm_name),
par_case_name, sizeof(par_case_name));
#else #else
/* On Windows platfrom, check /* On Windows platfrom, check
whether there exists table name in whether there exists table name in
system table whose name is system table whose name is
not being normalized to lower case */ not being normalized to lower case */
normalize_table_name_c_low( normalize_table_name_c_low(
par_case_name, table_name, false); par_case_name, sizeof(par_case_name),
table_name, false);
#endif #endif
/* FIXME: try_drop_aborted */ /* FIXME: try_drop_aborted */
ib_table = dict_table_open_on_name( ib_table = dict_table_open_on_name(
@@ -6437,29 +6429,6 @@ innobase_fts_text_cmp(
s2->f_str, static_cast<uint>(s2->f_len))); s2->f_str, static_cast<uint>(s2->f_len)));
} }
/******************************************************************//**
compare two character string case insensitively according to their charset. */
int
innobase_fts_text_case_cmp(
/*=======================*/
const void* cs, /*!< in: Character set */
const void* p1, /*!< in: key */
const void* p2) /*!< in: node */
{
const CHARSET_INFO* charset = (const CHARSET_INFO*) cs;
const fts_string_t* s1 = (const fts_string_t*) p1;
const fts_string_t* s2 = (const fts_string_t*) p2;
ulint newlen;
my_casedn_str(charset, (char*) s2->f_str);
newlen = strlen((const char*) s2->f_str);
return(ha_compare_word(charset,
s1->f_str, static_cast<uint>(s1->f_len),
s2->f_str, static_cast<uint>(newlen)));
}
/******************************************************************//** /******************************************************************//**
Get the first character's code position for FTS index partition. */ Get the first character's code position for FTS index partition. */
ulint ulint
@@ -6511,28 +6480,6 @@ innobase_fts_text_cmp_prefix(
return(-result); return(-result);
} }
/******************************************************************//**
Makes all characters in a string lower case. */
size_t
innobase_fts_casedn_str(
/*====================*/
CHARSET_INFO* cs, /*!< in: Character set */
char* src, /*!< in: string to put in lower case */
size_t src_len,/*!< in: input string length */
char* dst, /*!< in: buffer for result string */
size_t dst_len)/*!< in: buffer size */
{
if (cs->casedn_multiply() == 1) {
memcpy(dst, src, src_len);
dst[src_len] = 0;
my_casedn_str(cs, dst);
return(strlen(dst));
} else {
return(cs->casedn(src, src_len, dst, dst_len));
}
}
#define true_word_char(c, ch) ((c) & (_MY_U | _MY_L | _MY_NMR) || (ch) == '_') #define true_word_char(c, ch) ((c) & (_MY_U | _MY_L | _MY_NMR) || (ch) == '_')
#define misc_word_char(X) 0 #define misc_word_char(X) 0
@@ -12079,7 +12026,7 @@ int create_table_info_t::prepare_create_table(const char* name, bool strict)
set_tablespace_type(false); set_tablespace_type(false);
normalize_table_name(m_table_name, name); normalize_table_name(m_table_name, sizeof(m_table_name), name);
/* Validate table options not handled by the SQL-parser */ /* Validate table options not handled by the SQL-parser */
if (check_table_options()) { if (check_table_options()) {
@@ -12481,7 +12428,7 @@ create_table_info_t::create_foreign_keys()
return (DB_OUT_OF_MEMORY); return (DB_OUT_OF_MEMORY);
} }
dict_mem_foreign_table_name_lookup_set(foreign, TRUE); foreign->foreign_table_name_lookup_set();
foreign->foreign_index = index; foreign->foreign_index = index;
foreign->n_fields = i & dict_index_t::MAX_N_FIELDS; foreign->n_fields = i & dict_index_t::MAX_N_FIELDS;
@@ -12588,7 +12535,7 @@ create_table_info_t::create_foreign_keys()
} }
foreign->referenced_index = index; foreign->referenced_index = index;
dict_mem_referenced_table_name_lookup_set(foreign, TRUE); foreign->referenced_table_name_lookup_set();
foreign->referenced_col_names = static_cast<const char**>( foreign->referenced_col_names = static_cast<const char**>(
mem_heap_alloc(foreign->heap, i * sizeof(void*))); mem_heap_alloc(foreign->heap, i * sizeof(void*)));
@@ -13203,16 +13150,12 @@ int
ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info,
bool file_per_table, trx_t *trx= nullptr) bool file_per_table, trx_t *trx= nullptr)
{ {
char norm_name[FN_REFLEN]; /* {database}/{tablename} */
char remote_path[FN_REFLEN]; /* Absolute path of table */
DBUG_ENTER("ha_innobase::create"); DBUG_ENTER("ha_innobase::create");
DBUG_ASSERT(form->s == table_share); DBUG_ASSERT(form->s == table_share);
DBUG_ASSERT(table_share->table_type == TABLE_TYPE_SEQUENCE || DBUG_ASSERT(table_share->table_type == TABLE_TYPE_SEQUENCE ||
table_share->table_type == TABLE_TYPE_NORMAL); table_share->table_type == TABLE_TYPE_NORMAL);
create_table_info_t info(ha_thd(), form, create_info, norm_name, create_table_info_t info(ha_thd(), form, create_info, file_per_table, trx);
remote_path, file_per_table, trx);
int error= info.initialize(); int error= info.initialize();
if (!error) if (!error)
@@ -13435,16 +13378,18 @@ int ha_innobase::delete_table(const char *name)
{ {
char norm_name[FN_REFLEN]; char norm_name[FN_REFLEN];
normalize_table_name(norm_name, name); size_t norm_len= normalize_table_name_c_low(norm_name, sizeof(norm_name),
span<const char> n{norm_name, strlen(norm_name)}; name, IF_WIN(true,false));
span<const char> n{norm_name, norm_len};
dict_sys.lock(SRW_LOCK_CALL); dict_sys.lock(SRW_LOCK_CALL);
table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP); table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP);
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
if (!table && lower_case_table_names == 1 && is_partition(norm_name)) if (!table && lower_case_table_names == 1 && is_partition(norm_name))
{ {
IF_WIN(normalize_table_name_c_low(norm_name, name, false), norm_len= normalize_table_name_c_low(norm_name, sizeof(norm_name),
innobase_casedn_str(norm_name)); name, IF_WIN(false, true));
n= {norm_name, norm_len};
table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP); table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP);
} }
#endif #endif
@@ -13752,8 +13697,8 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from,
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
normalize_table_name(norm_to, to); normalize_table_name(norm_to, sizeof(norm_to), to);
normalize_table_name(norm_from, from); normalize_table_name(norm_from, sizeof(norm_from), from);
DEBUG_SYNC_C("innodb_rename_table_ready"); DEBUG_SYNC_C("innodb_rename_table_ready");
@@ -13772,15 +13717,17 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from,
/* Check for the table using lower /* Check for the table using lower
case name, including the partition case name, including the partition
separator "P" */ separator "P" */
strcpy(par_case_name, norm_from); system_charset_info->casedn_z(
innobase_casedn_str(par_case_name); norm_from, strlen(norm_from),
par_case_name, sizeof(par_case_name));
#else #else
/* On Windows platfrom, check /* On Windows platfrom, check
whether there exists table name in whether there exists table name in
system table whose name is system table whose name is
not being normalized to lower case */ not being normalized to lower case */
normalize_table_name_c_low( normalize_table_name_c_low(
par_case_name, from, false); par_case_name, sizeof(par_case_name),
from, false);
#endif /* _WIN32 */ #endif /* _WIN32 */
trx_start_if_not_started(trx, true); trx_start_if_not_started(trx, true);
error = row_rename_table_for_mysql( error = row_rename_table_for_mysql(
@@ -14091,8 +14038,8 @@ ha_innobase::rename_table(
char norm_from[MAX_FULL_NAME_LEN]; char norm_from[MAX_FULL_NAME_LEN];
char norm_to[MAX_FULL_NAME_LEN]; char norm_to[MAX_FULL_NAME_LEN];
normalize_table_name(norm_from, from); normalize_table_name(norm_from, sizeof(norm_from), from);
normalize_table_name(norm_to, to); normalize_table_name(norm_to, sizeof(norm_to), to);
dberr_t error = DB_SUCCESS; dberr_t error = DB_SUCCESS;
const bool from_temp = dict_table_t::is_temporary_name(norm_from); const bool from_temp = dict_table_t::is_temporary_name(norm_from);

View File

@@ -625,8 +625,6 @@ public:
THD* thd, THD* thd,
const TABLE* form, const TABLE* form,
HA_CREATE_INFO* create_info, HA_CREATE_INFO* create_info,
char* table_name,
char* remote_path,
bool file_per_table, bool file_per_table,
trx_t* trx = NULL); trx_t* trx = NULL);
@@ -740,13 +738,13 @@ private:
/** Create options. */ /** Create options. */
HA_CREATE_INFO* m_create_info; HA_CREATE_INFO* m_create_info;
/** Table name */ /** Table name: {database}/{tablename} */
char* m_table_name; char m_table_name[FN_REFLEN];
/** Table */ /** Table */
dict_table_t* m_table; dict_table_t* m_table;
/** Remote path (DATA DIRECTORY) or zero length-string */ /** Remote path (DATA DIRECTORY) or zero length-string */
char* m_remote_path; char m_remote_path[FN_REFLEN]; // Absolute path of the table
/** Local copy of srv_file_per_table. */ /** Local copy of srv_file_per_table. */
bool m_innodb_file_per_table; bool m_innodb_file_per_table;

View File

@@ -2897,7 +2897,7 @@ innobase_init_foreign(
foreign->foreign_table = table; foreign->foreign_table = table;
foreign->foreign_table_name = mem_heap_strdup( foreign->foreign_table_name = mem_heap_strdup(
foreign->heap, table->name.m_name); foreign->heap, table->name.m_name);
dict_mem_foreign_table_name_lookup_set(foreign, TRUE); foreign->foreign_table_name_lookup_set();
foreign->foreign_index = index; foreign->foreign_index = index;
foreign->n_fields = static_cast<unsigned>(num_field) foreign->n_fields = static_cast<unsigned>(num_field)
@@ -2916,7 +2916,7 @@ innobase_init_foreign(
foreign->referenced_table_name = mem_heap_strdup( foreign->referenced_table_name = mem_heap_strdup(
foreign->heap, referenced_table_name); foreign->heap, referenced_table_name);
dict_mem_referenced_table_name_lookup_set(foreign, TRUE); foreign->referenced_table_name_lookup_set();
foreign->referenced_col_names = static_cast<const char**>( foreign->referenced_col_names = static_cast<const char**>(
mem_heap_alloc(foreign->heap, mem_heap_alloc(foreign->heap,
@@ -6493,7 +6493,7 @@ prepare_inplace_alter_table_dict(
new_clustered = (DICT_CLUSTERED & index_defs[0].ind_type) != 0; new_clustered = (DICT_CLUSTERED & index_defs[0].ind_type) != 0;
create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table, create_table_info_t info(ctx->prebuilt->trx->mysql_thd, altered_table,
ha_alter_info->create_info, NULL, NULL, ha_alter_info->create_info,
srv_file_per_table); srv_file_per_table);
/* The primary index would be rebuilt if a FTS Doc ID /* The primary index would be rebuilt if a FTS Doc ID
@@ -7904,8 +7904,6 @@ ha_innobase::prepare_inplace_alter_table(
create_table_info_t info(m_user_thd, create_table_info_t info(m_user_thd,
altered_table, altered_table,
ha_alter_info->create_info, ha_alter_info->create_info,
NULL,
NULL,
srv_file_per_table); srv_file_per_table);
info.set_tablespace_type(indexed_table->space != fil_system.sys_space); info.set_tablespace_type(indexed_table->space != fil_system.sys_space);

View File

@@ -411,28 +411,6 @@ dict_foreign_t*
dict_mem_foreign_create(void); dict_mem_foreign_create(void);
/*=========================*/ /*=========================*/
/**********************************************************************//**
Sets the foreign_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
will point to foreign_table_name. If 2, then another string is
allocated from the heap and set to lower case. */
void
dict_mem_foreign_table_name_lookup_set(
/*===================================*/
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc); /*!< in: is an alloc needed */
/**********************************************************************//**
Sets the referenced_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0 or 1, referenced_table_name_lookup
will point to referenced_table_name. If 2, then another string is
allocated from the heap and set to lower case. */
void
dict_mem_referenced_table_name_lookup_set(
/*======================================*/
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc); /*!< in: is an alloc needed */
/** Fills the dependent virtual columns in a set. /** Fills the dependent virtual columns in a set.
Reason for being dependent are Reason for being dependent are
1) FK can be present on base column of virtual columns 1) FK can be present on base column of virtual columns
@@ -1522,6 +1500,20 @@ struct dict_foreign_t{
/** Check whether the fulltext index gets affected by /** Check whether the fulltext index gets affected by
foreign key constraint */ foreign key constraint */
bool affects_fulltext() const; bool affects_fulltext() const;
/**********************************************************************//**
Sets the foreign_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
will point to foreign_table_name. If 2, then another string is
allocated from the heap and set to lower case. */
void foreign_table_name_lookup_set();
/**********************************************************************//**
Sets the referenced_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0 or 1, referenced_table_name_lookup
will point to referenced_table_name. If 2, then another string is
allocated from the heap and set to lower case. */
void referenced_table_name_lookup_set();
}; };
std::ostream& std::ostream&

View File

@@ -737,21 +737,6 @@ innobase_fts_text_cmp(
const void* p1, /*!< in: key */ const void* p1, /*!< in: key */
const void* p2); /*!< in: node */ const void* p2); /*!< in: node */
/******************************************************************//**
Makes all characters in a string lower case. */
extern
size_t
innobase_fts_casedn_str(
/*====================*/
CHARSET_INFO* cs, /*!< in: Character set */
char* src, /*!< in: string to put in
lower case */
size_t src_len, /*!< in: input string length */
char* dst, /*!< in: buffer for result
string */
size_t dst_len); /*!< in: buffer size */
/******************************************************************//** /******************************************************************//**
compare two character string according to their charset. */ compare two character string according to their charset. */
extern extern

View File

@@ -329,6 +329,16 @@ fts_string_dup(
const fts_string_t* src, /*!< in: src string */ const fts_string_t* src, /*!< in: src string */
mem_heap_t* heap); /*!< in: heap to use */ mem_heap_t* heap); /*!< in: heap to use */
/******************************************************************//**
Duplicate a string with lower case conversion. */
UNIV_INLINE
fts_string_t
fts_string_dup_casedn(
/*===========*/
CHARSET_INFO *cs,
const fts_string_t& src, /*!< in: src string */
mem_heap_t* heap); /*!< in: heap to use */
/******************************************************************//** /******************************************************************//**
Get the selected FTS aux INDEX suffix. */ Get the selected FTS aux INDEX suffix. */
UNIV_INLINE UNIV_INLINE

View File

@@ -46,6 +46,25 @@ fts_string_dup(
dst->f_n_char = src->f_n_char; dst->f_n_char = src->f_n_char;
} }
/******************************************************************//**
Duplicate a string with lower case conversion */
UNIV_INLINE
fts_string_t
fts_string_dup_casedn(
/*===========*/
CHARSET_INFO *cs, /*!< in: the character set */
const fts_string_t& src, /*!< in: src string */
mem_heap_t* heap) /*!< in: heap to use */
{
size_t dst_nbytes = src.f_len * cs->casedn_multiply() + 1;
fts_string_t dst;
dst.f_str = (byte*)mem_heap_alloc(heap, dst_nbytes);
dst.f_len = cs->casedn_z((const char *) src.f_str, src.f_len,
(char *) dst.f_str, dst_nbytes);
dst.f_n_char = src.f_n_char;
return dst;
}
/******************************************************************//** /******************************************************************//**
Compare two fts_trx_row_t doc_ids. Compare two fts_trx_row_t doc_ids.
@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ @return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */

View File

@@ -175,12 +175,6 @@ innobase_convert_from_id(
const char* from, /*!< in: identifier to convert */ const char* from, /*!< in: identifier to convert */
ulint len); /*!< in: length of 'to', in bytes; ulint len); /*!< in: length of 'to', in bytes;
should be at least 3 * strlen(to) + 1 */ should be at least 3 * strlen(to) + 1 */
/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
void
innobase_casedn_str(
/*================*/
char* a); /*!< in/out: string to put in lower case */
#ifdef WITH_WSREP #ifdef WITH_WSREP
ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
@@ -240,15 +234,6 @@ thd_lock_wait_timeout(
THD* thd); /*!< in: thread handle, or NULL to query THD* thd); /*!< in: thread handle, or NULL to query
the global innodb_lock_wait_timeout */ the global innodb_lock_wait_timeout */
/******************************************************************//**
compare two character string case insensitively according to their charset. */
int
innobase_fts_text_case_cmp(
/*=======================*/
const void* cs, /*!< in: Character set */
const void* p1, /*!< in: key */
const void* p2); /*!< in: node */
/******************************************************************//** /******************************************************************//**
Returns true if transaction should be flagged as read-only. Returns true if transaction should be flagged as read-only.
@return true if the thd is marked as read-only */ @return true if the thd is marked as read-only */
@@ -439,11 +424,13 @@ Normalizes a table name string. A normalized name consists of the
database name catenated to '/' and table name. An example: database name catenated to '/' and table name. An example:
test/mytable. On Windows normalization puts both the database name and the test/mytable. On Windows normalization puts both the database name and the
table name always to lower case if "set_lower_case" is set to TRUE. */ table name always to lower case if "set_lower_case" is set to TRUE. */
void size_t
normalize_table_name_c_low( normalize_table_name_c_low(
/*=======================*/ /*=======================*/
char* norm_name, /*!< out: normalized name as a char* norm_name, /*!< out: normalized name as a
null-terminated string */ null-terminated string */
size_t norm_name_size, /*!< in: number of bytes available
in norm_name*/
const char* name, /*!< in: table name string */ const char* name, /*!< in: table name string */
bool set_lower_case); /*!< in: true if we want to set bool set_lower_case); /*!< in: true if we want to set
name to lower case */ name to lower case */

View File

@@ -266,6 +266,24 @@ mem_heap_strdupl(mem_heap_t* heap, const char* str, size_t len)
return(static_cast<char*>(memcpy(s, str, len))); return(static_cast<char*>(memcpy(s, str, len)));
} }
/** Duplicate a string to a memory heap, with lower-case conversion
@param[in] heap memory heap where string is allocated
@param[in] cs the character set of the string
@param[in] str the source string
@return own: a NUL-terminated lower-cased copy of str */
inline
LEX_STRING
mem_heap_alloc_casedn_z(mem_heap_t *heap,
CHARSET_INFO *cs,
const LEX_CSTRING &str)
{
size_t nbytes= str.length * cs->casedn_multiply() + 1;
LEX_STRING res;
res.str= static_cast<char*>(mem_heap_alloc(heap, nbytes));
res.length= cs->casedn_z(str.str, str.length, res.str, nbytes);
return res;
}
/**********************************************************************//** /**********************************************************************//**
Concatenate two strings and return the result, using a memory heap. Concatenate two strings and return the result, using a memory heap.
@return own: the result */ @return own: the result */

View File

@@ -472,14 +472,12 @@ row_merge_fts_doc_tokenize(
ulint len; ulint len;
row_merge_buf_t* buf; row_merge_buf_t* buf;
dfield_t* field; dfield_t* field;
fts_string_t t_str;
ibool buf_full = FALSE; ibool buf_full = FALSE;
byte str_buf[FTS_MAX_WORD_LEN + 1]; CharBuffer<FTS_MAX_WORD_LEN> str_buf;
ulint data_size[FTS_NUM_AUX_INDEX]; ulint data_size[FTS_NUM_AUX_INDEX];
ulint n_tuple[FTS_NUM_AUX_INDEX]; ulint n_tuple[FTS_NUM_AUX_INDEX];
st_mysql_ftparser* parser; st_mysql_ftparser* parser;
t_str.f_n_char = 0;
t_ctx->buf_used = 0; t_ctx->buf_used = 0;
memset(n_tuple, 0, FTS_NUM_AUX_INDEX * sizeof(ulint)); memset(n_tuple, 0, FTS_NUM_AUX_INDEX * sizeof(ulint));
@@ -544,11 +542,8 @@ row_merge_fts_doc_tokenize(
continue; continue;
} }
t_str.f_len = innobase_fts_casedn_str( str_buf.copy_casedn(doc->charset,
doc->charset, (char*) str.f_str, str.f_len, LEX_CSTRING{(const char *) str.f_str, str.f_len});
(char*) &str_buf, FTS_MAX_WORD_LEN + 1);
t_str.f_str = (byte*) &str_buf;
/* if "cached_stopword" is defined, ignore words in the /* if "cached_stopword" is defined, ignore words in the
stopword list */ stopword list */
@@ -566,8 +561,8 @@ row_merge_fts_doc_tokenize(
/* There are FTS_NUM_AUX_INDEX auxiliary tables, find /* There are FTS_NUM_AUX_INDEX auxiliary tables, find
out which sort buffer to put this word record in */ out which sort buffer to put this word record in */
t_ctx->buf_used = fts_select_index( t_ctx->buf_used = fts_select_index(doc->charset,
doc->charset, t_str.f_str, t_str.f_len); (const byte*) str_buf.ptr(), str_buf.length());
buf = sort_buf[t_ctx->buf_used]; buf = sort_buf[t_ctx->buf_used];
@@ -581,7 +576,7 @@ row_merge_fts_doc_tokenize(
FTS_NUM_FIELDS_SORT * sizeof *field)); FTS_NUM_FIELDS_SORT * sizeof *field));
/* The first field is the tokenized word */ /* The first field is the tokenized word */
dfield_set_data(field, t_str.f_str, t_str.f_len); dfield_set_data(field, str_buf.ptr(), str_buf.length());
len = dfield_get_len(field); len = dfield_get_len(field);
dict_col_copy_type(dict_index_get_nth_col(buf->index, 0), &field->type); dict_col_copy_type(dict_index_get_nth_col(buf->index, 0), &field->type);

View File

@@ -2595,17 +2595,16 @@ row_rename_table_for_mysql(
/* Check for the table using lower /* Check for the table using lower
case name, including the partition case name, including the partition
separator "P" */ separator "P" */
memcpy(par_case_name, old_name, system_charset_info->casedn_z(
strlen(old_name)); old_name, strlen(old_name),
par_case_name[strlen(old_name)] = 0; par_case_name, sizeof(par_case_name));
innobase_casedn_str(par_case_name);
#else #else
/* On Windows platfrom, check /* On Windows platfrom, check
whether there exists table name in whether there exists table name in
system table whose name is system table whose name is
not being normalized to lower case */ not being normalized to lower case */
normalize_table_name_c_low( normalize_table_name_c_low(
par_case_name, old_name, FALSE); par_case_name, sizeof(par_case_name), old_name, FALSE);
#endif #endif
table = dict_table_open_on_name(par_case_name, true, table = dict_table_open_on_name(par_case_name, true,
DICT_ERR_IGNORE_FK_NOKEY); DICT_ERR_IGNORE_FK_NOKEY);

View File

@@ -120,8 +120,9 @@ int main(int argc,char *argv[])
if (subkeys.i >= 0) if (subkeys.i >= 0)
weight= subkeys.f; weight= subkeys.f;
snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey_buff+1); keylen= (uint) my_ci_casedn(default_charset_info, buf, sizeof(buf) - 1,
my_casedn_str(default_charset_info,buf); (char *) info->lastkey_buff + 1, keylen);
buf[keylen]= '\0';
total++; total++;
lengths[keylen]++; lengths[keylen]++;

View File

@@ -118,8 +118,9 @@ int main(int argc,char *argv[])
if (subkeys.i >= 0) if (subkeys.i >= 0)
weight= subkeys.f; weight= subkeys.f;
snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1); keylen= (uint) my_ci_casedn(default_charset_info, buf, sizeof(buf) - 1,
my_casedn_str(default_charset_info,buf); (char *) info->lastkey + 1, keylen);
buf[keylen]= '\0';
total++; total++;
lengths[keylen]++; lengths[keylen]++;

View File

@@ -231,13 +231,8 @@ extern "C" int myisammrg_parent_open_callback(void *callback_param,
ha_myisammrg *ha_myrg= (ha_myisammrg*) callback_param; ha_myisammrg *ha_myrg= (ha_myisammrg*) callback_param;
TABLE *parent= ha_myrg->table_ptr(); TABLE *parent= ha_myrg->table_ptr();
Mrg_child_def *mrg_child_def; Mrg_child_def *mrg_child_def;
char *db; LEX_STRING db, table_name;
char *table_name;
size_t dirlen;
size_t db_length;
size_t table_name_length;
char dir_path[FN_REFLEN]; char dir_path[FN_REFLEN];
char name_buf[NAME_LEN];
DBUG_ENTER("myisammrg_parent_open_callback"); DBUG_ENTER("myisammrg_parent_open_callback");
/* /*
@@ -249,70 +244,51 @@ extern "C" int myisammrg_parent_open_callback(void *callback_param,
if (!has_path(filename)) if (!has_path(filename))
{ {
/* Child is in the same database as parent. */ /* Child is in the same database as parent. */
db_length= parent->s->db.length; db= ha_myrg->make_child_ident(parent->s->db);
db= strmake_root(&ha_myrg->children_mem_root, parent->s->db.str, db_length);
/* Child table name is encoded in parent dot-MRG starting with 5.1.46. */ /* Child table name is encoded in parent dot-MRG starting with 5.1.46. */
if (parent->s->mysql_version >= 50146) table_name= (parent->s->mysql_version >= 50146) ?
{ ha_myrg->make_child_ident_filename_to_tablename(filename,
table_name_length= filename_to_tablename(filename, name_buf, lower_case_table_names) :
sizeof(name_buf)); ha_myrg->make_child_ident_opt_casedn(Lex_cstring_strlen(filename),
table_name= strmake_root(&ha_myrg->children_mem_root, name_buf, lower_case_table_names);
table_name_length);
}
else
{
table_name_length= strlen(filename);
table_name= strmake_root(&ha_myrg->children_mem_root, filename,
table_name_length);
}
} }
else else
{ {
DBUG_ASSERT(strlen(filename) < sizeof(dir_path)); DBUG_ASSERT(strlen(filename) < sizeof(dir_path));
fn_format(dir_path, filename, "", "", 0); fn_format(dir_path, filename, "", "", 0);
/* Extract child table name and database name from filename. */ /* Extract child table name and database name from filename. */
dirlen= dirname_length(dir_path); size_t dirlen= dirname_length(dir_path);
/* Child db/table name is encoded in parent dot-MRG starting with 5.1.6. */ /* Child db/table name is encoded in parent dot-MRG starting with 5.1.6. */
if (parent->s->mysql_version >= 50106) if (parent->s->mysql_version >= 50106)
{ {
table_name_length= filename_to_tablename(dir_path + dirlen, name_buf, table_name= ha_myrg->make_child_ident_filename_to_tablename(
sizeof(name_buf)); dir_path + dirlen,
table_name= strmake_root(&ha_myrg->children_mem_root, name_buf, lower_case_table_names);
table_name_length);
dir_path[dirlen - 1]= 0; dir_path[dirlen - 1]= 0;
dirlen= dirname_length(dir_path); dirlen= dirname_length(dir_path);
db_length= filename_to_tablename(dir_path + dirlen, name_buf, sizeof(name_buf)); db= ha_myrg->make_child_ident_filename_to_tablename(dir_path + dirlen,
db= strmake_root(&ha_myrg->children_mem_root, name_buf, db_length); false);
} }
else else
{ {
table_name_length= strlen(dir_path + dirlen); table_name= ha_myrg->make_child_ident_opt_casedn(
table_name= strmake_root(&ha_myrg->children_mem_root, dir_path + dirlen, Lex_cstring_strlen(dir_path + dirlen),
table_name_length); lower_case_table_names);
dir_path[dirlen - 1]= 0; dir_path[dirlen - 1]= 0;
dirlen= dirname_length(dir_path); dirlen= dirname_length(dir_path);
db_length= strlen(dir_path + dirlen); db= ha_myrg->make_child_ident(Lex_cstring_strlen(dir_path + dirlen));
db= strmake_root(&ha_myrg->children_mem_root, dir_path + dirlen,
db_length);
} }
} }
if (! db || ! table_name) if (! db.str || ! table_name.str)
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int) db_length, db, DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int) db.length, db.str,
(int) table_name_length, table_name)); (int) table_name.length, table_name.str));
/* Convert to lowercase if required. */
if (lower_case_table_names && table_name_length)
{
/* purecov: begin tested */
table_name_length= my_casedn_str(files_charset_info, table_name);
/* purecov: end */
}
mrg_child_def= new (&ha_myrg->children_mem_root) mrg_child_def= new (&ha_myrg->children_mem_root)
Mrg_child_def(db, db_length, table_name, table_name_length); Mrg_child_def(db.str, db.length,
table_name.str, table_name.length);
if (! mrg_child_def || if (! mrg_child_def ||
ha_myrg->child_def_list.push_back(mrg_child_def, ha_myrg->child_def_list.push_back(mrg_child_def,

View File

@@ -170,4 +170,45 @@ public:
int create_mrg(const char *name, HA_CREATE_INFO *create_info); int create_mrg(const char *name, HA_CREATE_INFO *create_info);
MYRG_INFO *myrg_info() { return file; } MYRG_INFO *myrg_info() { return file; }
TABLE *table_ptr() { return table; } TABLE *table_ptr() { return table; }
/*
Make an exact copy an identifier on children_mem_root.
@param src - The original identifier
@return - {NULL,0} in case of EOM,
or a non-NULL LEX_STRING with the identifier copy.
*/
LEX_STRING make_child_ident(const LEX_CSTRING &src)
{
return lex_string_strmake_root(&children_mem_root, src.str, src.length);
}
/*
Make an exact copy or a lower-cased copy of an identifier
on children mem_root.
@param src - The original identifier
@param casedn - If the name should be converted to lower case
@return - {NULL,0} in case of EOM,
or a non-NULL LEX_STRING with the identifier copy.
*/
LEX_STRING make_child_ident_opt_casedn(const LEX_CSTRING &src, bool casedn)
{
return casedn ? lex_string_casedn_root(&children_mem_root,
&my_charset_utf8mb3_general_ci,
src.str, src.length) :
make_child_ident(src);
}
/*
Make an optionally lower-cases filename_to_tablename-decoded identifier
in chirdren mem_root.
*/
LEX_STRING make_child_ident_filename_to_tablename(const char *src,
bool casedn)
{
char buf[NAME_LEN];
size_t len= filename_to_tablename(src, buf, sizeof(buf));
return make_child_ident_opt_casedn({buf, len}, casedn);
}
}; };

View File

@@ -466,36 +466,22 @@ LF_PINS* get_table_share_hash_pins(PFS_thread *thread)
@param table_name The table name. @param table_name The table name.
@param table_name_length The table name length. @param table_name_length The table name length.
*/ */
static void set_table_share_key(PFS_table_share_key *key, void PFS_table_share_key::set(bool temporary,
bool temporary, const char *schema_name,
const char *schema_name, size_t schema_name_length, size_t schema_name_length,
const char *table_name, size_t table_name_length) const char *table_name,
size_t table_name_length)
{ {
assert(schema_name_length <= NAME_LEN); assert(schema_name_length <= NAME_LEN);
assert(table_name_length <= NAME_LEN); assert(table_name_length <= NAME_LEN);
char *saved_schema_name;
char *saved_table_name;
char *ptr= &key->m_hash_key[0]; m_hash_key[0]= (temporary ? OBJECT_TYPE_TEMPORARY_TABLE : OBJECT_TYPE_TABLE);
ptr[0]= (temporary ? OBJECT_TYPE_TEMPORARY_TABLE : OBJECT_TYPE_TABLE); m_key_length= 1;
ptr++;
saved_schema_name= ptr;
memcpy(ptr, schema_name, schema_name_length);
ptr+= schema_name_length;
ptr[0]= 0;
ptr++;
saved_table_name= ptr;
memcpy(ptr, table_name, table_name_length);
ptr+= table_name_length;
ptr[0]= 0;
ptr++;
key->m_key_length= (uint)(ptr - &key->m_hash_key[0]);
if (lower_case_table_names) append_opt_casedn_z(files_charset_info, schema_name, schema_name_length,
{ lower_case_table_names);
my_casedn_str(files_charset_info, saved_schema_name); append_opt_casedn_z(files_charset_info, table_name, table_name_length,
my_casedn_str(files_charset_info, saved_table_name); lower_case_table_names);
}
} }
/** /**
@@ -1740,8 +1726,7 @@ PFS_table_share* find_or_create_table_share(PFS_thread *thread,
const char *table_name= share->table_name.str; const char *table_name= share->table_name.str;
size_t table_name_length= share->table_name.length; size_t table_name_length= share->table_name.length;
set_table_share_key(&key, temporary, key.set(temporary, schema_name, schema_name_length,
schema_name, schema_name_length,
table_name, table_name_length); table_name, table_name_length);
PFS_table_share **entry; PFS_table_share **entry;
@@ -1953,7 +1938,7 @@ void drop_table_share(PFS_thread *thread,
LF_PINS* pins= get_table_share_hash_pins(thread); LF_PINS* pins= get_table_share_hash_pins(thread);
if (unlikely(pins == NULL)) if (unlikely(pins == NULL))
return; return;
set_table_share_key(&key, temporary, schema_name, schema_name_length, key.set(temporary, schema_name, schema_name_length,
table_name, table_name_length); table_name, table_name_length);
PFS_table_share **entry; PFS_table_share **entry;
entry= reinterpret_cast<PFS_table_share**> entry= reinterpret_cast<PFS_table_share**>

View File

@@ -265,6 +265,46 @@ struct PFS_table_share_key
char m_hash_key[PFS_TABLESHARE_HASHKEY_SIZE]; char m_hash_key[PFS_TABLESHARE_HASHKEY_SIZE];
/** Length in bytes of @c m_hash_key. */ /** Length in bytes of @c m_hash_key. */
uint m_key_length; uint m_key_length;
size_t available_length() const
{
return sizeof(m_hash_key) - m_key_length;
}
char *end()
{
return m_hash_key + m_key_length;
}
void set(bool temporary,
const char *schema_name, size_t schema_name_length,
const char *table_name, size_t table_name_length);
private:
// Append and 0-terminate a string with an optional lower-case conversion
void append_opt_casedn_z(CHARSET_INFO *cs,
const char *str, size_t length,
bool casedn)
{
DBUG_ASSERT(length <= sizeof(m_hash_key)); // Expect valid db/tbl names
size_t dst_length= available_length();
if (dst_length > 0)
{
dst_length--;
DBUG_ASSERT(dst_length >= length);
if (casedn)
{
m_key_length+= (uint) cs->casedn(str, length, end(), dst_length);
}
else
{
set_if_smaller(length, dst_length); // Safety for release builds
memcpy(end(), str, length);
m_key_length+= (uint) length;
}
m_hash_key[m_key_length++]= '\0';
}
}
}; };
/** Table index or 'key' */ /** Table index or 'key' */

View File

@@ -118,31 +118,21 @@ static void set_program_key(PFS_program_key *key,
*/ */
char *ptr= &key->m_hash_key[0]; char *ptr= &key->m_hash_key[0];
const char *end= ptr + sizeof(key->m_hash_key) - 1;
ptr[0]= object_type; ptr[0]= object_type;
ptr++; ptr++;
if (object_name_length > 0) if (object_name_length > 0)
{ ptr+= system_charset_info->casedn(object_name, object_name_length,
char tmp_object_name[COL_OBJECT_NAME_SIZE + 1]; ptr, end - ptr);
memcpy(tmp_object_name, object_name, object_name_length);
tmp_object_name[object_name_length]= '\0';
my_casedn_str(system_charset_info, tmp_object_name);
memcpy(ptr, tmp_object_name, object_name_length);
ptr+= object_name_length;
}
ptr[0]= 0; ptr[0]= 0;
ptr++; ptr++;
if (schema_name_length > 0) if (schema_name_length > 0)
{ ptr+= system_charset_info->opt_casedn(schema_name, schema_name_length,
char tmp_schema_name[COL_OBJECT_SCHEMA_SIZE + 1]; ptr, end - ptr,
memcpy(tmp_schema_name, schema_name, schema_name_length); lower_case_table_names);
tmp_schema_name[schema_name_length]='\0';
my_casedn_str(system_charset_info, tmp_schema_name);
memcpy(ptr, tmp_schema_name, schema_name_length);
ptr+= schema_name_length;
}
ptr[0]= 0; ptr[0]= 0;
ptr++; ptr++;

View File

@@ -40,6 +40,8 @@ void test_oom()
PFS_thread pfs_thread; PFS_thread pfs_thread;
PFS_table_share *pfs_table_share; PFS_table_share *pfs_table_share;
files_charset_info= &my_charset_utf8mb3_general_ci;
rc= init_sync_class(1000, 0, 0); rc= init_sync_class(1000, 0, 0);
ok(rc == 1, "oom (mutex)"); ok(rc == 1, "oom (mutex)");
rc= init_sync_class(0, 1000, 0); rc= init_sync_class(0, 1000, 0);

View File

@@ -225,8 +225,6 @@ mc_mb - converts the given Unicode code into multi-byte sequence.
Case and sort conversion Case and sort conversion
------------------------ ------------------------
caseup_str - converts the given 0-terminated string to uppercase
casedn_str - converts the given 0-terminated string to lowercase
caseup - converts the given string to lowercase using length caseup - converts the given string to lowercase using length
casedn - converts the given string to lowercase using length casedn - converts the given string to lowercase using length

View File

@@ -6807,8 +6807,6 @@ static MY_CHARSET_HANDLER my_charset_big5_handler=
my_mb_wc_big5, /* mb_wc */ my_mb_wc_big5, /* mb_wc */
my_wc_mb_big5, /* wc_mb */ my_wc_mb_big5, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, my_caseup_mb,
my_casedn_mb, my_casedn_mb,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -236,15 +236,6 @@ static int my_strnncollsp_8bit_nopad_bin(CHARSET_INFO * cs
} }
/* This function is used for all conversion functions */
static size_t my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)),
char *str __attribute__((unused)))
{
return 0;
}
static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)), static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)),
const char *src, size_t srclen, const char *src, size_t srclen,
char *dst, size_t dstlen __attribute__((unused))) char *dst, size_t dstlen __attribute__((unused)))
@@ -583,8 +574,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_bin, my_mb_wc_bin,
my_wc_mb_bin, my_wc_mb_bin,
my_mb_ctype_8bit, my_mb_ctype_8bit,
my_case_str_bin,
my_case_str_bin,
my_case_bin, my_case_bin,
my_case_bin, my_case_bin,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -34764,8 +34764,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_cp932, /* mb_wc */ my_mb_wc_cp932, /* mb_wc */
my_wc_mb_cp932, /* wc_mb */ my_wc_mb_cp932, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, my_caseup_mb,
my_casedn_mb, my_casedn_mb,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -10054,8 +10054,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_euc_kr, /* mb_wc */ my_mb_wc_euc_kr, /* mb_wc */
my_wc_mb_euc_kr, /* wc_mb */ my_wc_mb_euc_kr, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, /* UPPER() can reduce length: Turkish DOTLESS i -> I */ my_caseup_mb, /* UPPER() can reduce length: Turkish DOTLESS i -> I */
my_casedn_mb, /* LOWER() does not change length */ my_casedn_mb, /* LOWER() does not change length */
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -67592,8 +67592,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_eucjpms, /* mb_wc */ my_mb_wc_eucjpms, /* mb_wc */
my_wc_mb_eucjpms, /* wc_mb */ my_wc_mb_eucjpms, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_ujis, my_caseup_ujis,
my_casedn_ujis, my_casedn_ujis,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -6458,8 +6458,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_gb2312, /* mb_wc */ my_mb_wc_gb2312, /* mb_wc */
my_wc_mb_gb2312, /* wc_mb */ my_wc_mb_gb2312, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, my_caseup_mb,
my_casedn_mb, my_casedn_mb,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -10739,8 +10739,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_gbk, my_mb_wc_gbk,
my_wc_mb_gbk, my_wc_mb_gbk,
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, my_caseup_mb,
my_casedn_mb, my_casedn_mb,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -407,8 +407,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_latin1, my_mb_wc_latin1,
my_wc_mb_latin1, my_wc_mb_latin1,
my_mb_ctype_8bit, my_mb_ctype_8bit,
my_caseup_str_8bit,
my_casedn_str_8bit,
my_caseup_8bit, my_caseup_8bit,
my_casedn_8bit, my_casedn_8bit,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -21,48 +21,6 @@
#ifdef USE_MB #ifdef USE_MB
size_t my_caseup_str_mb(CHARSET_INFO * cs, char *str)
{
register uint32 l;
register const uchar *map= cs->to_upper;
char *str_orig= str;
while (*str)
{
/* Pointing after the '\0' is safe here. */
if ((l= my_ismbchar(cs, str, str + cs->mbmaxlen)))
str+= l;
else
{
*str= (char) map[(uchar)*str];
str++;
}
}
return (size_t) (str - str_orig);
}
size_t my_casedn_str_mb(CHARSET_INFO * cs, char *str)
{
register uint32 l;
register const uchar *map= cs->to_lower;
char *str_orig= str;
while (*str)
{
/* Pointing after the '\0' is safe here. */
if ((l= my_ismbchar(cs, str, str + cs->mbmaxlen)))
str+= l;
else
{
*str= (char) map[(uchar)*str];
str++;
}
}
return (size_t) (str - str_orig);
}
static inline const MY_CASEFOLD_CHARACTER* static inline const MY_CASEFOLD_CHARACTER*
get_case_info_for_ch(CHARSET_INFO *cs, uint page, uint offs) get_case_info_for_ch(CHARSET_INFO *cs, uint page, uint offs)
{ {

View File

@@ -2143,8 +2143,6 @@ MY_CHARSET_HANDLER my_charset_8bit_handler=
my_mb_wc_8bit, my_mb_wc_8bit,
my_wc_mb_8bit, my_wc_mb_8bit,
my_mb_ctype_8bit, my_mb_ctype_8bit,
my_caseup_str_8bit,
my_casedn_str_8bit,
my_caseup_8bit, my_caseup_8bit,
my_casedn_8bit, my_casedn_8bit,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -34152,8 +34152,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_sjis, /* mb_wc */ my_mb_wc_sjis, /* mb_wc */
my_wc_mb_sjis, /* wc_mb */ my_wc_mb_sjis, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb,
my_casedn_str_mb,
my_caseup_mb, my_caseup_mb,
my_casedn_mb, my_casedn_mb,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -914,8 +914,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_mb_wc_tis620, /* mb_wc */ my_mb_wc_tis620, /* mb_wc */
my_wc_mb_tis620, /* wc_mb */ my_wc_mb_tis620, /* wc_mb */
my_mb_ctype_8bit, my_mb_ctype_8bit,
my_caseup_str_8bit,
my_casedn_str_8bit,
my_caseup_8bit, my_caseup_8bit,
my_casedn_8bit, my_casedn_8bit,
my_snprintf_8bit, my_snprintf_8bit,

View File

@@ -55,23 +55,6 @@ static unsigned long lfactor[9]=
#ifdef HAVE_CHARSET_mb2_or_mb4 #ifdef HAVE_CHARSET_mb2_or_mb4
static size_t
my_caseup_str_mb2_or_mb4(CHARSET_INFO * cs __attribute__((unused)),
char * s __attribute__((unused)))
{
DBUG_ASSERT(0);
return 0;
}
static size_t
my_casedn_str_mb2_or_mb4(CHARSET_INFO *cs __attribute__((unused)),
char * s __attribute__((unused)))
{
DBUG_ASSERT(0);
return 0;
}
static int static int
my_strcasecmp_mb2_or_mb4(CHARSET_INFO *cs __attribute__((unused)), my_strcasecmp_mb2_or_mb4(CHARSET_INFO *cs __attribute__((unused)),
@@ -1567,8 +1550,6 @@ MY_CHARSET_HANDLER my_charset_utf16_handler=
my_utf16_uni, /* mb_wc */ my_utf16_uni, /* mb_wc */
my_uni_utf16, /* wc_mb */ my_uni_utf16, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb2_or_mb4,
my_casedn_str_mb2_or_mb4,
my_caseup_utf16, my_caseup_utf16,
my_casedn_utf16, my_casedn_utf16,
my_snprintf_mb2, my_snprintf_mb2,
@@ -1920,8 +1901,6 @@ static MY_CHARSET_HANDLER my_charset_utf16le_handler=
my_utf16le_uni, /* mb_wc */ my_utf16le_uni, /* mb_wc */
my_uni_utf16le, /* wc_mb */ my_uni_utf16le, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb2_or_mb4,
my_casedn_str_mb2_or_mb4,
my_caseup_utf16, my_caseup_utf16,
my_casedn_utf16, my_casedn_utf16,
my_snprintf_mb2, my_snprintf_mb2,
@@ -2719,8 +2698,6 @@ MY_CHARSET_HANDLER my_charset_utf32_handler=
my_utf32_uni, my_utf32_uni,
my_uni_utf32, my_uni_utf32,
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb2_or_mb4,
my_casedn_str_mb2_or_mb4,
my_caseup_utf32, my_caseup_utf32,
my_casedn_utf32, my_casedn_utf32,
my_snprintf_utf32, my_snprintf_utf32,
@@ -3334,8 +3311,6 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
my_ucs2_uni, /* mb_wc */ my_ucs2_uni, /* mb_wc */
my_uni_ucs2, /* wc_mb */ my_uni_ucs2, /* wc_mb */
my_mb_ctype_mb, my_mb_ctype_mb,
my_caseup_str_mb2_or_mb4,
my_casedn_str_mb2_or_mb4,
my_caseup_ucs2, my_caseup_ucs2,
my_casedn_ucs2, my_casedn_ucs2,
my_snprintf_mb2, my_snprintf_mb2,

Some files were not shown because too many files have changed in this diff Show More