mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Fixed that LPAD() and RPAD() cuts arguments
New test for string functions
This commit is contained in:
parent
36c7d4eb02
commit
b186b4f27a
9 changed files with 168 additions and 29 deletions
|
@ -1,6 +1 @@
|
|||
jani@prima.mysql.com
|
||||
jani@prima.mysql.fi
|
||||
monty@donna.mysql.com
|
||||
sasha@mysql.sashanet.com
|
||||
sasha@work.mysql.com
|
||||
serg@serg.mysql.com
|
||||
monty@tik.mysql.com
|
||||
|
|
|
@ -9778,8 +9778,7 @@ the sort order!
|
|||
@item The default return type of @code{IF} will now depend on both arguments
|
||||
and not only the first argument.
|
||||
@item @code{AUTO_INCREMENT} will not work with negative numbers.
|
||||
@item @code{INNER}, @code{DELAYED}, @code{RIGHT} and @code{WHEN}
|
||||
are now reserved words.
|
||||
@item @code{INNER}, @code{DELAYED}, @code{RIGHT}, @code{CASE}, @code{THEN}, @code{WHEN}, @code{ELSE}, @code{END} and @code{WHEN} are now reserved words.
|
||||
@item @code{FLOAT(X)} is now a true floating-point type and not a value with
|
||||
a fixed number of decimals.
|
||||
@item When declaring @code{DECIMAL(length,dec)} the length argument no
|
||||
|
@ -9816,10 +9815,11 @@ almost always sorted. In Version 3.23, you must use @code{GROUP BY} or
|
|||
@item
|
||||
@code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching
|
||||
rows. This is according to ANSI SQL.
|
||||
@item New restricted words: @code{CASE, THEN, WHEN, ELSE, END, and RIGHT}.
|
||||
@item An @code{AND} or @code{OR} with @code{NULL} values will now return
|
||||
@code{NULL} instead of 0. This mostly affects queries that use @code{NOT}
|
||||
on an @code{AND/OR} expression as @code{NOT NULL} = @code{NULL}.
|
||||
@code{LPAD()} and @code{RPAD()} will shorten the result string if it's longer
|
||||
than the length argument.
|
||||
@end itemize
|
||||
|
||||
@cindex compatibility, between MySQL versions
|
||||
|
@ -14389,11 +14389,13 @@ The values retrieved from the @code{CHAR(4)} and @code{VARCHAR(4)} columns
|
|||
will be the same in each case, because trailing spaces are removed from
|
||||
@code{CHAR} columns upon retrieval.
|
||||
|
||||
Values in @code{CHAR} and @code{VARCHAR} columns are sorted and compared in
|
||||
case-insensitive fashion, unless the @code{BINARY} attribute was specified
|
||||
when the table was created. The @code{BINARY} attribute means that column
|
||||
values are sorted and compared in case-sensitive fashion according to the
|
||||
ASCII order of the machine where the @strong{MySQL} server is running.
|
||||
Values in @code{CHAR} and @code{VARCHAR} columns are sorted and compared
|
||||
in case-insensitive fashion, unless the @code{BINARY} attribute was
|
||||
specified when the table was created. The @code{BINARY} attribute means
|
||||
that column values are sorted and compared in case-sensitive fashion
|
||||
according to the ASCII order of the machine where the @strong{MySQL}
|
||||
server is running. @code{BINARY} doesn't affect how the column is stored
|
||||
or retrieved.
|
||||
|
||||
The @code{BINARY} attribute is sticky. This means that if a column marked
|
||||
@code{BINARY} is used in an expression, the whole expression is compared as a
|
||||
|
@ -14831,6 +14833,11 @@ between function calls and references to tables or columns that happen to
|
|||
have the same name as a function. Spaces around arguments are permitted,
|
||||
though.
|
||||
|
||||
You can force @strong{MySQL} to accept spaces after the function name by
|
||||
starting @code{mysqld} with @code{--ansi} or using the
|
||||
@code{CLIENT_IGNORE_SPACE} to @code{mysql_connect()}, but in this case all
|
||||
function names will become reserved words. @xref{ANSI mode}.
|
||||
|
||||
@need 2000
|
||||
For the sake of brevity, examples display the output from the @code{mysql}
|
||||
program in abbreviated form. So this:
|
||||
|
@ -16160,8 +16167,9 @@ This function is multi-byte safe.
|
|||
|
||||
@findex LPAD()
|
||||
@item LPAD(str,len,padstr)
|
||||
Returns the string @code{str}, left-padded with the string
|
||||
@code{padstr} until @code{str} is @code{len} characters long:
|
||||
Returns the string @code{str}, left-padded with the string @code{padstr}
|
||||
until @code{str} is @code{len} characters long. If @code{str} is longer
|
||||
than @code{len'} then it will be shortened to @code{len} characters.
|
||||
|
||||
@example
|
||||
mysql> select LPAD('hi',4,'??');
|
||||
|
@ -16171,7 +16179,10 @@ mysql> select LPAD('hi',4,'??');
|
|||
@findex RPAD()
|
||||
@item RPAD(str,len,padstr)
|
||||
Returns the string @code{str}, right-padded with the string
|
||||
@code{padstr} until @code{str} is @code{len} characters long.
|
||||
@code{padstr} until @code{str} is @code{len} characters long. If
|
||||
@code{str} is longer than @code{len'} then it will be shortened to
|
||||
@code{len} characters.
|
||||
|
||||
@example
|
||||
mysql> select RPAD('hi',5,'?');
|
||||
-> 'hi???'
|
||||
|
@ -20624,6 +20635,12 @@ threads. Otherwise, you can see only your own threads. @xref{KILL, ,
|
|||
@code{KILL}}. If you don't use the @code{FULL} option, then only
|
||||
the first 100 characters of each query will be shown.
|
||||
|
||||
This command is very useful if you get the 'too many connections' error
|
||||
message and want to find out what's going on. @strong{MySQL} reserves
|
||||
one extra connection for a client with the @code{Process_priv} privilege
|
||||
to ensure that you should always be able to login and check the system
|
||||
(assuming you are not giving this privilege to all your users).
|
||||
|
||||
@cindex privileges, display
|
||||
@node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW
|
||||
@subsection SHOW GRANTS (Privileges) for a User
|
||||
|
@ -26846,8 +26863,8 @@ statement. In this case the last @code{SELECT} statement in the previous
|
|||
scenario would execute before the @code{INSERT} statement.
|
||||
|
||||
@item
|
||||
You can give a specific @code{INSERT}, @code{UPDATE}, or @code{DELETE} statement
|
||||
lower priority with the @code{LOW_PRIORITY} attribute.
|
||||
You can give a specific @code{INSERT}, @code{UPDATE}, or @code{DELETE}
|
||||
statement lower priority with the @code{LOW_PRIORITY} attribute.
|
||||
|
||||
@item
|
||||
Start @code{mysqld} with a low value for @strong{max_write_lock_count} to give
|
||||
|
@ -39765,6 +39782,11 @@ though, so Version 3.23 is not released as a stable version yet.
|
|||
@appendixsubsec Changes in release 3.23.29
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed bug in @code{REPLACE} with BDB tables.
|
||||
@item
|
||||
@code{LPAD()} and @code{RPAD()} will shorten the result string if it's longer
|
||||
than the length argument.
|
||||
@item
|
||||
Remove not used BDB logs on shutdown.
|
||||
@item
|
||||
When creating a table, put @code{PRIMARY} keys first, followed by
|
||||
|
@ -44994,6 +45016,17 @@ using @code{-O thread_cache_size= 5'} will help a lot!
|
|||
|
||||
If you want to get a core dump on Linux if @code{mysqld} dies with a
|
||||
SIGSEGV signal, you can start mysqld with the @code{--core-file} option.
|
||||
This core file can be used to make a backtrace that may help you
|
||||
find out why @code{mysqld} died:
|
||||
|
||||
@example
|
||||
shell> gdb mysqld core
|
||||
gdb> backtrace
|
||||
gdb> info local
|
||||
gdb> exit
|
||||
@end example
|
||||
|
||||
@xref{Crashing}.
|
||||
|
||||
If you are using gdb 4.17.x or above on Linux, you should install a
|
||||
@file{.gdb} file, with the following information, in your current
|
||||
|
|
|
@ -660,11 +660,10 @@ static uint getTableStructure(char *table, char* db)
|
|||
strpos=strend(insert_pat);
|
||||
while ((row=mysql_fetch_row(tableRes)))
|
||||
{
|
||||
ulong *lengths=mysql_fetch_lengths(tableRes);
|
||||
if (init)
|
||||
{
|
||||
if (cFlag)
|
||||
strpos=strmov(strpos,", ");
|
||||
strpos=strmov(strpos,", ");
|
||||
}
|
||||
init=1;
|
||||
if (cFlag)
|
||||
|
|
|
@ -531,8 +531,8 @@ static void read_user_name(char *name)
|
|||
|
||||
static void read_user_name(char *name)
|
||||
{
|
||||
char *str=getenv("USER");
|
||||
strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */
|
||||
char *str=getenv("USER"); /* ODBC will send user variable */
|
||||
strmake(name,str ? str : "ODBC", USERNAME_LENGTH);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1149,8 +1149,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
const char *passwd, const char *db,
|
||||
uint port, const char *unix_socket,uint client_flag)
|
||||
{
|
||||
char buff[NAME_LEN+100],charset_name_buff[16],*end,*host_info,
|
||||
*charset_name;
|
||||
char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
|
||||
char *end,*host_info,*charset_name;
|
||||
my_socket sock;
|
||||
uint32 ip_addr;
|
||||
struct sockaddr_in sock_addr;
|
||||
|
|
62
mysql-test/r/strfunc.result
Normal file
62
mysql-test/r/strfunc.result
Normal file
|
@ -0,0 +1,62 @@
|
|||
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
|
||||
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
|
||||
hello
|
||||
hellomonty
|
||||
length('\n\t\r\b\0\_\%\\')
|
||||
10
|
||||
concat('monty',' was here ','again') length('hello') char(ascii('h'))
|
||||
monty was here again 5 h
|
||||
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
|
||||
1 0 4
|
||||
instr('hello','he')
|
||||
1
|
||||
position('ll' in 'hello') position('a' in 'hello')
|
||||
3 0
|
||||
left('hello',2) right('hello',2) substring('hello',2,2) mid('hello',1,5)
|
||||
he lo el hello
|
||||
concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1))
|
||||
happy
|
||||
substring_index('www.tcx.se','.',-2) substring_index('www.tcx.se','.',1)
|
||||
tcx.se www
|
||||
substring_index('www.tcx.se','tcx',1) substring_index('www.tcx.se','tcx',-1)
|
||||
www. .se
|
||||
substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1)
|
||||
tcx.se .se
|
||||
concat(':',ltrim(' left '),':',rtrim(' right '),':')
|
||||
:left : right:
|
||||
concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':')
|
||||
:left: right:
|
||||
concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':')
|
||||
:m:y:s:
|
||||
concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':')
|
||||
:my:sql:
|
||||
concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':')
|
||||
:my:sql:
|
||||
insert('txs',2,1,'hi') insert('is ',4,0,'a') insert('txxxxt',2,4,'es')
|
||||
this is a test
|
||||
replace('aaaa','a','b') replace('aaaa','aa','b') replace('aaaa','a','bb') replace('aaaa','','b') replace('bbbb','a','c')
|
||||
bbbb bb bbbbbbbb aaaa bbbb
|
||||
replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL')
|
||||
this is a REAL test
|
||||
soundex('') soundex('he') soundex('hello all folks')
|
||||
H000 H4142
|
||||
password('test') length(encrypt('test')) encrypt('test','aa')
|
||||
378b243e220ca493 13 aaqPiZY5xR5l.
|
||||
md5('hello')
|
||||
5d41402abc4b2a76b9719d911017c592
|
||||
repeat('monty',5) concat('*',space(5),'*')
|
||||
montymontymontymontymonty * *
|
||||
reverse('abc') reverse('abcd')
|
||||
cba dcba
|
||||
rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12')
|
||||
a111 a121 abc
|
||||
lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12')
|
||||
111a 121a abc
|
||||
rpad(741653838,17,'0') lpad(741653838,17,'0')
|
||||
74165383800000000 00000000741653838
|
||||
rpad('abcd',7,'ab') lpad('abcd',7,'ab')
|
||||
abcdaba abaabcd
|
||||
rpad('abcd',1,'ab') lpad('abcd',1,'ab')
|
||||
a a
|
||||
LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD') GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD')
|
||||
HAROLD HARRY
|
40
mysql-test/t/strfunc.test
Normal file
40
mysql-test/t/strfunc.test
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Version: 3.23.29
|
||||
#
|
||||
# Description
|
||||
# -----------
|
||||
# Testing string functions
|
||||
|
||||
select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
|
||||
select 'hello' 'monty';
|
||||
select length('\n\t\r\b\0\_\%\\');
|
||||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
select instr('hello','he');
|
||||
select position('ll' in 'hello'),position('a' in 'hello');
|
||||
select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
|
||||
select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
|
||||
select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
|
||||
select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1);
|
||||
select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1);
|
||||
|
||||
select concat(':',ltrim(' left '),':',rtrim(' right '),':');
|
||||
select concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':');
|
||||
select concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':');
|
||||
select concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':');
|
||||
select concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':');
|
||||
|
||||
select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
|
||||
select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
|
||||
select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
|
||||
select soundex(''),soundex('he'),soundex('hello all folks');
|
||||
select password('test'),length(encrypt('test')),encrypt('test','aa');
|
||||
select md5('hello');
|
||||
select repeat('monty',5),concat('*',space(5),'*');
|
||||
select reverse('abc'),reverse('abcd');
|
||||
select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12');
|
||||
select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12');
|
||||
select rpad(741653838,17,'0'),lpad(741653838,17,'0');
|
||||
select rpad('abcd',7,'ab'),lpad('abcd',7,'ab');
|
||||
select rpad('abcd',1,'ab'),lpad('abcd',1,'ab');
|
||||
|
||||
select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD');
|
|
@ -615,7 +615,7 @@ void handler::print_error(int error, myf errflag)
|
|||
|
||||
uint handler::get_dup_key(int error)
|
||||
{
|
||||
DBUG_ENTER("key_error");
|
||||
DBUG_ENTER("get_dup_key");
|
||||
table->file->errkey = (uint) -1;
|
||||
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE)
|
||||
info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
|
||||
|
|
|
@ -1465,7 +1465,10 @@ String *Item_func_rpad::val_str(String *str)
|
|||
goto err;
|
||||
null_value=0;
|
||||
if (count <= (int32) (res_length=res->length()))
|
||||
return (res); // String to pad is big enough
|
||||
{ // String to pad is big enough
|
||||
res->length(count); // Shorten result if longer
|
||||
return (res);
|
||||
}
|
||||
length_pad= rpad->length();
|
||||
if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad)
|
||||
goto err;
|
||||
|
@ -1521,7 +1524,10 @@ String *Item_func_lpad::val_str(String *str)
|
|||
goto err;
|
||||
null_value=0;
|
||||
if (count <= (res_length=res->length()))
|
||||
return (res); // String to pad is big enough
|
||||
{ // String to pad is big enough
|
||||
res->length(count); // Shorten result if longer
|
||||
return (res);
|
||||
}
|
||||
length_pad= lpad->length();
|
||||
if (count > max_allowed_packet || args[2]->null_value || !length_pad)
|
||||
goto err;
|
||||
|
|
|
@ -1042,7 +1042,11 @@ static void init_signals(void)
|
|||
|
||||
static sig_handler write_core(int sig)
|
||||
{
|
||||
fprintf(stderr,"Got signal %s in thread %d\n",sys_siglist[sig],getpid());
|
||||
fprintf(stderr,"\
|
||||
mysqld got signal %s in thread %d; Writing core file: %s\n\
|
||||
The manual section 'Debugging a MySQL server' tells you how to use a \n\
|
||||
debugger on the core file to produce a backtrace that may help you find out\n\
|
||||
why mysqld died\n",sys_siglist[sig],getpid(),mysql_home);
|
||||
signal(sig, SIG_DFL);
|
||||
if (fork() != 0) exit(1); // Abort main program
|
||||
// Core will be written at exit
|
||||
|
|
Loading…
Reference in a new issue