mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
5.1 merge
This commit is contained in:
commit
4ee5ae3e7f
16 changed files with 232 additions and 25 deletions
|
@ -1965,3 +1965,4 @@ CPackSourceConfig.cmake
|
||||||
win/nmake_cache.txt
|
win/nmake_cache.txt
|
||||||
*.manifest
|
*.manifest
|
||||||
*.resource.txt
|
*.resource.txt
|
||||||
|
sql/sql_yacc.hh
|
||||||
|
|
|
@ -1896,7 +1896,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
|
||||||
const char *str_create)
|
const char *str_create)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
my_bool body_found= 0;
|
my_bool body_found __attribute__((unused)) = 0;
|
||||||
char *create_stmt_ptr= NULL;
|
char *create_stmt_ptr= NULL;
|
||||||
ulong create_stmt_len= 0;
|
ulong create_stmt_len= 0;
|
||||||
MYSQL_FIELD *field;
|
MYSQL_FIELD *field;
|
||||||
|
|
25
mysql-test/suite/maria/r/distinct.result
Normal file
25
mysql-test/suite/maria/r/distinct.result
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=Aria;
|
||||||
|
INSERT t1 VALUES (3,2004),(2,2006),(1,2007),(3,2008),(2,2005),(2,2001);
|
||||||
|
SELECT GROUP_CONCAT(a) FROM t1 GROUP BY b;
|
||||||
|
GROUP_CONCAT(a)
|
||||||
|
2
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
3
|
||||||
|
SELECT DISTINCT GROUP_CONCAT(a) FROM t1 GROUP BY b;
|
||||||
|
GROUP_CONCAT(a)
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b VARCHAR(1)) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (7,'q'),(2,NULL),(7,'g'),(6,'x');
|
||||||
|
SELECT DISTINCT MAX( a ) FROM t1 GROUP BY b ORDER BY DES_DECRYPT( b );
|
||||||
|
MAX( a )
|
||||||
|
2
|
||||||
|
7
|
||||||
|
6
|
||||||
|
DROP TABLE t1;
|
25
mysql-test/suite/maria/t/distinct.test
Normal file
25
mysql-test/suite/maria/t/distinct.test
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#
|
||||||
|
# MDEV-4280:
|
||||||
|
# Assertion `empty_size == empty_size_on_page' failure in ma_blockrec.c or
|
||||||
|
# ER_NOT_KEYFILE on query with DISTINCT and GROUP BY
|
||||||
|
#
|
||||||
|
# This issue was a bug in how we delete row during duplicate removal when
|
||||||
|
# we use Aria for internal temporary table.
|
||||||
|
#
|
||||||
|
|
||||||
|
-- source include/have_maria.inc
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT) ENGINE=Aria;
|
||||||
|
INSERT t1 VALUES (3,2004),(2,2006),(1,2007),(3,2008),(2,2005),(2,2001);
|
||||||
|
SELECT GROUP_CONCAT(a) FROM t1 GROUP BY b;
|
||||||
|
SELECT DISTINCT GROUP_CONCAT(a) FROM t1 GROUP BY b;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b VARCHAR(1)) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES (7,'q'),(2,NULL),(7,'g'),(6,'x');
|
||||||
|
SELECT DISTINCT MAX( a ) FROM t1 GROUP BY b ORDER BY DES_DECRYPT( b );
|
||||||
|
DROP TABLE t1;
|
|
@ -224,7 +224,7 @@ drop table t17583;
|
||||||
--exec $MYSQL test -e "connect test invalid_hostname" 2>&1
|
--exec $MYSQL test -e "connect test invalid_hostname" 2>&1
|
||||||
|
|
||||||
--echo The commands reported in the bug report
|
--echo The commands reported in the bug report
|
||||||
--replace_regex /\([0-9]*\)/(errno)/
|
--replace_regex /\([0-9|-]*\)/(errno)/
|
||||||
--error 1
|
--error 1
|
||||||
--exec $MYSQL test -e "\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1
|
--exec $MYSQL test -e "\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
|
||||||
if (param->state == Item_param::NO_VALUE)
|
if (param->state == Item_param::NO_VALUE)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (param->limit_clause_param && param->item_type != Item::INT_ITEM)
|
if (param->limit_clause_param)
|
||||||
{
|
{
|
||||||
param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
|
param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
|
||||||
param->item_type= Item::INT_ITEM;
|
param->item_type= Item::INT_ITEM;
|
||||||
|
|
|
@ -14747,7 +14747,8 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
|
||||||
if (!found)
|
if (!found)
|
||||||
break; // End of file
|
break; // End of file
|
||||||
/* Restart search on saved row */
|
/* Restart search on saved row */
|
||||||
error=file->restart_rnd_next(record);
|
if ((error= file->restart_rnd_next(record)))
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->extra(HA_EXTRA_NO_CACHE);
|
file->extra(HA_EXTRA_NO_CACHE);
|
||||||
|
|
|
@ -2304,7 +2304,9 @@ int ha_maria::remember_rnd_pos()
|
||||||
|
|
||||||
int ha_maria::restart_rnd_next(uchar *buf)
|
int ha_maria::restart_rnd_next(uchar *buf)
|
||||||
{
|
{
|
||||||
(*file->s->scan_restore_pos)(file, remember_pos);
|
int error;
|
||||||
|
if ((error= (*file->s->scan_restore_pos)(file, remember_pos)))
|
||||||
|
return error;
|
||||||
return rnd_next(buf);
|
return rnd_next(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4014,6 +4014,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
||||||
uint length, empty_space;
|
uint length, empty_space;
|
||||||
uchar *dir;
|
uchar *dir;
|
||||||
DBUG_ENTER("delete_dir_entry");
|
DBUG_ENTER("delete_dir_entry");
|
||||||
|
DBUG_PRINT("enter", ("record_number: %u number_of_records: %u",
|
||||||
|
record_number, number_of_records));
|
||||||
|
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
if (record_number >= number_of_records ||
|
if (record_number >= number_of_records ||
|
||||||
|
@ -4030,7 +4032,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
||||||
check_directory(buff, block_size, 0, (uint) -1);
|
check_directory(buff, block_size, 0, (uint) -1);
|
||||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
dir= dir_entry_pos(buff, block_size, record_number);
|
dir= dir_entry_pos(buff, block_size, record_number);
|
||||||
length= uint2korr(dir + 2);
|
length= uint2korr(dir + 2); /* Length of entry we just deleted */
|
||||||
|
DBUG_ASSERT(uint2korr(dir) != 0 && length < block_size);
|
||||||
|
|
||||||
if (record_number == number_of_records - 1)
|
if (record_number == number_of_records - 1)
|
||||||
{
|
{
|
||||||
|
@ -5248,11 +5251,6 @@ void _ma_scan_end_block_record(MARIA_HA *info)
|
||||||
For the moment we can only remember one position, but this is
|
For the moment we can only remember one position, but this is
|
||||||
good enough for MySQL usage
|
good enough for MySQL usage
|
||||||
|
|
||||||
@Warning
|
|
||||||
When this function is called, we assume that the thread is not deleting
|
|
||||||
or updating the current row before ma_scan_restore_block_record()
|
|
||||||
is called!
|
|
||||||
|
|
||||||
@return
|
@return
|
||||||
@retval 0 ok
|
@retval 0 ok
|
||||||
@retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position
|
@retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position
|
||||||
|
@ -5272,15 +5270,18 @@ int _ma_scan_remember_block_record(MARIA_HA *info,
|
||||||
info->scan_save->bitmap_buff= ((uchar*) info->scan_save +
|
info->scan_save->bitmap_buff= ((uchar*) info->scan_save +
|
||||||
ALIGN_SIZE(sizeof(*info->scan_save)));
|
ALIGN_SIZE(sizeof(*info->scan_save)));
|
||||||
}
|
}
|
||||||
/* Point to the last read row */
|
/* For checking if pages have changed since we last read it */
|
||||||
*lastpos= info->cur_row.nextpos - 1;
|
info->scan.row_changes= info->row_changes;
|
||||||
info->scan.dir+= DIR_ENTRY_SIZE;
|
|
||||||
|
|
||||||
/* Remember used bitmap and used head page */
|
/* Remember used bitmap and used head page */
|
||||||
bitmap_buff= info->scan_save->bitmap_buff;
|
bitmap_buff= info->scan_save->bitmap_buff;
|
||||||
memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save));
|
memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save));
|
||||||
info->scan_save->bitmap_buff= bitmap_buff;
|
info->scan_save->bitmap_buff= bitmap_buff;
|
||||||
memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2);
|
memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2);
|
||||||
|
|
||||||
|
/* Point to the last read row */
|
||||||
|
*lastpos= info->cur_row.nextpos - 1;
|
||||||
|
info->scan_save->dir+= DIR_ENTRY_SIZE;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5288,15 +5289,22 @@ int _ma_scan_remember_block_record(MARIA_HA *info,
|
||||||
/**
|
/**
|
||||||
@brief restore scan block it's original values
|
@brief restore scan block it's original values
|
||||||
|
|
||||||
|
@return
|
||||||
|
0 ok
|
||||||
|
# error
|
||||||
|
|
||||||
@note
|
@note
|
||||||
In theory we could swap bitmap buffers instead of copy them.
|
In theory we could swap bitmap buffers instead of copy them.
|
||||||
For the moment we don't do that because there are variables pointing
|
For the moment we don't do that because there are variables pointing
|
||||||
inside the buffers and it's a bit of hassle to either make them relative
|
inside the buffers and it's a bit of hassle to either make them relative
|
||||||
or repoint them.
|
or repoint them.
|
||||||
|
|
||||||
|
If the data file has changed, we will re-read the new block record
|
||||||
|
to ensure that when we continue scanning we can ignore any deleted rows.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _ma_scan_restore_block_record(MARIA_HA *info,
|
int _ma_scan_restore_block_record(MARIA_HA *info,
|
||||||
MARIA_RECORD_POS lastpos)
|
MARIA_RECORD_POS lastpos)
|
||||||
{
|
{
|
||||||
uchar *bitmap_buff;
|
uchar *bitmap_buff;
|
||||||
DBUG_ENTER("_ma_scan_restore_block_record");
|
DBUG_ENTER("_ma_scan_restore_block_record");
|
||||||
|
@ -5307,7 +5315,26 @@ void _ma_scan_restore_block_record(MARIA_HA *info,
|
||||||
info->scan.bitmap_buff= bitmap_buff;
|
info->scan.bitmap_buff= bitmap_buff;
|
||||||
memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2);
|
memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2);
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
if (info->scan.row_changes != info->row_changes)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Table has been changed. We have to re-read the current page block as
|
||||||
|
data may have changed on it that we have to see.
|
||||||
|
*/
|
||||||
|
if (!(pagecache_read(info->s->pagecache,
|
||||||
|
&info->dfile,
|
||||||
|
ma_recordpos_to_page(info->scan.row_base_page),
|
||||||
|
0, info->scan.page_buff,
|
||||||
|
info->s->page_type,
|
||||||
|
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
|
||||||
|
DBUG_RETURN(my_errno);
|
||||||
|
info->scan.number_of_rows=
|
||||||
|
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET];
|
||||||
|
info->scan.dir_end= (info->scan.page_buff + info->s->block_size -
|
||||||
|
PAGE_SUFFIX_SIZE -
|
||||||
|
info->scan.number_of_rows * DIR_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5334,7 +5361,7 @@ void _ma_scan_restore_block_record(MARIA_HA *info,
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
# Error code
|
# Error code (Normally HA_ERR_END_OF_FILE)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int _ma_scan_block_record(MARIA_HA *info, uchar *record,
|
int _ma_scan_block_record(MARIA_HA *info, uchar *record,
|
||||||
|
@ -5353,6 +5380,12 @@ restart_record_read:
|
||||||
uchar *data, *end_of_data;
|
uchar *data, *end_of_data;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
/* Ensure that scan.dir and record_pos are in sync */
|
||||||
|
DBUG_ASSERT(info->scan.dir == dir_entry_pos(info->scan.page_buff,
|
||||||
|
share->block_size,
|
||||||
|
record_pos));
|
||||||
|
|
||||||
|
/* Search for a valid directory entry (not 0) */
|
||||||
while (!(offset= uint2korr(info->scan.dir)))
|
while (!(offset= uint2korr(info->scan.dir)))
|
||||||
{
|
{
|
||||||
info->scan.dir-= DIR_ENTRY_SIZE;
|
info->scan.dir-= DIR_ENTRY_SIZE;
|
||||||
|
@ -5365,13 +5398,19 @@ restart_record_read:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
This should always be true as the directory should always start with
|
||||||
|
a valid entry.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(info->scan.dir >= info->scan.dir_end);
|
||||||
|
|
||||||
/* found row */
|
/* found row */
|
||||||
info->cur_row.lastpos= info->scan.row_base_page + record_pos;
|
info->cur_row.lastpos= info->scan.row_base_page + record_pos;
|
||||||
info->cur_row.nextpos= record_pos + 1;
|
info->cur_row.nextpos= record_pos + 1;
|
||||||
data= info->scan.page_buff + offset;
|
data= info->scan.page_buff + offset;
|
||||||
length= uint2korr(info->scan.dir + 2);
|
length= uint2korr(info->scan.dir + 2);
|
||||||
end_of_data= data + length;
|
end_of_data= data + length;
|
||||||
info->scan.dir-= DIR_ENTRY_SIZE; /* Point to previous row */
|
info->scan.dir-= DIR_ENTRY_SIZE; /* Point to next row to process */
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
if (end_of_data > info->scan.dir_end ||
|
if (end_of_data > info->scan.dir_end ||
|
||||||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
|
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
|
||||||
|
|
|
@ -167,8 +167,8 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info);
|
||||||
void _ma_scan_end_block_record(MARIA_HA *info);
|
void _ma_scan_end_block_record(MARIA_HA *info);
|
||||||
int _ma_scan_remember_block_record(MARIA_HA *info,
|
int _ma_scan_remember_block_record(MARIA_HA *info,
|
||||||
MARIA_RECORD_POS *lastpos);
|
MARIA_RECORD_POS *lastpos);
|
||||||
void _ma_scan_restore_block_record(MARIA_HA *info,
|
int _ma_scan_restore_block_record(MARIA_HA *info,
|
||||||
MARIA_RECORD_POS lastpos);
|
MARIA_RECORD_POS lastpos);
|
||||||
|
|
||||||
MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
|
MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
|
||||||
const uchar *record);
|
const uchar *record);
|
||||||
|
|
|
@ -112,6 +112,7 @@ int maria_delete(MARIA_HA *info,const uchar *record)
|
||||||
info->state->checksum-= info->cur_row.checksum;
|
info->state->checksum-= info->cur_row.checksum;
|
||||||
info->state->records--;
|
info->state->records--;
|
||||||
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
|
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
|
||||||
|
info->row_changes++;
|
||||||
share->state.changed|= (STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE |
|
share->state.changed|= (STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE |
|
||||||
STATE_NOT_ZEROFILLED);
|
STATE_NOT_ZEROFILLED);
|
||||||
info->state->changed=1;
|
info->state->changed=1;
|
||||||
|
|
|
@ -68,7 +68,8 @@ int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
|
int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos)
|
||||||
{
|
{
|
||||||
info->cur_row.nextpos= lastpos;
|
info->cur_row.nextpos= lastpos;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,7 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||||
We can't yet have HA_STATE_AKTIV here, as block_record dosn't support it
|
We can't yet have HA_STATE_AKTIV here, as block_record dosn't support it
|
||||||
*/
|
*/
|
||||||
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
|
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
|
||||||
|
info->row_changes++;
|
||||||
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
|
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
|
||||||
info->state->changed= 1;
|
info->state->changed= 1;
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,7 @@ int maria_write(MARIA_HA *info, uchar *record)
|
||||||
info->state->records++;
|
info->state->records++;
|
||||||
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
|
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
|
||||||
HA_STATE_ROW_CHANGED);
|
HA_STATE_ROW_CHANGED);
|
||||||
|
info->row_changes++;
|
||||||
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
|
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
|
||||||
info->state->changed= 1;
|
info->state->changed= 1;
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ typedef struct st_maria_share
|
||||||
/* End scan */
|
/* End scan */
|
||||||
void (*scan_end)(MARIA_HA *);
|
void (*scan_end)(MARIA_HA *);
|
||||||
int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
|
int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
|
||||||
void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
|
int (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
|
||||||
/* Pre-write of row (some handlers may do the actual write here) */
|
/* Pre-write of row (some handlers may do the actual write here) */
|
||||||
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
|
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
|
||||||
/* Write record (or accept write_record_init) */
|
/* Write record (or accept write_record_init) */
|
||||||
|
@ -495,6 +495,7 @@ typedef struct st_maria_block_scan
|
||||||
ulonglong bits;
|
ulonglong bits;
|
||||||
uint number_of_rows, bit_pos;
|
uint number_of_rows, bit_pos;
|
||||||
MARIA_RECORD_POS row_base_page;
|
MARIA_RECORD_POS row_base_page;
|
||||||
|
ulonglong row_changes;
|
||||||
} MARIA_BLOCK_SCAN;
|
} MARIA_BLOCK_SCAN;
|
||||||
|
|
||||||
|
|
||||||
|
@ -536,6 +537,7 @@ struct st_maria_handler
|
||||||
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
|
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
|
||||||
invalidator_by_filename invalidator; /* query cache invalidator */
|
invalidator_by_filename invalidator; /* query cache invalidator */
|
||||||
ulonglong last_auto_increment; /* auto value at start of statement */
|
ulonglong last_auto_increment; /* auto value at start of statement */
|
||||||
|
ulonglong row_changes; /* Incremented for each change */
|
||||||
ulong this_unique; /* uniq filenumber or thread */
|
ulong this_unique; /* uniq filenumber or thread */
|
||||||
ulong last_unique; /* last unique number */
|
ulong last_unique; /* last unique number */
|
||||||
ulong this_loop; /* counter for this open */
|
ulong this_loop; /* counter for this open */
|
||||||
|
@ -1179,7 +1181,7 @@ my_bool _ma_check_status(void *param);
|
||||||
void _ma_restore_status(void *param);
|
void _ma_restore_status(void *param);
|
||||||
void _ma_reset_status(MARIA_HA *maria);
|
void _ma_reset_status(MARIA_HA *maria);
|
||||||
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
|
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
|
||||||
void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
|
int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);
|
||||||
|
|
||||||
#include "ma_commit.h"
|
#include "ma_commit.h"
|
||||||
|
|
||||||
|
|
|
@ -16786,7 +16786,11 @@ static void test_bug43560(void)
|
||||||
fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
|
fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
if (opt_unix_socket)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n");
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Set up a separate connection for this test to avoid messing up the
|
Set up a separate connection for this test to avoid messing up the
|
||||||
general MYSQL object used in other subtests. Use TCP protocol to avoid
|
general MYSQL object used in other subtests. Use TCP protocol to avoid
|
||||||
|
@ -17577,6 +17581,109 @@ static void test_bug13001491()
|
||||||
myquery(rc);
|
myquery(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_mdev4326()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
MYSQL_BIND bind;
|
||||||
|
char query[]= "SELECT * FROM mysql.user LIMIT ?";
|
||||||
|
char str_data[]= "1";
|
||||||
|
unsigned long length= 0;
|
||||||
|
int int_data= 1;
|
||||||
|
int rc, count;
|
||||||
|
my_bool is_null= 0;
|
||||||
|
my_bool error= 0;
|
||||||
|
myheader("test_mdev4326");
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, opt_user, opt_password, "mysql");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "SET GLOBAL general_log = 1");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
check_stmt(stmt);
|
||||||
|
|
||||||
|
/* Numeric parameter test */
|
||||||
|
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
check_stmt(stmt);
|
||||||
|
verify_param_count(stmt, 1);
|
||||||
|
|
||||||
|
memset((char *)&bind, 0, sizeof(bind));
|
||||||
|
bind.buffer_type= MYSQL_TYPE_LONG;
|
||||||
|
bind.buffer= (char *)&int_data;
|
||||||
|
bind.is_null= &is_null;
|
||||||
|
bind.length= &length;
|
||||||
|
bind.error= &error;
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_param(stmt, &bind);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 1);
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 1);
|
||||||
|
int_data= 0;
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 0);
|
||||||
|
rc= mysql_stmt_close(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
/* String parameter test */
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
check_stmt(stmt);
|
||||||
|
verify_param_count(stmt, 1);
|
||||||
|
|
||||||
|
memset((char *)&bind, 0, sizeof(bind));
|
||||||
|
bind.buffer_type= MYSQL_TYPE_STRING;
|
||||||
|
bind.buffer= (char *)str_data;
|
||||||
|
length= bind.buffer_length= sizeof(str_data);
|
||||||
|
bind.is_null= &is_null;
|
||||||
|
bind.length= &length;
|
||||||
|
bind.error= &error;
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_param(stmt, &bind);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 1);
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 1);
|
||||||
|
str_data[0]= '0';
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
count= 0;
|
||||||
|
while (!(rc= mysql_stmt_fetch(stmt)))
|
||||||
|
count++;
|
||||||
|
DIE_UNLESS(count == 0);
|
||||||
|
rc= mysql_stmt_close(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
static struct my_tests_st my_tests[]= {
|
static struct my_tests_st my_tests[]= {
|
||||||
{ "disable_query_logs", disable_query_logs },
|
{ "disable_query_logs", disable_query_logs },
|
||||||
|
@ -17826,6 +17933,7 @@ static struct my_tests_st my_tests[]= {
|
||||||
{ "test_bug58036", test_bug58036 },
|
{ "test_bug58036", test_bug58036 },
|
||||||
{ "test_bug56976", test_bug56976 },
|
{ "test_bug56976", test_bug56976 },
|
||||||
{ "test_bug13001491", test_bug13001491 },
|
{ "test_bug13001491", test_bug13001491 },
|
||||||
|
{ "test_mdev4326", test_mdev4326 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue