Commit c13d6386 authored by unknown's avatar unknown

Fixed that LPAD() and RPAD() cuts arguments

New test for string functions


Docs/manual.texi:
  Updated changes for 3.23.29
client/mysqldump.c:
  Cleanup
libmysql/libmysql.c:
  Fixed possible overflow
sql/handler.cc:
  Fixed typo
sql/item_strfunc.cc:
  Fixed that LPAD() and RPAD() cuts arguments
sql/mysqld.cc:
  Better error message on core dump
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent 3e2df584
jani@prima.mysql.com monty@tik.mysql.com
jani@prima.mysql.fi
monty@donna.mysql.com
sasha@mysql.sashanet.com
sasha@work.mysql.com
serg@serg.mysql.com
...@@ -9778,8 +9778,7 @@ the sort order! ...@@ -9778,8 +9778,7 @@ the sort order!
@item The default return type of @code{IF} will now depend on both arguments @item The default return type of @code{IF} will now depend on both arguments
and not only the first argument. and not only the first argument.
@item @code{AUTO_INCREMENT} will not work with negative numbers. @item @code{AUTO_INCREMENT} will not work with negative numbers.
@item @code{INNER}, @code{DELAYED}, @code{RIGHT} and @code{WHEN} @item @code{INNER}, @code{DELAYED}, @code{RIGHT}, @code{CASE}, @code{THEN}, @code{WHEN}, @code{ELSE}, @code{END} and @code{WHEN} are now reserved words.
are now reserved words.
@item @code{FLOAT(X)} is now a true floating-point type and not a value with @item @code{FLOAT(X)} is now a true floating-point type and not a value with
a fixed number of decimals. a fixed number of decimals.
@item When declaring @code{DECIMAL(length,dec)} the length argument no @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 ...@@ -9816,10 +9815,11 @@ almost always sorted. In Version 3.23, you must use @code{GROUP BY} or
@item @item
@code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching @code{SUM()} now returns @code{NULL}, instead of 0, if there is no matching
rows. This is according to ANSI SQL. 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 @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} @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}. 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 @end itemize
@cindex compatibility, between MySQL versions @cindex compatibility, between MySQL versions
...@@ -14389,11 +14389,13 @@ The values retrieved from the @code{CHAR(4)} and @code{VARCHAR(4)} columns ...@@ -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 will be the same in each case, because trailing spaces are removed from
@code{CHAR} columns upon retrieval. @code{CHAR} columns upon retrieval.
Values in @code{CHAR} and @code{VARCHAR} columns are sorted and compared in Values in @code{CHAR} and @code{VARCHAR} columns are sorted and compared
case-insensitive fashion, unless the @code{BINARY} attribute was specified in case-insensitive fashion, unless the @code{BINARY} attribute was
when the table was created. The @code{BINARY} attribute means that column specified when the table was created. The @code{BINARY} attribute means
values are sorted and compared in case-sensitive fashion according to the that column values are sorted and compared in case-sensitive fashion
ASCII order of the machine where the @strong{MySQL} server is running. 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 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 @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 ...@@ -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, have the same name as a function. Spaces around arguments are permitted,
though. 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 @need 2000
For the sake of brevity, examples display the output from the @code{mysql} For the sake of brevity, examples display the output from the @code{mysql}
program in abbreviated form. So this: program in abbreviated form. So this:
...@@ -16160,8 +16167,9 @@ This function is multi-byte safe. ...@@ -16160,8 +16167,9 @@ This function is multi-byte safe.
@findex LPAD() @findex LPAD()
@item LPAD(str,len,padstr) @item LPAD(str,len,padstr)
Returns the string @code{str}, left-padded with the string Returns the string @code{str}, left-padded with the string @code{padstr}
@code{padstr} until @code{str} is @code{len} characters long: 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 @example
mysql> select LPAD('hi',4,'??'); mysql> select LPAD('hi',4,'??');
...@@ -16171,7 +16179,10 @@ mysql> select LPAD('hi',4,'??'); ...@@ -16171,7 +16179,10 @@ mysql> select LPAD('hi',4,'??');
@findex RPAD() @findex RPAD()
@item RPAD(str,len,padstr) @item RPAD(str,len,padstr)
Returns the string @code{str}, right-padded with the string 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 @example
mysql> select RPAD('hi',5,'?'); mysql> select RPAD('hi',5,'?');
-> 'hi???' -> 'hi???'
...@@ -20624,6 +20635,12 @@ threads. Otherwise, you can see only your own threads. @xref{KILL, , ...@@ -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 @code{KILL}}. If you don't use the @code{FULL} option, then only
the first 100 characters of each query will be shown. 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 @cindex privileges, display
@node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW @node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW
@subsection SHOW GRANTS (Privileges) for a User @subsection SHOW GRANTS (Privileges) for a User
...@@ -26846,8 +26863,8 @@ statement. In this case the last @code{SELECT} statement in the previous ...@@ -26846,8 +26863,8 @@ statement. In this case the last @code{SELECT} statement in the previous
scenario would execute before the @code{INSERT} statement. scenario would execute before the @code{INSERT} statement.
@item @item
You can give a specific @code{INSERT}, @code{UPDATE}, or @code{DELETE} statement You can give a specific @code{INSERT}, @code{UPDATE}, or @code{DELETE}
lower priority with the @code{LOW_PRIORITY} attribute. statement lower priority with the @code{LOW_PRIORITY} attribute.
@item @item
Start @code{mysqld} with a low value for @strong{max_write_lock_count} to give 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. ...@@ -39765,6 +39782,11 @@ though, so Version 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.29 @appendixsubsec Changes in release 3.23.29
@itemize @bullet @itemize @bullet
@item @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. Remove not used BDB logs on shutdown.
@item @item
When creating a table, put @code{PRIMARY} keys first, followed by 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! ...@@ -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 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. 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 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 @file{.gdb} file, with the following information, in your current
...@@ -660,11 +660,10 @@ static uint getTableStructure(char *table, char* db) ...@@ -660,11 +660,10 @@ static uint getTableStructure(char *table, char* db)
strpos=strend(insert_pat); strpos=strend(insert_pat);
while ((row=mysql_fetch_row(tableRes))) while ((row=mysql_fetch_row(tableRes)))
{ {
ulong *lengths=mysql_fetch_lengths(tableRes);
if (init) if (init)
{ {
if (cFlag) if (cFlag)
strpos=strmov(strpos,", "); strpos=strmov(strpos,", ");
} }
init=1; init=1;
if (cFlag) if (cFlag)
......
...@@ -531,8 +531,8 @@ static void read_user_name(char *name) ...@@ -531,8 +531,8 @@ static void read_user_name(char *name)
static void read_user_name(char *name) static void read_user_name(char *name)
{ {
char *str=getenv("USER"); char *str=getenv("USER"); /* ODBC will send user variable */
strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */ strmake(name,str ? str : "ODBC", USERNAME_LENGTH);
} }
#endif #endif
...@@ -1149,8 +1149,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1149,8 +1149,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag) uint port, const char *unix_socket,uint client_flag)
{ {
char buff[NAME_LEN+100],charset_name_buff[16],*end,*host_info, char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
*charset_name; char *end,*host_info,*charset_name;
my_socket sock; my_socket sock;
uint32 ip_addr; uint32 ip_addr;
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
......
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
# 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) ...@@ -615,7 +615,7 @@ void handler::print_error(int error, myf errflag)
uint handler::get_dup_key(int error) uint handler::get_dup_key(int error)
{ {
DBUG_ENTER("key_error"); DBUG_ENTER("get_dup_key");
table->file->errkey = (uint) -1; table->file->errkey = (uint) -1;
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE) if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE)
info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK); info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
......
...@@ -1465,7 +1465,10 @@ String *Item_func_rpad::val_str(String *str) ...@@ -1465,7 +1465,10 @@ String *Item_func_rpad::val_str(String *str)
goto err; goto err;
null_value=0; null_value=0;
if (count <= (int32) (res_length=res->length())) 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(); length_pad= rpad->length();
if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad) if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad)
goto err; goto err;
...@@ -1521,7 +1524,10 @@ String *Item_func_lpad::val_str(String *str) ...@@ -1521,7 +1524,10 @@ String *Item_func_lpad::val_str(String *str)
goto err; goto err;
null_value=0; null_value=0;
if (count <= (res_length=res->length())) 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(); length_pad= lpad->length();
if (count > max_allowed_packet || args[2]->null_value || !length_pad) if (count > max_allowed_packet || args[2]->null_value || !length_pad)
goto err; goto err;
......
...@@ -1042,7 +1042,11 @@ static void init_signals(void) ...@@ -1042,7 +1042,11 @@ static void init_signals(void)
static sig_handler write_core(int sig) 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); signal(sig, SIG_DFL);
if (fork() != 0) exit(1); // Abort main program if (fork() != 0) exit(1); // Abort main program
// Core will be written at exit // Core will be written at exit
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment