Commit 5ed755d0 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Merge mysql.com:/home/kostja/mysql/tmp_merge

into  mysql.com:/home/kostja/mysql/mysql-5.1-merge
parents ea22f9ea 5678bc52
......@@ -343,7 +343,7 @@ MYSQL_PROG_AR
# libmysqlclient versioning when linked with GNU ld.
if $LD --version 2>/dev/null|grep -q GNU; then
LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmysql/libmysql.ver"
LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_builddir)/libmysql/libmysql.ver"
AC_CONFIG_FILES(libmysql/libmysql.ver)
fi
AC_SUBST(LD_VERSION_SCRIPT)
......
......@@ -136,6 +136,7 @@ typedef struct st_heap_share
HP_KEYDEF *keydef;
ulong min_records,max_records; /* Params to open */
ulong data_length,index_length,max_table_size;
uint key_stat_version; /* version to indicate insert/delete */
uint records; /* records */
uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */
......
......@@ -5036,6 +5036,12 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
{
DBUG_ENTER("mysql_stmt_reset");
DBUG_ASSERT(stmt != 0);
if (!stmt->mysql)
{
/* mysql can be reset in mysql_close called from mysql_reconnect */
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
DBUG_RETURN(1);
}
/* Reset the client and server sides of the prepared statement */
DBUG_RETURN(reset_stmt_handle(stmt, RESET_SERVER_SIDE | RESET_LONG_DATA));
}
......
drop table if exists t1;
drop table if exists t1, t2, t3;
create table t1 (kill_id int);
insert into t1 values(connection_id());
select ((@id := kill_id) - kill_id) from t1;
......@@ -27,3 +27,15 @@ select 1;
select RELEASE_LOCK("a");
RELEASE_LOCK("a")
1
create table t1 (id int primary key);
create table t2 (id int unsigned not null);
insert into t2 select id from t1;
create table t3 (kill_id int);
insert into t3 values(connection_id());
select id from t1 where id in (select distinct id from t2);
select ((@id := kill_id) - kill_id) from t3;
((@id := kill_id) - kill_id)
0
kill @id;
ERROR 08S01: Server shutdown in progress
drop table t1, t2, t3;
......@@ -567,7 +567,7 @@ Warnings:
Note 1031 Table storage engine for 't1' doesn't have this option
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a NULL 1000 NULL NULL YES HASH
t1 1 a 1 a NULL 500 NULL NULL YES HASH
drop table t1,t2;
create table t1 ( a tinytext, b char(1), index idx (a(1),b) );
insert into t1 values (null,''), (null,'');
......
......@@ -358,3 +358,22 @@ update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1;
affected rows: 3
info: Rows matched: 3 Changed: 3 Warnings: 0
drop table t1,t2;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, filler1 char(200), filler2 char(200), key(a));
insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B;
flush status;
update t2 set a=3 where a=2;
show status like 'handler_read%';
Variable_name Value
Handler_read_first 0
Handler_read_key 1
Handler_read_next 1
Handler_read_prev 0
Handler_read_rnd 1
Handler_read_rnd_next 0
drop table t1, t2;
create table t1(f1 int, `*f2` int);
insert into t1 values (1,1);
update t1 set `*f2`=1;
drop table t1;
......@@ -436,6 +436,17 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
drop table t1;
#
# Bug 12796: Record doesn't show when selecting through index
#
CREATE TABLE t1 (a int, key(a)) engine=heap;
insert delayed into t1 values (0);
delete from t1;
select * from t1;
insert delayed into t1 values (0), (1);
select * from t1 where a = 0;
drop table t1;
# End of 4.1 tests
#
......
......@@ -12,7 +12,7 @@ connect (con2, localhost, root,,);
#remember id of con1
connection con1;
--disable_warnings
drop table if exists t1;
drop table if exists t1, t2, t3;
--enable_warnings
--disable_reconnect
......@@ -47,6 +47,53 @@ connection con2;
select 4;
drop table t1;
disconnect con2;
connection default;
#
# BUG#14851: killing long running subquery processed via a temporary table.
#
create table t1 (id int primary key);
create table t2 (id int unsigned not null);
connect (conn1, localhost, root,,);
connection conn1;
-- disable_result_log
-- disable_query_log
let $1 = 4096;
while ($1)
{
eval insert into t1 values ($1);
dec $1;
}
-- enable_query_log
-- enable_result_log
insert into t2 select id from t1;
create table t3 (kill_id int);
insert into t3 values(connection_id());
-- disable_result_log
send select id from t1 where id in (select distinct id from t2);
-- enable_result_log
connect (conn2, localhost, root,,);
connection conn2;
select ((@id := kill_id) - kill_id) from t3;
-- sleep 1
kill @id;
connection conn1;
-- error 1053
reap;
disconnect conn1;
disconnect conn2;
connection default;
drop table t1, t2, t3;
# End of 4.1 tests
#
......
......@@ -287,4 +287,23 @@ update t1 set f1=1 where f1=3;
update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1;
--disable_info
drop table t1,t2;
# BUG#15935
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, filler1 char(200), filler2 char(200), key(a));
insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B;
flush status;
update t2 set a=3 where a=2;
show status like 'handler_read%';
drop table t1, t2;
#
# Bug #16510 Updating field named like '*name' caused server crash
#
create table t1(f1 int, `*f2` int);
insert into t1 values (1,1);
update t1 set `*f2`=1;
drop table t1;
# End of 4.1 tests
......@@ -73,7 +73,7 @@ static handler *heap_create_handler(TABLE_SHARE *table)
ha_heap::ha_heap(TABLE_SHARE *table_arg)
:handler(&heap_hton, table_arg), file(0), records_changed(0),
key_stats_ok(0)
key_stats_version(0)
{}
......@@ -124,7 +124,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
ha_heap::info(), which is always called before key statistics are
used.
*/
key_stats_ok= FALSE;
key_stat_version= file->s->key_stat_version-1;
}
return (file ? 0 : 1);
}
......@@ -171,14 +171,21 @@ void ha_heap::update_key_stats()
continue;
if (key->algorithm != HA_KEY_ALG_BTREE)
{
ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
key->rec_per_key[key->key_parts-1]=
hash_buckets ? file->s->records/hash_buckets : 0;
if (key->flags & HA_NOSAME)
key->rec_per_key[key->key_parts-1]= 1;
else
{
ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
uint no_records= hash_buckets ? file->s->records/hash_buckets : 2;
if (no_records < 2)
no_records= 2;
key->rec_per_key[key->key_parts-1]= no_records;
}
}
}
records_changed= 0;
/* At the end of update_key_stats() we can proudly claim they are OK. */
key_stats_ok= TRUE;
key_stat_version= file->s->key_stat_version;
}
......@@ -193,7 +200,13 @@ int ha_heap::write_row(byte * buf)
res= heap_write(file,buf);
if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records))
key_stats_ok= FALSE;
{
/*
We can perform this safely since only one writer at the time is
allowed on the table.
*/
file->s->key_stat_version++;
}
return res;
}
......@@ -206,7 +219,13 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
res= heap_update(file,old_data,new_data);
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records)
key_stats_ok= FALSE;
{
/*
We can perform this safely since only one writer at the time is
allowed on the table.
*/
file->s->key_stat_version++;
}
return res;
}
......@@ -217,7 +236,13 @@ int ha_heap::delete_row(const byte * buf)
res= heap_delete(file,buf);
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
key_stats_ok= FALSE;
{
/*
We can perform this safely since only one writer at the time is
allowed on the table.
*/
file->s->key_stat_version++;
}
return res;
}
......@@ -344,7 +369,7 @@ void ha_heap::info(uint flag)
have to update the key statistics. Hoping that a table lock is now
in place.
*/
if (! key_stats_ok)
if (key_stat_version != file->s->key_stat_version)
update_key_stats();
}
......@@ -357,7 +382,13 @@ int ha_heap::delete_all_rows()
{
heap_clear(file);
if (table->s->tmp_table == NO_TMP_TABLE)
key_stats_ok= FALSE;
{
/*
We can perform this safely since only one writer at the time is
allowed on the table.
*/
file->s->key_stat_version++;
}
return 0;
}
......@@ -524,6 +555,9 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
max_key->flag != HA_READ_AFTER_KEY)
return HA_POS_ERROR; // Can only use exact keys
if (records <= 1)
return records;
/* Assert that info() did run. We need current statistics here. */
DBUG_ASSERT(key_stats_ok);
return key->rec_per_key[key->key_parts-1];
......
......@@ -29,7 +29,7 @@ class ha_heap: public handler
key_map btree_keys;
/* number of records changed since last statistics update */
uint records_changed;
bool key_stats_ok;
uint key_stat_version;
public:
ha_heap(TABLE_SHARE *table);
~ha_heap() {}
......
......@@ -1862,11 +1862,14 @@ bool select_dumpvar::send_eof()
void TMP_TABLE_PARAM::init()
{
DBUG_ENTER("TMP_TABLE_PARAM::init");
DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
field_count= sum_func_count= func_count= hidden_field_count= 0;
group_parts= group_length= group_null_parts= 0;
quick_group= 1;
table_charset= 0;
precomputed_group_by= 0;
DBUG_VOID_RETURN;
}
......
......@@ -6064,6 +6064,20 @@ void JOIN::cleanup(bool full)
problems in free_elements() as some of the elements are then deleted.
*/
tmp_table_param.copy_funcs.empty();
/*
If we have tmp_join and 'this' JOIN is not tmp_join and
tmp_table_param.copy_field's of them are equal then we have to remove
pointer to tmp_table_param.copy_field from tmp_join, because it qill
be removed in tmp_table_param.cleanup().
*/
if (tmp_join &&
tmp_join != this &&
tmp_join->tmp_table_param.copy_field ==
tmp_table_param.copy_field)
{
tmp_join->tmp_table_param.copy_field=
tmp_join->tmp_table_param.save_copy_field= 0;
}
tmp_table_param.cleanup();
}
DBUG_VOID_RETURN;
......
......@@ -286,7 +286,14 @@ class JOIN :public Sql_alloc
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
JOIN(JOIN &join)
:fields_list(join.fields_list)
{
init(join.thd, join.fields_list, join.select_options,
join.result);
}
void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
{
......@@ -333,7 +340,7 @@ class JOIN :public Sql_alloc
all_fields= fields_arg;
fields_list= fields_arg;
bzero((char*) &keyuse,sizeof(keyuse));
tmp_table_param.copy_field=0;
tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;
rollup.state= ROLLUP::STATE_NONE;
}
......
......@@ -331,7 +331,6 @@ int mysql_update(THD *thd,
SORT_FIELD *sortorder;
ha_rows examined_rows;
used_index= MAX_KEY; // For call to init_read_record()
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
......@@ -362,7 +361,21 @@ int mysql_update(THD *thd,
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
/* If quick select is used, initialize it before retrieving rows. */
if (select && select->quick && select->quick->reset())
goto err;
/*
When we get here, we have one of the following options:
A. used_index == MAX_KEY
This means we should use full table scan, and start it with
init_read_record call
B. used_index != MAX_KEY
B.1 quick select is used, start the scan with init_read_record
B.2 quick select is not used, this is full index scan (with LIMIT)
Full index scan must be started with init_read_record_idx
*/
/* If quick select is used, initialize it before retrieving rows. */
if (select && select->quick && select->quick->reset())
goto err;
......
......@@ -135,6 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
DBUG_RETURN(1);
}
share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys);
init_block(&share->block, reclength + 1, min_records, max_records);
/* Fix keys */
......
......@@ -84,6 +84,11 @@
#define CFG_DB_BACKUP_DATADIR 158
#define CFG_DB_MAX_OPEN_FILES 159
#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160 /* used from 5.1 */
#define CFG_DB_STRING_MEMORY 161 /* used from 5.1 */
#define CFG_DB_INITIAL_OPEN_FILES 162 /* used from 5.1 */
#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */
#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160
#define CFG_DB_STRING_MEMORY 161
......
......@@ -1483,13 +1483,16 @@ testperf()
// insert char (one trans)
{
DBG("--- insert char ---");
char b[20];
t1.on();
CHK((g_con = g_ndb->startTransaction()) != 0);
for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
CHK(g_opr->insertTuple() == 0);
CHK(g_opr->equal(cA, (char*)&k) == 0);
CHK(g_opr->setValue(cB, "b") == 0);
memset(b, 0x20, sizeof(b));
b[0] = 'b';
CHK(g_opr->setValue(cB, b) == 0);
CHK(g_con->execute(NoCommit) == 0);
}
t1.off(g_opt.m_rowsperf);
......@@ -1526,12 +1529,15 @@ testperf()
{
DBG("--- insert for read test ---");
unsigned n = 0;
char b[20];
CHK((g_con = g_ndb->startTransaction()) != 0);
for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
CHK(g_opr->insertTuple() == 0);
CHK(g_opr->equal(cA, (char*)&k) == 0);
CHK(g_opr->setValue(cB, "b") == 0);
memset(b, 0x20, sizeof(b));
b[0] = 'b';
CHK(g_opr->setValue(cB, b) == 0);
CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0);
CHK((g_bh1->setValue("c", 1) == 0));
if (++n == g_opt.m_batch) {
......@@ -1565,7 +1571,7 @@ testperf()
a = (Uint32)-1;
b[0] = 0;
CHK(g_con->execute(NoCommit) == 0);
CHK(a == k && strcmp(b, "b") == 0);
CHK(a == k && b[0] == 'b');
}
CHK(g_con->execute(Commit) == 0);
t1.off(g_opt.m_rowsperf);
......@@ -1591,7 +1597,7 @@ testperf()
CHK(g_con->execute(NoCommit) == 0);
Uint32 m = 20;
CHK(g_bh1->readData(c, m) == 0);
CHK(a == k && m == 1 && strcmp(c, "c") == 0);
CHK(a == k && m == 1 && c[0] == 'c');
}
CHK(g_con->execute(Commit) == 0);
t2.off(g_opt.m_rowsperf);
......@@ -1623,7 +1629,7 @@ testperf()
CHK((ret = g_ops->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0);
CHK(a < g_opt.m_rowsperf && b[0] == 'b');
n++;
}
CHK(n == g_opt.m_rowsperf);
......@@ -1654,7 +1660,7 @@ testperf()
break;
Uint32 m = 20;
CHK(g_bh1->readData(c, m) == 0);
CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0);
CHK(a < g_opt.m_rowsperf && m == 1 && c[0] == 'c');
n++;
}
CHK(n == g_opt.m_rowsperf);
......
......@@ -14714,6 +14714,56 @@ static void test_bug16144()
mysql_stmt_close(stmt);
}
static void test_bug12744()
{
MYSQL_STMT *prep_stmt = NULL;
int rc;
myheader("test_bug12744");
prep_stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
DIE_UNLESS(rc==0);
rc= mysql_kill(mysql, mysql_thread_id(mysql));
DIE_UNLESS(rc==0);
if (rc= mysql_stmt_execute(prep_stmt))
{
if (rc= mysql_stmt_reset(prep_stmt))
printf("OK!\n");
else
{
printf("Error!");
DIE_UNLESS(1==0);
}
}
else
{
fprintf(stderr, "expected error but no error occured\n");
DIE_UNLESS(1==0);
}
rc= mysql_stmt_close(prep_stmt);
}
/* Bug #16144: mysql_stmt_attr_get type error */
static void test_bug16144()
{
const my_bool flag_orig= (my_bool) 0xde;
my_bool flag= flag_orig;
MYSQL_STMT *stmt;
myheader("test_bug16144");
/* Check that attr_get returns correct data on little and big endian CPUs */
stmt= mysql_stmt_init(mysql);
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
DIE_UNLESS(flag == flag_orig);
mysql_stmt_close(stmt);
}
/*
Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
field length"
......@@ -15038,6 +15088,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug14845", test_bug14845 },
{ "test_opt_reconnect", test_opt_reconnect },
{ "test_bug15510", test_bug15510},
{ "test_bug12744", test_bug12744 },
{ "test_bug16144", test_bug16144 },
{ "test_bug15613", test_bug15613 },
{ 0, 0 }
......
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