mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge knielsen@10.100.52.19:/usr/local/mysql/mysql-4.1-mtr-fix
into mysql.com:/data0/knielsen/mysql-4.1-mtr-fix
This commit is contained in:
@@ -1377,6 +1377,38 @@ dict_col_reposition_in_cache(
|
||||
HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
If the given column name is reserved for InnoDB system columns, return
|
||||
TRUE.*/
|
||||
|
||||
ibool
|
||||
dict_col_name_is_reserved(
|
||||
/*======================*/
|
||||
/* out: TRUE if name is reserved */
|
||||
const char* name) /* in: column name */
|
||||
{
|
||||
/* This check reminds that if a new system column is added to
|
||||
the program, it should be dealt with here. */
|
||||
#if DATA_N_SYS_COLS != 4
|
||||
#error "DATA_N_SYS_COLS != 4"
|
||||
#endif
|
||||
|
||||
static const char* reserved_names[] = {
|
||||
"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
|
||||
};
|
||||
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
|
||||
if (strcmp(name, reserved_names[i]) == 0) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Adds an index to the dictionary cache. */
|
||||
|
||||
@@ -2160,8 +2192,9 @@ dict_foreign_error_report(
|
||||
fputs(msg, file);
|
||||
fputs(" Constraint:\n", file);
|
||||
dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
|
||||
putc('\n', file);
|
||||
if (fk->foreign_index) {
|
||||
fputs("\nThe index in the foreign key in table is ", file);
|
||||
fputs("The index in the foreign key in table is ", file);
|
||||
ut_print_name(file, NULL, fk->foreign_index->name);
|
||||
fputs(
|
||||
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
|
||||
|
@@ -94,6 +94,21 @@ dict_mem_table_create(
|
||||
return(table);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Free a table memory object. */
|
||||
|
||||
void
|
||||
dict_mem_table_free(
|
||||
/*================*/
|
||||
dict_table_t* table) /* in: table */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
|
||||
mutex_free(&(table->autoinc_mutex));
|
||||
mem_heap_free(table->heap);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Creates a cluster memory object. */
|
||||
|
||||
|
@@ -98,6 +98,15 @@ ulint
|
||||
dict_col_get_clust_pos(
|
||||
/*===================*/
|
||||
dict_col_t* col);
|
||||
/********************************************************************
|
||||
If the given column name is reserved for InnoDB system columns, return
|
||||
TRUE. */
|
||||
|
||||
ibool
|
||||
dict_col_name_is_reserved(
|
||||
/*======================*/
|
||||
/* out: TRUE if name is reserved */
|
||||
const char* name); /* in: column name */
|
||||
/************************************************************************
|
||||
Initializes the autoinc counter. It is not an error to initialize an already
|
||||
initialized counter. */
|
||||
|
@@ -55,6 +55,13 @@ dict_mem_table_create(
|
||||
is ignored if the table is made
|
||||
a member of a cluster */
|
||||
ulint n_cols); /* in: number of columns */
|
||||
/********************************************************************
|
||||
Free a table memory object. */
|
||||
|
||||
void
|
||||
dict_mem_table_free(
|
||||
/*================*/
|
||||
dict_table_t* table); /* in: table */
|
||||
/**************************************************************************
|
||||
Creates a cluster memory object. */
|
||||
|
||||
|
@@ -242,6 +242,9 @@ contains the sum of the following flag and the locally stored len. */
|
||||
|
||||
#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
|
||||
|
||||
/* Compile-time constant of the given array's size. */
|
||||
#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ut0dbg.h"
|
||||
#include "ut0ut.h"
|
||||
|
@@ -1474,6 +1474,7 @@ row_create_table_for_mysql(
|
||||
const char* table_name;
|
||||
ulint table_name_len;
|
||||
ulint err;
|
||||
ulint i;
|
||||
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
@@ -1510,6 +1511,19 @@ row_create_table_for_mysql(
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
/* Check that no reserved column names are used. */
|
||||
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
|
||||
dict_col_t* col = dict_table_get_nth_col(table, i);
|
||||
|
||||
if (dict_col_name_is_reserved(col->name)) {
|
||||
|
||||
dict_mem_table_free(table);
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
if (row_mysql_is_recovered_tmp_table(table->name)) {
|
||||
|
@@ -1158,16 +1158,22 @@ my_bool _mi_memmap_file(MI_INFO *info)
|
||||
MYISAM_SHARE *share=info->s;
|
||||
DBUG_ENTER("mi_memmap_file");
|
||||
|
||||
if (!info->s->file_map)
|
||||
if (!share->file_map)
|
||||
{
|
||||
my_off_t data_file_length= share->state.state.data_file_length;
|
||||
if (data_file_length > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
|
||||
{
|
||||
DBUG_PRINT("warning", ("File is too large for mmap"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
|
||||
share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
|
||||
data_file_length + MEMMAP_EXTRA_MARGIN)
|
||||
{
|
||||
DBUG_PRINT("warning",("File isn't extended for memmap"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
file_map=(byte*)
|
||||
mmap(0,share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN,PROT_READ,
|
||||
mmap(0, data_file_length + MEMMAP_EXTRA_MARGIN, PROT_READ,
|
||||
MAP_SHARED | MAP_NORESERVE,info->dfile,0L);
|
||||
if (file_map == (byte*) MAP_FAILED)
|
||||
{
|
||||
@@ -1175,7 +1181,7 @@ my_bool _mi_memmap_file(MI_INFO *info)
|
||||
my_errno=errno;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
info->s->file_map=file_map;
|
||||
share->file_map= file_map;
|
||||
}
|
||||
info->opt_flag|= MEMMAP_USED;
|
||||
info->read_record=share->read_record=_mi_read_mempack_record;
|
||||
|
@@ -34,20 +34,20 @@ static uint lengths[256];
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"help", 'h', "Display help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Synonym for -h.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"count", 'c', "Calculate per-word stats (counts and global weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"dump", 'd', "Dump index (incl. data offsets and word weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"length", 'l', "Report length distribution.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"stats", 's', "Report global stats.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"verbose", 'v', "Be verbose.",
|
||||
(gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"count", 'c', "Calculate per-word stats (counts and global weights).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"length", 'l', "Report length distribution.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", 'h', "Display help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Synonym for -h.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@@ -169,3 +169,11 @@ SELECT CASE '1' WHEN '2' THEN 'BUG' ELSE 'nobug' END;
|
||||
case+union+test
|
||||
case+union+test
|
||||
nobug
|
||||
create table t1(a float, b int default 3);
|
||||
insert into t1 (a) values (2), (11), (8);
|
||||
select min(a), min(case when 1=1 then a else NULL end),
|
||||
min(case when 1!=1 then NULL else a end)
|
||||
from t1 where b=3 group by b;
|
||||
min(a) min(case when 1=1 then a else NULL end) min(case when 1!=1 then NULL else a end)
|
||||
2 2 2
|
||||
drop table t1;
|
||||
|
@@ -666,6 +666,18 @@ Warnings:
|
||||
Warning 1265 Data truncated for column 'Field1' at row 1
|
||||
DROP TABLE t1;
|
||||
SET NAMES latin1;
|
||||
SELECT CONVERT(103, CHAR(50) UNICODE);
|
||||
CONVERT(103, CHAR(50) UNICODE)
|
||||
103
|
||||
SELECT CONVERT(103.0, CHAR(50) UNICODE);
|
||||
CONVERT(103.0, CHAR(50) UNICODE)
|
||||
103.0
|
||||
SELECT CONVERT(-103, CHAR(50) UNICODE);
|
||||
CONVERT(-103, CHAR(50) UNICODE)
|
||||
-103
|
||||
SELECT CONVERT(-103.0, CHAR(50) UNICODE);
|
||||
CONVERT(-103.0, CHAR(50) UNICODE)
|
||||
-103.0
|
||||
CREATE TABLE t1 (
|
||||
a varchar(255) NOT NULL default '',
|
||||
KEY a (a)
|
||||
|
@@ -72,3 +72,10 @@ set @@max_allowed_packet=1048576*100;
|
||||
select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null;
|
||||
compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null
|
||||
0
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
uncompress(a) uncompressed_length(a)
|
||||
NULL NULL
|
||||
a 1
|
||||
drop table t1;
|
||||
|
@@ -604,3 +604,13 @@ count(distinct (f1+1))
|
||||
1
|
||||
3
|
||||
drop table t1;
|
||||
create table t1 (f1 int unsigned, f2 varchar(255));
|
||||
insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
|
||||
select f2,group_concat(f1) from t1 group by f2;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t1 t1 f2 f2 253 255 255 Y 0 0 8
|
||||
def group_concat(f1) 252 400 1 Y 128 0 63
|
||||
f2 group_concat(f1)
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
|
||||
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2
|
||||
drop table t1;
|
||||
|
@@ -287,3 +287,45 @@ check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY);
|
||||
SET GLOBAL key_cache_block_size=1536;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT @@key_cache_block_size;
|
||||
@@key_cache_block_size
|
||||
1536
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
|
||||
CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
|
||||
SET GLOBAL key_cache_block_size=1536;
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
4181
|
||||
SELECT @@key_cache_block_size;
|
||||
@@key_cache_block_size
|
||||
1536
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1,t2;
|
||||
|
@@ -788,3 +788,35 @@ a
|
||||
2
|
||||
2
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
|
||||
(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a;
|
||||
b a
|
||||
10 1
|
||||
10 2
|
||||
20 1
|
||||
20 2
|
||||
30 1
|
||||
30 2
|
||||
(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC;
|
||||
b
|
||||
10
|
||||
10
|
||||
20
|
||||
20
|
||||
30
|
||||
30
|
||||
(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b;
|
||||
b a
|
||||
10 1
|
||||
20 1
|
||||
30 1
|
||||
10 2
|
||||
20 2
|
||||
30 2
|
||||
(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b;
|
||||
b a
|
||||
10 1
|
||||
20 1
|
||||
10 2
|
||||
DROP TABLE t1;
|
||||
|
@@ -44,8 +44,39 @@ select * from t2;
|
||||
a
|
||||
22
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No #
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 13110
|
||||
Relay_Log_File #
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running Yes
|
||||
Slave_SQL_Running Yes
|
||||
Replicate_Do_DB
|
||||
Replicate_Ignore_DB
|
||||
Replicate_Do_Table
|
||||
Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 13110
|
||||
Relay_Log_Space #
|
||||
Until_Condition None
|
||||
Until_Log_File
|
||||
Until_Log_Pos 0
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
stop slave;
|
||||
change master to master_log_pos=401;
|
||||
begin;
|
||||
@@ -62,8 +93,39 @@ select * from t2;
|
||||
a
|
||||
22
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No #
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 13110
|
||||
Relay_Log_File #
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running #
|
||||
Slave_SQL_Running Yes
|
||||
Replicate_Do_DB
|
||||
Replicate_Ignore_DB
|
||||
Replicate_Do_Table
|
||||
Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 13110
|
||||
Relay_Log_Space #
|
||||
Until_Condition None
|
||||
Until_Log_File
|
||||
Until_Log_Pos 0
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
set global max_relay_log_size=0;
|
||||
stop slave;
|
||||
change master to master_log_pos=401;
|
||||
@@ -82,6 +144,37 @@ select * from t2;
|
||||
a
|
||||
22
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No #
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 13110
|
||||
Relay_Log_File #
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running #
|
||||
Slave_SQL_Running Yes
|
||||
Replicate_Do_DB
|
||||
Replicate_Ignore_DB
|
||||
Replicate_Do_Table
|
||||
Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 13110
|
||||
Relay_Log_Space #
|
||||
Until_Condition None
|
||||
Until_Log_File
|
||||
Until_Log_Pos 0
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
drop table t1,t2,t3,t4;
|
||||
|
@@ -10,10 +10,7 @@ reset slave;
|
||||
start slave;
|
||||
stop slave;
|
||||
start slave;
|
||||
select master_pos_wait('master-bin.001',3000)>=0;
|
||||
master_pos_wait('master-bin.001',3000)>=0
|
||||
1
|
||||
select * from t1 where a=8000;
|
||||
a
|
||||
select max(a) from t1;
|
||||
max(a)
|
||||
8000
|
||||
drop table t1;
|
||||
|
@@ -89,3 +89,17 @@ f
|
||||
7
|
||||
drop table t1,t2;
|
||||
create temporary table t3 (f int);
|
||||
set @session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
set @con1_id=connection_id();
|
||||
kill @con1_id;
|
||||
create table t1(f int);
|
||||
insert into t1 values (1);
|
||||
select * from t1 /* must be 1 */;
|
||||
f
|
||||
1
|
||||
drop table t1;
|
||||
|
@@ -119,4 +119,15 @@ SELECT 'case+union+test'
|
||||
UNION
|
||||
SELECT CASE '1' WHEN '2' THEN 'BUG' ELSE 'nobug' END;
|
||||
|
||||
#
|
||||
# Bug #17896: problem with MIN(CASE...)
|
||||
#
|
||||
|
||||
create table t1(a float, b int default 3);
|
||||
insert into t1 (a) values (2), (11), (8);
|
||||
select min(a), min(case when 1=1 then a else NULL end),
|
||||
min(case when 1!=1 then NULL else a end)
|
||||
from t1 where b=3 group by b;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -407,6 +407,14 @@ INSERT INTO t1 VALUES ('-1');
|
||||
DROP TABLE t1;
|
||||
SET NAMES latin1;
|
||||
|
||||
#
|
||||
# Bug#18691 Converting number to UNICODE string returns invalid result
|
||||
#
|
||||
SELECT CONVERT(103, CHAR(50) UNICODE);
|
||||
SELECT CONVERT(103.0, CHAR(50) UNICODE);
|
||||
SELECT CONVERT(-103, CHAR(50) UNICODE);
|
||||
SELECT CONVERT(-103.0, CHAR(50) UNICODE);
|
||||
|
||||
#
|
||||
# Bug#9557 MyISAM utf8 table crash
|
||||
#
|
||||
|
@@ -10,6 +10,3 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
rpl_relayrotate : Unstable test case, bug#12429
|
||||
rpl_until : Unstable test case, bug#12429
|
||||
rpl_deadlock : Unstable test case, bug#12429
|
||||
|
@@ -45,4 +45,13 @@ set @@max_allowed_packet=1048576*100;
|
||||
--replace_result "''" XXX "'1'" XXX
|
||||
eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null;
|
||||
|
||||
#
|
||||
# Bug #18643: problem with null values
|
||||
#
|
||||
|
||||
create table t1(a blob);
|
||||
insert into t1 values(NULL), (compress('a'));
|
||||
select uncompress(a), uncompressed_length(a) from t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -390,4 +390,15 @@ insert into t1 values(1),(2),(3);
|
||||
select f1, group_concat(f1+1) from t1 group by f1 with rollup;
|
||||
select count(distinct (f1+1)) from t1 group by f1 with rollup;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#14169 type of group_concat() result changed to blob if tmp_table was used
|
||||
#
|
||||
create table t1 (f1 int unsigned, f2 varchar(255));
|
||||
insert into t1 values (1,repeat('a',255)),(2,repeat('b',255));
|
||||
--enable_metadata
|
||||
select f2,group_concat(f1) from t1 group by f2;
|
||||
--disable_metadata
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -149,6 +149,7 @@ show status like 'key_blocks_used';
|
||||
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
|
||||
show status like 'key_blocks_unused';
|
||||
|
||||
|
||||
# Cleanup
|
||||
# We don't reset keycache2 as we want to ensure that mysqld will reset it
|
||||
set global keycache2.key_buffer_size=0;
|
||||
@@ -157,7 +158,7 @@ set global keycache2.key_buffer_size=0;
|
||||
set global keycache3.key_buffer_size=100;
|
||||
set global keycache3.key_buffer_size=0;
|
||||
|
||||
# Test case for buf 6447
|
||||
# Test case for bug 6447
|
||||
|
||||
create table t1 (mytext text, FULLTEXT (mytext));
|
||||
insert t1 values ('aaabbb');
|
||||
@@ -168,4 +169,42 @@ check table t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #19079: corrupted index when key_cache_block_size is not multiple of
|
||||
# myisam_block_size
|
||||
|
||||
CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY);
|
||||
SET GLOBAL key_cache_block_size=1536;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT @@key_cache_block_size;
|
||||
CHECK TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
|
||||
CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int);
|
||||
SET GLOBAL key_cache_block_size=1536;
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
INSERT INTO t2(b) SELECT b FROM t1;
|
||||
INSERT INTO t1(b) SELECT b FROM t2;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT @@key_cache_block_size;
|
||||
CHECK TABLE t1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -545,4 +545,18 @@ SELECT a FROM t1 ORDER BY a;
|
||||
(SELECT a FROM t1) ORDER BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was
|
||||
# ignored or 'concatened' to the latter.
|
||||
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
|
||||
|
||||
(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a;
|
||||
(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC;
|
||||
(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b;
|
||||
(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -58,7 +58,7 @@ while ($1)
|
||||
enable_query_log;
|
||||
select * from t1 for update;
|
||||
start slave;
|
||||
--sleep 3 # hope that slave is blocked now
|
||||
--real_sleep 3 # hope that slave is blocked now
|
||||
insert into t2 values(22); # provoke deadlock, slave should be victim
|
||||
commit;
|
||||
sync_with_master;
|
||||
@@ -67,7 +67,9 @@ select * from t2;
|
||||
# check that no error is reported
|
||||
--replace_column 1 # 8 # 9 # 23 # 33 #
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--vertical_results
|
||||
show slave status;
|
||||
--horizontal_results
|
||||
|
||||
# 2) Test lock wait timeout
|
||||
|
||||
@@ -76,15 +78,17 @@ change master to master_log_pos=401; # the BEGIN log event
|
||||
begin;
|
||||
select * from t2 for update; # hold lock
|
||||
start slave;
|
||||
--sleep 10 # slave should have blocked, and be retrying
|
||||
--real_sleep 10 # slave should have blocked, and be retrying
|
||||
commit;
|
||||
sync_with_master;
|
||||
select * from t1; # check that slave succeeded finally
|
||||
select * from t2;
|
||||
# check that no error is reported
|
||||
--replace_column 1 # 8 # 9 # 23 # 33 #
|
||||
--replace_column 1 # 8 # 9 # 11 # 23 # 33 #
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--vertical_results
|
||||
show slave status;
|
||||
--horizontal_results
|
||||
|
||||
# Now we repeat 2), but with BEGIN in the same relay log as
|
||||
# COMMIT (to see if seeking into hot log is ok).
|
||||
@@ -97,14 +101,16 @@ change master to master_log_pos=401;
|
||||
begin;
|
||||
select * from t2 for update;
|
||||
start slave;
|
||||
--sleep 10
|
||||
--real_sleep 10
|
||||
commit;
|
||||
sync_with_master;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
--replace_column 1 # 8 # 9 # 23 # 33 #
|
||||
--replace_column 1 # 8 # 9 # 11 # 23 # 33 #
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--vertical_results
|
||||
show slave status;
|
||||
--horizontal_results
|
||||
|
||||
connection master;
|
||||
drop table t1,t2,t3,t4;
|
||||
|
@@ -52,11 +52,9 @@ start slave;
|
||||
# which proves that the transaction restarted at
|
||||
# the right place.
|
||||
# We must wait for the transaction to commit before
|
||||
# reading, MASTER_POS_WAIT() will do it for sure
|
||||
# (the only statement with position>=3000 is COMMIT).
|
||||
select master_pos_wait('master-bin.001',3000)>=0;
|
||||
select * from t1 where a=8000;
|
||||
|
||||
# reading:
|
||||
sync_with_master;
|
||||
select max(a) from t1;
|
||||
connection master;
|
||||
|
||||
# The following DROP is a very important cleaning task:
|
||||
|
@@ -128,6 +128,32 @@ drop table t1,t2;
|
||||
create temporary table t3 (f int);
|
||||
sync_with_master;
|
||||
|
||||
# The server will now close done
|
||||
#
|
||||
# BUG#17263 incorrect generation DROP temp tables
|
||||
# Temporary tables of connection are dropped in batches
|
||||
# where a batch correspond to pseudo_thread_id
|
||||
# value was set up at the moment of temp table creation
|
||||
#
|
||||
connection con1;
|
||||
set @session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
set @con1_id=connection_id();
|
||||
kill @con1_id;
|
||||
|
||||
#now do something to show that slave is ok after DROP temp tables
|
||||
connection master;
|
||||
create table t1(f int);
|
||||
insert into t1 values (1);
|
||||
|
||||
sync_slave_with_master;
|
||||
#connection slave;
|
||||
select * from t1 /* must be 1 */;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@@ -26,6 +26,7 @@ show binlog events;
|
||||
connection slave;
|
||||
start slave until master_log_file='master-bin.000001', master_log_pos=244;
|
||||
sleep 2;
|
||||
wait_for_slave_to_stop;
|
||||
# here table should be still not deleted
|
||||
select * from t1;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
@@ -37,6 +38,7 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29
|
||||
# again this table should be still not deleted
|
||||
select * from t1;
|
||||
sleep 2;
|
||||
wait_for_slave_to_stop;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_column 1 # 9 # 11 # 23 # 33 #
|
||||
show slave status;
|
||||
@@ -44,6 +46,7 @@ show slave status;
|
||||
# try replicate all until second insert to t2;
|
||||
start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537;
|
||||
sleep 4;
|
||||
wait_for_slave_to_stop;
|
||||
select * from t2;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_column 1 # 9 # 11 # 23 # 33 #
|
||||
@@ -61,6 +64,7 @@ stop slave;
|
||||
start slave until master_log_file='master-bin.000001', master_log_pos=561;
|
||||
# 2 is not enough when running with valgrind
|
||||
--real_sleep 4
|
||||
wait_for_slave_to_stop;
|
||||
# here the sql slave thread should be stopped
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
|
||||
--replace_column 1 # 9 # 23 # 33 #
|
||||
|
@@ -1741,6 +1741,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
|
||||
uint status;
|
||||
int page_st;
|
||||
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
/* Read data in key_cache_block_size increments */
|
||||
do
|
||||
{
|
||||
@@ -1750,7 +1751,6 @@ byte *key_cache_read(KEY_CACHE *keycache,
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
goto no_key_cache;
|
||||
}
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
filepos-= offset;
|
||||
read_length= length;
|
||||
set_if_smaller(read_length, keycache->key_cache_block_size-offset);
|
||||
@@ -1826,6 +1826,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
|
||||
#endif
|
||||
buff+= read_length;
|
||||
filepos+= read_length+offset;
|
||||
offset= 0;
|
||||
|
||||
} while ((length-= read_length));
|
||||
DBUG_RETURN(start);
|
||||
@@ -1877,17 +1878,17 @@ int key_cache_insert(KEY_CACHE *keycache,
|
||||
uint read_length;
|
||||
int page_st;
|
||||
int error;
|
||||
uint offset;
|
||||
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
do
|
||||
{
|
||||
uint offset;
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
if (!keycache->can_be_used)
|
||||
{
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
/* Read data into key cache from buff in key_cache_block_size incr. */
|
||||
filepos-= offset;
|
||||
read_length= length;
|
||||
@@ -1945,6 +1946,7 @@ int key_cache_insert(KEY_CACHE *keycache,
|
||||
|
||||
buff+= read_length;
|
||||
filepos+= read_length+offset;
|
||||
offset= 0;
|
||||
|
||||
} while ((length-= read_length));
|
||||
}
|
||||
@@ -2011,17 +2013,17 @@ int key_cache_write(KEY_CACHE *keycache,
|
||||
/* Key cache is used */
|
||||
uint read_length;
|
||||
int page_st;
|
||||
uint offset;
|
||||
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
do
|
||||
{
|
||||
uint offset;
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
if (!keycache->can_be_used)
|
||||
{
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
goto no_key_cache;
|
||||
}
|
||||
offset= (uint) (filepos & (keycache->key_cache_block_size-1));
|
||||
/* Write data in key_cache_block_size increments */
|
||||
filepos-= offset;
|
||||
read_length= length;
|
||||
|
@@ -111,8 +111,12 @@ SimBlockList::unload(){
|
||||
if(theList != 0){
|
||||
for(int i = 0; i<noOfBlocks; i++){
|
||||
if(theList[i] != 0){
|
||||
#ifdef VM_TRACE
|
||||
theList[i]->~SimulatedBlock();
|
||||
free(theList[i]);
|
||||
#else
|
||||
delete(theList[i]);
|
||||
#endif
|
||||
theList[i] = 0;
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,10 @@
|
||||
|
||||
void Ndbcntr::initData()
|
||||
{
|
||||
|
||||
c_start.reset();
|
||||
cmasterNodeId = 0;
|
||||
cnoStartNodes = 0;
|
||||
cnoWaitrep = 0;
|
||||
// Records with constant sizes
|
||||
ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC];
|
||||
}//Ndbcntr::initData()
|
||||
|
@@ -37,10 +37,25 @@ static Item_result item_store_type(Item_result a,Item_result b)
|
||||
|
||||
static void agg_result_type(Item_result *type, Item **items, uint nitems)
|
||||
{
|
||||
uint i;
|
||||
type[0]= items[0]->result_type();
|
||||
for (i=1 ; i < nitems ; i++)
|
||||
type[0]= item_store_type(type[0], items[i]->result_type());
|
||||
Item **item, **item_end;
|
||||
|
||||
*type= STRING_RESULT;
|
||||
/* Skip beginning NULL items */
|
||||
for (item= items, item_end= item + nitems; item < item_end; item++)
|
||||
{
|
||||
if ((*item)->type() != Item::NULL_ITEM)
|
||||
{
|
||||
*type= (*item)->result_type();
|
||||
item++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Combine result types. Note: NULL items don't affect the result */
|
||||
for (; item < item_end; item++)
|
||||
{
|
||||
if ((*item)->type() != Item::NULL_ITEM)
|
||||
*type= item_store_type(type[0], (*item)->result_type());
|
||||
}
|
||||
}
|
||||
|
||||
static void agg_cmp_type(Item_result *type, Item **items, uint nitems)
|
||||
|
@@ -307,7 +307,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
|
||||
res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
if (max_length > 255)
|
||||
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
|
||||
res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation);
|
||||
else
|
||||
res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation);
|
||||
|
@@ -2850,6 +2850,7 @@ String *Item_func_uncompress::val_str(String *str)
|
||||
|
||||
if (!res)
|
||||
goto err;
|
||||
null_value= 0;
|
||||
if (res->is_empty())
|
||||
return res;
|
||||
|
||||
|
@@ -729,6 +729,13 @@ class Item_func_group_concat : public Item_sum
|
||||
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
|
||||
const char *func_name() const { return "group_concat"; }
|
||||
virtual Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const
|
||||
{
|
||||
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
|
||||
return FIELD_TYPE_BLOB;
|
||||
else
|
||||
return MYSQL_TYPE_VAR_STRING;
|
||||
}
|
||||
void clear();
|
||||
bool add();
|
||||
void reset_field();
|
||||
|
@@ -2221,7 +2221,7 @@ String *Item_char_typecast::val_str(String *str)
|
||||
// Convert character set if differ
|
||||
uint dummy_errors;
|
||||
if (!(res= args[0]->val_str(&tmp_value)) ||
|
||||
str->copy(res->ptr(), res->length(), res->charset(),
|
||||
str->copy(res->ptr(), res->length(), from_cs,
|
||||
cast_cs, &dummy_errors))
|
||||
{
|
||||
null_value= 1;
|
||||
@@ -2261,14 +2261,32 @@ void Item_char_typecast::fix_length_and_dec()
|
||||
For single-byte character sets we allow just to copy
|
||||
from the argument. A single-byte character sets string
|
||||
is always well-formed.
|
||||
|
||||
There is a special trick to convert form a number to ucs2.
|
||||
As numbers have my_charset_bin as their character set,
|
||||
it wouldn't do conversion to ucs2 without an additional action.
|
||||
To force conversion, we should pretend to be non-binary.
|
||||
Let's choose from_cs this way:
|
||||
- If the argument in a number and cast_cs is ucs2 (i.e. mbminlen > 1),
|
||||
then from_cs is set to latin1, to perform latin1 -> ucs2 conversion.
|
||||
- If the argument is a number and cast_cs is ASCII-compatible
|
||||
(i.e. mbminlen == 1), then from_cs is set to cast_cs,
|
||||
which allows just to take over the args[0]->val_str() result
|
||||
and thus avoid unnecessary character set conversion.
|
||||
- If the argument is not a number, then from_cs is set to
|
||||
the argument's charset.
|
||||
*/
|
||||
from_cs= (args[0]->result_type() == INT_RESULT ||
|
||||
args[0]->result_type() == REAL_RESULT) ?
|
||||
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
|
||||
args[0]->collation.collation;
|
||||
charset_conversion= (cast_cs->mbmaxlen > 1) ||
|
||||
!my_charset_same(args[0]->collation.collation, cast_cs) &&
|
||||
args[0]->collation.collation != &my_charset_bin &&
|
||||
!my_charset_same(from_cs, cast_cs) &&
|
||||
from_cs != &my_charset_bin &&
|
||||
cast_cs != &my_charset_bin;
|
||||
collation.set(cast_cs, DERIVATION_IMPLICIT);
|
||||
char_length= (cast_length >= 0) ? cast_length :
|
||||
args[0]->max_length/args[0]->collation.collation->mbmaxlen;
|
||||
args[0]->max_length/from_cs->mbmaxlen;
|
||||
max_length= char_length * cast_cs->mbmaxlen;
|
||||
}
|
||||
|
||||
|
@@ -681,7 +681,7 @@ public:
|
||||
class Item_char_typecast :public Item_typecast
|
||||
{
|
||||
int cast_length;
|
||||
CHARSET_INFO *cast_cs;
|
||||
CHARSET_INFO *cast_cs, *from_cs;
|
||||
bool charset_conversion;
|
||||
String tmp_value;
|
||||
public:
|
||||
|
52
sql/lock.cc
52
sql/lock.cc
@@ -78,6 +78,7 @@ extern HASH open_cache;
|
||||
|
||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
|
||||
uint flags, TABLE **write_locked);
|
||||
static void reset_lock_data(MYSQL_LOCK *sql_lock);
|
||||
static int lock_external(THD *thd, TABLE **table,uint count);
|
||||
static int unlock_external(THD *thd, TABLE **table,uint count);
|
||||
static void print_lock_error(int error);
|
||||
@@ -120,12 +121,16 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
|
||||
*/
|
||||
if (wait_if_global_read_lock(thd, 1, 1))
|
||||
{
|
||||
/* Clear the lock type of all lock data to avoid reusage. */
|
||||
reset_lock_data(sql_lock);
|
||||
my_free((gptr) sql_lock,MYF(0));
|
||||
sql_lock=0;
|
||||
break;
|
||||
}
|
||||
if (thd->version != refresh_version)
|
||||
{
|
||||
/* Clear the lock type of all lock data to avoid reusage. */
|
||||
reset_lock_data(sql_lock);
|
||||
my_free((gptr) sql_lock,MYF(0));
|
||||
goto retry;
|
||||
}
|
||||
@@ -134,6 +139,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
|
||||
thd->proc_info="System lock";
|
||||
if (lock_external(thd, tables, count))
|
||||
{
|
||||
/* Clear the lock type of all lock data to avoid reusage. */
|
||||
reset_lock_data(sql_lock);
|
||||
my_free((gptr) sql_lock,MYF(0));
|
||||
sql_lock=0;
|
||||
thd->proc_info=0;
|
||||
@@ -639,6 +646,9 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
if (table->db_stat & HA_READ_ONLY)
|
||||
{
|
||||
my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name);
|
||||
/* Clear the lock type of the lock data that are stored already. */
|
||||
sql_lock->lock_count= locks - sql_lock->locks;
|
||||
reset_lock_data(sql_lock);
|
||||
my_free((gptr) sql_lock,MYF(0));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@@ -663,6 +673,48 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reset lock type in lock data.
|
||||
|
||||
SYNOPSIS
|
||||
reset_lock_data()
|
||||
sql_lock The MySQL lock.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
After a locking error we want to quit the locking of the table(s).
|
||||
The test case in the bug report for Bug #18544 has the following
|
||||
cases: 1. Locking error in lock_external() due to InnoDB timeout.
|
||||
2. Locking error in get_lock_data() due to missing write permission.
|
||||
3. Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||
|
||||
In all these cases we have already set the lock type into the lock
|
||||
data of the open table(s). If the table(s) are in the open table
|
||||
cache, they could be reused with the non-zero lock type set. This
|
||||
could lead to ignoring a different lock type with the next lock.
|
||||
|
||||
Clear the lock type of all lock data. This ensures that the next
|
||||
lock request will set its lock type properly.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
||||
{
|
||||
THR_LOCK_DATA **ldata;
|
||||
THR_LOCK_DATA **ldata_end;
|
||||
|
||||
for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count;
|
||||
ldata < ldata_end;
|
||||
ldata++)
|
||||
{
|
||||
/* Reset lock type. */
|
||||
(*ldata)->type= TL_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Lock table based on the name.
|
||||
This is used when we need total access to a closed, not open table
|
||||
|
@@ -5253,7 +5253,7 @@ The minimum value for this variable is 4096.",
|
||||
(gptr*) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
|
||||
{"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
|
||||
"Maximum numbrer of prepared statements in the server.",
|
||||
"Maximum number of prepared statements in the server.",
|
||||
(gptr*) &max_prepared_stmt_count, (gptr*) &max_prepared_stmt_count,
|
||||
0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
|
||||
{"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
|
||||
|
134
sql/sql_base.cc
134
sql/sql_base.cc
@@ -483,13 +483,22 @@ void close_temporary(TABLE *table,bool delete_table)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
|
||||
static inline uint tmpkeyval(THD *thd, TABLE *table)
|
||||
{
|
||||
return uint4korr(table->table_cache_key + table->key_length - 4);
|
||||
}
|
||||
|
||||
/* Creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread */
|
||||
|
||||
void close_temporary_tables(THD *thd)
|
||||
{
|
||||
TABLE *table,*next;
|
||||
char *query, *end;
|
||||
uint query_buf_size;
|
||||
bool found_user_tables = 0;
|
||||
TABLE *next,
|
||||
*prev_table /* prev link is not maintained in TABLE's double-linked list */,
|
||||
*table;
|
||||
char *query= (gptr) 0, *end;
|
||||
uint query_buf_size, max_names_len;
|
||||
bool found_user_tables;
|
||||
|
||||
if (!thd->temporary_tables)
|
||||
return;
|
||||
@@ -497,40 +506,105 @@ void close_temporary_tables(THD *thd)
|
||||
LINT_INIT(end);
|
||||
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
|
||||
|
||||
for (table=thd->temporary_tables ; table ; table=table->next)
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names, so 1 does not look
|
||||
insertion sort of temp tables by pseudo_thread_id to build ordered list
|
||||
of sublists of equal pseudo_thread_id
|
||||
*/
|
||||
for (prev_table= thd->temporary_tables,
|
||||
table= prev_table->next,
|
||||
found_user_tables= (prev_table->real_name[0] != '#');
|
||||
table;
|
||||
prev_table= table, table= table->next)
|
||||
{
|
||||
TABLE *prev_sorted /* same as for prev_table */,
|
||||
*sorted;
|
||||
/*
|
||||
table not created directly by the user is moved to the tail.
|
||||
Fixme/todo: nothing (I checked the manual) prevents user to create temp
|
||||
with `#'
|
||||
*/
|
||||
if (table->real_name[0] == '#')
|
||||
continue;
|
||||
else
|
||||
{
|
||||
found_user_tables = 1;
|
||||
}
|
||||
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
|
||||
prev_sorted= sorted, sorted= sorted->next)
|
||||
{
|
||||
if (sorted->real_name[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
|
||||
{
|
||||
/* move into the sorted part of the list from the unsorted */
|
||||
prev_table->next= table->next;
|
||||
table->next= sorted;
|
||||
if (prev_sorted)
|
||||
{
|
||||
prev_sorted->next= table;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->temporary_tables= table;
|
||||
}
|
||||
table= prev_table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
calc query_buf_size as max per sublists, one sublist per pseudo thread id.
|
||||
Also stop at first occurence of `#'-named table that starts
|
||||
all implicitly created temp tables
|
||||
*/
|
||||
for (max_names_len= 0, table=thd->temporary_tables;
|
||||
table && table->real_name[0] != '#';
|
||||
table=table->next)
|
||||
{
|
||||
uint tmp_names_len;
|
||||
for (tmp_names_len= table->key_length + 1;
|
||||
table->next && table->real_name[0] != '#' &&
|
||||
tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
|
||||
table=table->next)
|
||||
{
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names, so 1 might not look
|
||||
enough; indeed it is enough, because table->key_length is greater (by 8,
|
||||
because of server_id and thread_id) than db||table.
|
||||
*/
|
||||
query_buf_size+= table->key_length+1;
|
||||
tmp_names_len += table->next->key_length + 1;
|
||||
}
|
||||
if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
|
||||
}
|
||||
|
||||
if ((query = alloc_root(thd->mem_root, query_buf_size)))
|
||||
/* allocate */
|
||||
if (found_user_tables && mysql_bin_log.is_open() &&
|
||||
(query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
|
||||
// Better add "if exists", in case a RESET MASTER has been done
|
||||
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||
end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||
|
||||
for (table=thd->temporary_tables ; table ; table=next)
|
||||
/* scan sorted tmps to generate sequence of DROP */
|
||||
for (table=thd->temporary_tables; table; table= next)
|
||||
{
|
||||
if (query) // we might be out of memory, but this is not fatal
|
||||
if (query // we might be out of memory, but this is not fatal
|
||||
&& table->real_name[0] != '#')
|
||||
{
|
||||
// skip temporary tables not created directly by the user
|
||||
if (table->real_name[0] != '#')
|
||||
found_user_tables = 1;
|
||||
/*
|
||||
Here we assume table_cache_key always starts
|
||||
with \0 terminated db name
|
||||
*/
|
||||
end = strxmov(end,"`",table->table_cache_key,"`.`",
|
||||
table->real_name,"`,", NullS);
|
||||
char *end_cur;
|
||||
/* Set pseudo_thread_id to be that of the processed table */
|
||||
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
|
||||
/* Loop forward through all tables within the sublist of
|
||||
common pseudo_thread_id to create single DROP query */
|
||||
for (end_cur= end;
|
||||
table && table->real_name[0] != '#' &&
|
||||
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
|
||||
table= next)
|
||||
{
|
||||
end_cur= strxmov(end_cur, "`", table->table_cache_key, "`.`",
|
||||
table->real_name, "`,", NullS);
|
||||
next= table->next;
|
||||
close_temporary(table, 1);
|
||||
}
|
||||
next=table->next;
|
||||
close_temporary(table);
|
||||
}
|
||||
if (query && found_user_tables && mysql_bin_log.is_open())
|
||||
{
|
||||
/* The -1 is to remove last ',' */
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE);
|
||||
/* The -1 is to remove last ',' */
|
||||
Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
|
||||
/*
|
||||
Imagine the thread had created a temp table, then was doing a SELECT, and
|
||||
the SELECT was killed. Then it's not clever to mark the statement above as
|
||||
@@ -543,6 +617,12 @@ void close_temporary_tables(THD *thd)
|
||||
qinfo.error_code= 0;
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
next= table->next;
|
||||
close_temporary(table, 1);
|
||||
}
|
||||
}
|
||||
thd->temporary_tables=0;
|
||||
}
|
||||
|
||||
|
@@ -400,6 +400,7 @@ public:
|
||||
bool check_updateable(char *db, char *table);
|
||||
void print(String *str);
|
||||
|
||||
bool add_fake_select_lex(THD *thd);
|
||||
ulong init_prepare_fake_select_lex(THD *thd);
|
||||
int change_result(select_subselect *result, select_subselect *old_result);
|
||||
inline bool is_prepared() { return prepared; }
|
||||
|
@@ -4189,23 +4189,9 @@ mysql_new_select(LEX *lex, bool move_down)
|
||||
else
|
||||
{
|
||||
select_lex->include_neighbour(lex->current_select);
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
SELECT_LEX *fake= unit->fake_select_lex;
|
||||
if (!fake)
|
||||
{
|
||||
/*
|
||||
as far as we included SELECT_LEX for UNION unit should have
|
||||
fake SELECT_LEX for UNION processing
|
||||
*/
|
||||
if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX()))
|
||||
if (!select_lex->master_unit()->fake_select_lex &&
|
||||
select_lex->master_unit()->add_fake_select_lex(lex->thd))
|
||||
return 1;
|
||||
fake->include_standalone(unit,
|
||||
(SELECT_LEX_NODE**)&unit->fake_select_lex);
|
||||
fake->select_number= INT_MAX;
|
||||
fake->make_empty_select();
|
||||
fake->linkage= GLOBAL_OPTIONS_TYPE;
|
||||
fake->select_limit= HA_POS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
select_lex->master_unit()->global_parameters= select_lex;
|
||||
@@ -4975,6 +4961,60 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a fake SELECT_LEX for a unit
|
||||
|
||||
SYNOPSIS:
|
||||
add_fake_select_lex()
|
||||
thd thread handle
|
||||
|
||||
DESCRIPTION
|
||||
The method create a fake SELECT_LEX object for a unit.
|
||||
This object is created for any union construct containing a union
|
||||
operation and also for any single select union construct of the form
|
||||
(SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
|
||||
or of the form
|
||||
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
|
||||
|
||||
NOTES
|
||||
The object is used to retrieve rows from the temporary table
|
||||
where the result on the union is obtained.
|
||||
|
||||
RETURN VALUES
|
||||
1 on failure to create the object
|
||||
0 on success
|
||||
*/
|
||||
|
||||
bool st_select_lex_unit::add_fake_select_lex(THD *thd)
|
||||
{
|
||||
SELECT_LEX *first_sl= first_select();
|
||||
DBUG_ENTER("add_fake_select_lex");
|
||||
DBUG_ASSERT(!fake_select_lex);
|
||||
|
||||
if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
|
||||
DBUG_RETURN(1);
|
||||
fake_select_lex->include_standalone(this,
|
||||
(SELECT_LEX_NODE**)&fake_select_lex);
|
||||
fake_select_lex->select_number= INT_MAX;
|
||||
fake_select_lex->make_empty_select();
|
||||
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
|
||||
fake_select_lex->select_limit= HA_POS_ERROR;
|
||||
|
||||
if (!first_sl->next_select())
|
||||
{
|
||||
/*
|
||||
This works only for
|
||||
(SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
|
||||
(SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
|
||||
just before the parser starts processing order_list
|
||||
*/
|
||||
global_parameters= fake_select_lex;
|
||||
fake_select_lex->no_table_names_allowed= 1;
|
||||
thd->lex->current_select= fake_select_lex;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
void add_join_on(TABLE_LIST *b,Item *expr)
|
||||
{
|
||||
if (expr)
|
||||
|
@@ -171,7 +171,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
|
||||
register SELECT_LEX *select_lex = &lex->select_lex;
|
||||
DBUG_ENTER("handle_select");
|
||||
|
||||
if (select_lex->next_select())
|
||||
if (select_lex->next_select() || select_lex->master_unit()->fake_select_lex)
|
||||
res=mysql_union(thd, lex, result, &lex->unit);
|
||||
else
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
@@ -4925,7 +4925,8 @@ static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
||||
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
|
||||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE)
|
||||
new_field= item->tmp_table_field_from_field_type(table);
|
||||
else if (item->max_length/item->collation.collation->mbmaxlen > 255)
|
||||
else if (item->max_length/item->collation.collation->mbmaxlen >
|
||||
CONVERT_IF_BIGGER_TO_BLOB)
|
||||
{
|
||||
if (convert_blob_length)
|
||||
new_field= new Field_varstring(convert_blob_length, maybe_null,
|
||||
@@ -5028,7 +5029,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
return new Field_longlong(item_sum->max_length,maybe_null,
|
||||
item->name,table,item->unsigned_flag);
|
||||
case STRING_RESULT:
|
||||
if (item_sum->max_length > 255)
|
||||
if (item_sum->max_length/item_sum->collation.collation->mbmaxlen >
|
||||
CONVERT_IF_BIGGER_TO_BLOB)
|
||||
{
|
||||
if (convert_blob_length)
|
||||
return new Field_varstring(convert_blob_length, maybe_null,
|
||||
|
@@ -184,7 +184,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
|
||||
thd_arg->lex->current_select= sl= first_select= first_select_in_union();
|
||||
found_rows_for_union= first_select->options & OPTION_FOUND_ROWS;
|
||||
is_union= test(first_select->next_select());
|
||||
is_union= test(first_select->next_select() || fake_select_lex);
|
||||
|
||||
/* Global option */
|
||||
|
||||
|
@@ -3790,15 +3790,33 @@ order_clause:
|
||||
ORDER_SYM BY
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
|
||||
lex->current_select->olap !=
|
||||
UNSPECIFIED_OLAP_TYPE)
|
||||
SELECT_LEX *sel= lex->current_select;
|
||||
SELECT_LEX_UNIT *unit= sel-> master_unit();
|
||||
if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
|
||||
sel->olap != UNSPECIFIED_OLAP_TYPE)
|
||||
{
|
||||
net_printf(lex->thd, ER_WRONG_USAGE,
|
||||
"CUBE/ROLLUP",
|
||||
"ORDER BY");
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
|
||||
{
|
||||
/*
|
||||
A query of the of the form (SELECT ...) ORDER BY order_list is
|
||||
executed in the same way as the query
|
||||
SELECT ... ORDER BY order_list
|
||||
unless the SELECT construct contains ORDER BY or LIMIT clauses.
|
||||
Otherwise we create a fake SELECT_LEX if it has not been created
|
||||
yet.
|
||||
*/
|
||||
SELECT_LEX *first_sl= unit->first_select();
|
||||
if (!first_sl->next_select() &&
|
||||
(first_sl->order_list.elements ||
|
||||
first_sl->select_limit != HA_POS_ERROR) &&
|
||||
unit->add_fake_select_lex(lex->thd))
|
||||
YYABORT;
|
||||
}
|
||||
} order_list;
|
||||
|
||||
order_list:
|
||||
|
@@ -60,6 +60,7 @@
|
||||
|
||||
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
|
||||
#define MAX_FIELD_CHARLENGTH 255
|
||||
#define CONVERT_IF_BIGGER_TO_BLOB 255
|
||||
/* Max column width +1 */
|
||||
#define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1)
|
||||
|
||||
|
Reference in New Issue
Block a user