Commit 3099c54d authored by monty@tik.mysql.fi's avatar monty@tik.mysql.fi

Test case for bug when updating on key

Fixed bug in CONCAT_WS()
Print the default ISOLATION level.
Change lock type for CREATE ... SELECT and INSERT/REPLACE ... SELECT
parent d145a6b9
mikef@nslinux.bedford.progress.com
monty@tik.mysql.fi
......@@ -13469,7 +13469,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
* COMMIT:: @code{BEGIN/COMMIT/ROLLBACK} syntax
* LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax
* SET OPTION:: @code{SET OPTION} syntax
* SET TRANSACTION::
* SET TRANSACTION:: @code{SET TRANSACTION} syntax
* GRANT:: @code{GRANT} and @code{REVOKE} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax
......@@ -18499,7 +18499,8 @@ row length = 1
+ (number of variable-length columns)
@end example
@item The @code{table_options} and @code{SELECT} options are only
@item
The @code{table_options} and @code{SELECT} options are only
implemented in @strong{MySQL} Version 3.23 and above.
The different table types are:
......@@ -18577,6 +18578,10 @@ mysql> CREATE TABLE test (a int not null auto_increment,
This will create a @code{MyISAM} table with 3 columns. Note that the
table will automatically be deleted if any errors occur while copying
data into the table.
To ensure that the update log/binary log can be used to re-create the
original tables, @strong{MySQL} will not allow concurrent inserts during
@code{CREATE TABLE .... SELECT}.
@item
The @code{RAID_TYPE} option will help you to break the 2G/4G limit for
the MyISAM data file (not the index file) on
......@@ -19913,6 +19918,11 @@ sub-select clauses, the situation could easily be very confusing!)
@item
You can use the C API function @code{mysql_info()} to get information about
the query. @xref{INSERT}.
@item
To ensure that the update log/binary log can be used to re-create the
original tables, @strong{MySQL} will not allow concurrent inserts during
@code{INSERT .... SELECT}.
@end itemize
You can of course also use @code{REPLACE} instead of @code{INSERT} to
......@@ -23861,8 +23871,8 @@ The @code{GEMINI} table type is developed and supported by NuSphere Corporation
(@uref{http://www.nusphere.com}). It features row-level locking, transaction
support (@code{COMMIT} and @code{ROLLBACK}), and automatic crash recovery.
@code{GEMINI} tables will be included in the @strong{MySQL} 3.23.35 source
distribution.
@code{GEMINI} tables will be included in some future @strong{MySQL} 3.23.X
source distribution.
@node GEMINI start, GEMINI features, GEMINI overview, GEMINI
@subsection GEMINI startup options
......@@ -41228,7 +41238,7 @@ are supported if the server and tables support them. It is
thread-safe, and contains a compatibility module for older code
written for the no-longer-maintained MySQLmodule interface.
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_11.tar.gz, mysql_mex_1_11.tar.gz}
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz, mysql_mex_1_12.tar.gz}
An interface program for the Matlab program by MathWorks. The interface
is done by Kimmo Uutela and John Fisher (not by Mathworks).
Check @uref{http://boojum.hut.fi/~kuutela/mysqlmex.html,mysqlmex.html}
......@@ -42331,7 +42341,7 @@ users uses this code as the rest of the code and because of this we are
not yet 100 % confident in this code.
@menu
* News-3.23.36::
* News-3.23.36:: Changes in release 3.23.36
* News-3.23.35:: Changes in release 3.23.35
* News-3.23.34a:: Changes in release 3.23.34a
* News-3.23.34:: Changes in release 3.23.34
......@@ -42377,6 +42387,17 @@ not yet 100 % confident in this code.
Added @code{SET TRANSACTION ISOLATION LEVEL ...}
@item
Added @code{SELECT ... FOR UPDATE}.
@item
Fixed bug where affected rows where not returned when @code{MySQL} was compiled
without transaction support.
@item
Fixed a bug in @code{UPDATE} where keys weren't always used to find the
rows to be updated.
@item
Fixed a bug in @code{CONCAT_WS()} where it returned wrong results.
@item
Changed @code{CREATE ... INSERT} and @code{INSERT ... SELECT} to not
allow concurrent inserts as this could make the binary log hard to repeat.
@end itemize
@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
......@@ -34,6 +34,14 @@ concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*')
:my:sql:
TRIM("foo" FROM "foo") TRIM("foo" FROM "foook") TRIM("foo" FROM "okfoo")
ok ok
concat_ws(', ','monty','was here','again')
monty, was here, again
concat_ws(NULL,'a') concat_ws(',',NULL,'')
NULL
concat_ws(',','',NULL,'a')
a
CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"')
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
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')
......@@ -96,3 +104,9 @@ domain
hello.de
domain
test.de
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"')
"Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4"
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"')
"Link";"1";"1";"1";"0";"4"
CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter)
Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4
......@@ -37,3 +37,5 @@ a
146
place_id shows
1 1
status
1
......@@ -4,6 +4,8 @@
# -----------
# Testing string functions
drop table if exists t1;
select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
select 'hello' 'monty';
select length('\n\t\r\b\0\_\%\\');
......@@ -24,6 +26,11 @@ select concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***s
select concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':');
select TRIM("foo" FROM "foo"), TRIM("foo" FROM "foook"), TRIM("foo" FROM "okfoo");
select concat_ws(', ','monty','was here','again');
select concat_ws(NULL,'a'),concat_ws(',',NULL,'');
select concat_ws(',','',NULL,'a');
SELECT CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"');
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') ;
......@@ -70,3 +77,26 @@ insert into t1 VALUES ("hello.de" ), ("test.de" );
select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@hello.de';
select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@test.de';
drop table t1;
#
# Test bug in concat_ws
#
CREATE TABLE t1 (
id int(10) unsigned NOT NULL,
title varchar(255) default NULL,
prio int(10) unsigned default NULL,
category int(10) unsigned default NULL,
program int(10) unsigned default NULL,
bugdesc text,
created datetime default NULL,
modified timestamp(14) NOT NULL,
bugstatus int(10) unsigned default NULL,
submitter int(10) unsigned default NULL
) TYPE=MyISAM;
INSERT INTO t1 VALUES (1,'Link',1,1,1,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','2001-02-28 08:40:16',20010228084016,0,4);
SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"') FROM t1;
SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"') FROM t1;
SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter) FROM t1;
drop table t1;
......@@ -37,3 +37,42 @@ VALUES (1,0,0,0,0,0,0,20000928174434);
UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00";
select place_id,shows from t1;
drop table t1;
#
# Test bug with update reported by Jan Legenhausen
#
CREATE TABLE t1 (
lfdnr int(10) unsigned NOT NULL default '0',
ticket int(10) unsigned NOT NULL default '0',
client varchar(255) NOT NULL default '',
replyto varchar(255) NOT NULL default '',
subject varchar(100) NOT NULL default '',
timestamp int(10) unsigned NOT NULL default '0',
tstamp timestamp(14) NOT NULL,
status int(3) NOT NULL default '0',
type varchar(15) NOT NULL default '',
assignment int(10) unsigned NOT NULL default '0',
fupcount int(4) unsigned NOT NULL default '0',
parent int(10) unsigned NOT NULL default '0',
activity int(10) unsigned NOT NULL default '0',
priority tinyint(1) unsigned NOT NULL default '1',
cc varchar(255) NOT NULL default '',
bcc varchar(255) NOT NULL default '',
body text NOT NULL,
comment text,
header text,
PRIMARY KEY (lfdnr),
KEY k1 (timestamp),
KEY k2 (type),
KEY k3 (parent),
KEY k4 (assignment),
KEY ticket (ticket)
) TYPE=MyISAM;
INSERT INTO t1 VALUES (773,773,'','','',980257344,20010318180652,0,'Open',10,0,0,0,1,'','','','','');
alter table t1 change lfdnr lfdnr int(10) unsigned default 0 not null auto_increment;
update t1 set status=1 where type='Open';
select status from t1;
drop table t1;
......@@ -472,7 +472,7 @@ int main(int argc,char **argv)
int error;
MY_INIT(argv[0]);
start_value=5315771L; best_t1=6916833L; best_t2=3813748L; best_type=3; /* mode=5839 add=5 type: 0 */
start_value=318439L; best_t1=7136932L; best_t2=1067561L; best_type=0; /* mode=5413 add=5 type: 0 */
if (get_options(argc,(char **) argv))
exit(1);
......
......@@ -55,16 +55,17 @@ const char *ha_table_type[] = {
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "GEMINI", "?", "?",NullS
};
TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
ha_table_type+1};
const char *ha_row_type[] = {
"", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
};
TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
ha_table_type+1};
const char *tx_isolation_names[] =
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE"};
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names),"",
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
NullS};
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
tx_isolation_names};
/* Use other database handler if databasehandler is not incompiled */
......
......@@ -223,9 +223,9 @@ String *Item_func_concat_ws::val_str(String *str)
// Skip until non-null and non-empty argument is found.
// If not, return the empty string
for (i=0;
!(res= args[i]->val_str(str)) || !res->length() && i < arg_count;
i++) ;
for (i=0; i < arg_count; i++)
if ((res= args[i]->val_str(str)) && res->length())
break;
if (i == arg_count)
return &empty_string;
......@@ -242,38 +242,52 @@ String *Item_func_concat_ws::val_str(String *str)
{ // Use old buffer
res->append(*sep_str); // res->length() > 0 always
res->append(*res2);
use_as_buff= &tmp_value;
}
else if (str->alloced_length() >=
res->length() + sep_str->length() + res2->length())
{
str->copy(*res);
str->append(*sep_str);
str->append(*res2);
/* We have room in str; We can't get any errors here */
if (str == res2)
{ // This is quote uncommon!
str->replace(0,0,*sep_str);
str->replace(0,0,*res);
}
else
{
str->copy(*res);
str->append(*sep_str);
str->append(*res2);
}
res=str;
use_as_buff= &tmp_value;
}
else if (res == &tmp_value)
{
if ((res->length() && res->append(*sep_str)) || res->append(*res2))
if (res->append(*sep_str) || res->append(*res2))
goto null; // Must be a blob
}
else if (res2 == &tmp_value)
{ // This can happend only 1 time
if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
goto null;
res= &tmp_value;
use_as_buff=str; // Put next arg here
}
else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
{
/*
This happens really seldom:
In this case res2 is sub string of tmp_value. We will
now work in place in tmp_value to set it to res | res2
now work in place in tmp_value to set it to res | sep_str | res2
*/
/* Chop the last characters in tmp_value that isn't in res2 */
tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
res2->length());
/* Place res2 at start of tmp_value, remove chars before res2 */
if (res->append(*sep_str))
goto null;
if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
*res))
*res) ||
tmp_value.replace(res->length(),0, *sep_str))
goto null;
res= &tmp_value;
use_as_buff=str; // Put next arg here
......
......@@ -536,6 +536,7 @@ extern bool low_priority_updates;
extern bool opt_sql_bin_update, opt_safe_show_db;
extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
extern const char **errmesg; /* Error messages */
extern const char *default_tx_isolation_name;
extern String empty_string;
extern struct show_var_st init_vars[];
extern struct show_var_st status_vars[];
......
......@@ -281,7 +281,9 @@ char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
const char *default_tx_isolation_name;
enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
#ifdef HAVE_GEMINI_DB
const char *gemini_recovery_options_str="FULL";
#endif
......@@ -2819,6 +2821,7 @@ struct show_var_st init_vars[]= {
{"thread_concurrency", (char*) &concurrency, SHOW_LONG},
#endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG},
{"transaction_isolation", (char*) &default_tx_isolation_name, SHOW_CHAR_PTR},
#ifdef HAVE_TZNAME
{"timezone", time_zone, SHOW_CHAR},
#endif
......@@ -3672,6 +3675,7 @@ static void get_options(int argc,char **argv)
}
fix_paths();
default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
}
......
......@@ -168,7 +168,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
table->time_stamp=save_time_stamp;
goto abort;
}
if (setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0))
if (setup_fields(thd,table_list,*values,0,0))
{
table->time_stamp=save_time_stamp;
goto abort;
......
......@@ -1266,8 +1266,11 @@ mysql_execute_command(void)
}
if (tables->next)
{
TABLE_LIST *table;
if (check_table_access(thd, SELECT_ACL, tables->next))
goto error; // Error message is given
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
thd->offset_limit=lex->offset_limit;
thd->select_limit=lex->select_limit+lex->offset_limit;
......@@ -1539,17 +1542,19 @@ mysql_execute_command(void)
{
// Check that we have modify privileges for the first table and
// select privileges for the rest
uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
if (check_access(thd, privilege,
tables->db,&tables->grant.privilege) ||
(grant_option && check_grant(thd, privilege, tables)))
goto error;
tables->next=save_next;
if ((res=check_table_access(thd, SELECT_ACL, save_next)))
goto error;
{
uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
if (check_access(thd, privilege,
tables->db,&tables->grant.privilege) ||
(grant_option && check_grant(thd, privilege, tables)))
goto error;
tables->next=save_next;
if ((res=check_table_access(thd, SELECT_ACL, save_next)))
goto error;
}
select_result *result;
thd->offset_limit=lex->offset_limit;
......@@ -1563,6 +1568,11 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
}
tables->lock_type=TL_WRITE; // update first table
{
TABLE_LIST *table;
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
if (!(res=open_and_lock_tables(thd,tables)))
{
if ((result=new select_insert(tables->table,&lex->field_list,
......
......@@ -699,6 +699,7 @@ create3:
/* empty */ {}
| opt_duplicate opt_as SELECT_SYM
{
Lex->lock_option= TL_READ_NO_INSERT;
mysql_init_select(Lex);
}
select_options select_item_list opt_select_from {}
......@@ -781,7 +782,7 @@ raid_types:
opt_select_from:
/* empty */
| select_from
| select_from select_lock_type
udf_func_type:
/* empty */ { $$ = UDFTYPE_FUNCTION; }
......@@ -2071,9 +2072,10 @@ insert_values:
LEX *lex=Lex;
lex->sql_command = (lex->sql_command == SQLCOM_INSERT ?
SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
lex->lock_option= TL_READ_NO_INSERT;
mysql_init_select(lex);
}
select_options select_item_list select_from {}
select_options select_item_list select_from select_lock_type {}
values_list:
values_list ',' no_braces
......@@ -2783,6 +2785,7 @@ set_isolation:
if (check_process_priv())
YYABORT;
default_tx_isolation= $2;
default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
}
| SESSION_SYM tx_isolation
{ current_thd->session_tx_isolation= Lex->tx_isolation= $2; }
......
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