Commit a806fd13 authored by Sergey Vojtovich's avatar Sergey Vojtovich

Merge mysql-next-mr to mysql-next-mr-svoj.

parents fd433cfb 1e2abc8f
...@@ -5407,4 +5407,60 @@ test.t1 repair status OK ...@@ -5407,4 +5407,60 @@ test.t1 repair status OK
select * from t1 limit 1; select * from t1 limit 1;
a a
drop table t1; drop table t1;
#
# Test for the following cases
# 1) integers and strings enclosed in quotes
# 2) integers and strings not enclosed in quotes
# 3) \X characters with quotes
# 4) \X characters outside quotes
#
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
# remove the already existing .CSV file if any
# create the .CSV file that contains the hard-coded data used in
# testing
1,"integer sans quotes"
1,string sans quotes
1,quotes"in between" strings
"1",Integer with quote and string with no quote
1,"escape sequence \n \" \\ \r \a within quotes"
1,escape sequence \n \" \\ \r \a without quotes
# select from the table in which the data has been filled in using
# the hard-coded .CSV file
SELECT * FROM t1;
c1 c2
1 integer sans quotes
1 string sans quotes
1 quotes"in between" strings
1 Integer with quote and string with no quote
1 escape sequence
" \ \a within quotes
1 escape sequence
" \ \a without quotes
DROP TABLE t1;
# Test for the case when a field begins with a quote, but does not end in a
# quote.
# Note: This results in an error.
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
# remove the already existing .CSV file if any
# create the .CSV file that contains the hard-coded data used in
# testing
1,"string only at the beginning quotes
# select from the table in which the data has been filled in using
# the hard-coded .CSV file
SELECT * FROM t1;
ERROR HY000: Table 't1' is marked as crashed and should be repaired
DROP TABLE t1;
# Test for the case when a field ends with a quote, but does not begin in a
# quote.
# Note: This results in an error.
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
# remove the already existing .CSV file if any
# create the .CSV file that contains the hard-coded data used in
# testing
1,string with only ending quotes"
# select from the table in which the data has been filled in using
# the hard-coded .CSV file
SELECT * FROM t1;
ERROR HY000: Table 't1' is marked as crashed and should be repaired
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
......
...@@ -65,6 +65,7 @@ SESSION_STATUS ...@@ -65,6 +65,7 @@ SESSION_STATUS
SESSION_VARIABLES SESSION_VARIABLES
STATISTICS STATISTICS
TABLES TABLES
TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS
...@@ -103,6 +104,7 @@ inner join information_schema.TABLES v2 on (v1.c=v2.table_name) ...@@ -103,6 +104,7 @@ inner join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%"; where v1.c like "t%";
c table_name c table_name
TABLES TABLES TABLES TABLES
TABLESPACES TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS TRIGGERS TRIGGERS
...@@ -122,6 +124,7 @@ left join information_schema.TABLES v2 on (v1.c=v2.table_name) ...@@ -122,6 +124,7 @@ left join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%"; where v1.c like "t%";
c table_name c table_name
TABLES TABLES TABLES TABLES
TABLESPACES TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS TRIGGERS TRIGGERS
...@@ -141,6 +144,7 @@ right join information_schema.TABLES v2 on (v1.c=v2.table_name) ...@@ -141,6 +144,7 @@ right join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%"; where v1.c like "t%";
c table_name c table_name
TABLES TABLES TABLES TABLES
TABLESPACES TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS TRIGGERS TRIGGERS
...@@ -628,6 +632,7 @@ COLLATIONS SYSTEM VIEW MEMORY ...@@ -628,6 +632,7 @@ COLLATIONS SYSTEM VIEW MEMORY
show tables from information_schema like "T%"; show tables from information_schema like "T%";
Tables_in_information_schema (T%) Tables_in_information_schema (T%)
TABLES TABLES
TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS
...@@ -637,6 +642,7 @@ use information_schema; ...@@ -637,6 +642,7 @@ use information_schema;
show full tables like "T%"; show full tables like "T%";
Tables_in_information_schema (T%) Table_type Tables_in_information_schema (T%) Table_type
TABLES SYSTEM VIEW TABLES SYSTEM VIEW
TABLESPACES SYSTEM VIEW
TABLE_CONSTRAINTS SYSTEM VIEW TABLE_CONSTRAINTS SYSTEM VIEW
TABLE_PRIVILEGES SYSTEM VIEW TABLE_PRIVILEGES SYSTEM VIEW
TRIGGERS SYSTEM VIEW TRIGGERS SYSTEM VIEW
...@@ -649,6 +655,7 @@ use information_schema; ...@@ -649,6 +655,7 @@ use information_schema;
show tables like "T%"; show tables like "T%";
Tables_in_information_schema (T%) Tables_in_information_schema (T%)
TABLES TABLES
TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS
...@@ -855,7 +862,7 @@ table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') ...@@ -855,7 +862,7 @@ table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest')
AND table_name not like 'ndb%' AND table_name not like 'innodb_%' AND table_name not like 'ndb%' AND table_name not like 'innodb_%'
GROUP BY TABLE_SCHEMA; GROUP BY TABLE_SCHEMA;
table_schema count(*) table_schema count(*)
information_schema 28 information_schema 29
mysql 22 mysql 22
create table t1 (i int, j int); create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row create trigger trg1 before insert on t1 for each row
...@@ -1317,6 +1324,7 @@ SESSION_STATUS information_schema.SESSION_STATUS 1 ...@@ -1317,6 +1324,7 @@ SESSION_STATUS information_schema.SESSION_STATUS 1
SESSION_VARIABLES information_schema.SESSION_VARIABLES 1 SESSION_VARIABLES information_schema.SESSION_VARIABLES 1
STATISTICS information_schema.STATISTICS 1 STATISTICS information_schema.STATISTICS 1
TABLES information_schema.TABLES 1 TABLES information_schema.TABLES 1
TABLESPACES information_schema.TABLESPACES 1
TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TRIGGERS information_schema.TRIGGERS 1 TRIGGERS information_schema.TRIGGERS 1
......
...@@ -28,6 +28,7 @@ SESSION_STATUS ...@@ -28,6 +28,7 @@ SESSION_STATUS
SESSION_VARIABLES SESSION_VARIABLES
STATISTICS STATISTICS
TABLES TABLES
TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS
...@@ -36,6 +37,7 @@ VIEWS ...@@ -36,6 +37,7 @@ VIEWS
show tables from INFORMATION_SCHEMA like 'T%'; show tables from INFORMATION_SCHEMA like 'T%';
Tables_in_information_schema (T%) Tables_in_information_schema (T%)
TABLES TABLES
TABLESPACES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TRIGGERS TRIGGERS
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
# #
# Don't test this under valgrind, memory leaks will occur # Don't test this under valgrind, memory leaks will occur
# Binary must be compiled with debug for crash to occur # Binary must be compiled with debug for crash to occur
call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
SET GLOBAL delay_key_write=ALL; SET GLOBAL delay_key_write=ALL;
CREATE TABLE t1(a INT, CREATE TABLE t1(a INT,
b INT, b INT,
......
...@@ -102,6 +102,7 @@ Database: information_schema ...@@ -102,6 +102,7 @@ Database: information_schema
| SESSION_VARIABLES | | SESSION_VARIABLES |
| STATISTICS | | STATISTICS |
| TABLES | | TABLES |
| TABLESPACES |
| TABLE_CONSTRAINTS | | TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES | | TABLE_PRIVILEGES |
| TRIGGERS | | TRIGGERS |
...@@ -142,6 +143,7 @@ Database: INFORMATION_SCHEMA ...@@ -142,6 +143,7 @@ Database: INFORMATION_SCHEMA
| SESSION_VARIABLES | | SESSION_VARIABLES |
| STATISTICS | | STATISTICS |
| TABLES | | TABLES |
| TABLESPACES |
| TABLE_CONSTRAINTS | | TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES | | TABLE_PRIVILEGES |
| TRIGGERS | | TRIGGERS |
......
...@@ -252,6 +252,15 @@ def information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 u ...@@ -252,6 +252,15 @@ def information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 u
def information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select def information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
def information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select def information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
def information_schema TABLESPACES AUTOEXTEND_SIZE 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
def information_schema TABLESPACES ENGINE 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLESPACES EXTENT_SIZE 5 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
def information_schema TABLESPACES LOGFILE_GROUP_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLESPACES MAXIMUM_SIZE 7 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
def information_schema TABLESPACES NODEGROUP_ID 8 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
def information_schema TABLESPACES TABLESPACE_COMMENT 9 NULL YES varchar 2048 6144 NULL NULL utf8 utf8_general_ci varchar(2048) select
def information_schema TABLESPACES TABLESPACE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLESPACES TABLESPACE_TYPE 3 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
def information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
def information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
...@@ -607,6 +616,15 @@ NULL information_schema TABLES CHECK_TIME datetime NULL NULL NULL NULL datetime ...@@ -607,6 +616,15 @@ NULL information_schema TABLES CHECK_TIME datetime NULL NULL NULL NULL datetime
NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) unsigned NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema TABLES CREATE_OPTIONS varchar 255 765 utf8 utf8_general_ci varchar(255) 3.0000 information_schema TABLES CREATE_OPTIONS varchar 255 765 utf8 utf8_general_ci varchar(255)
3.0000 information_schema TABLES TABLE_COMMENT varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema TABLES TABLE_COMMENT varchar 80 240 utf8 utf8_general_ci varchar(80)
3.0000 information_schema TABLESPACES TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES ENGINE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES TABLESPACE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLESPACES LOGFILE_GROUP_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
NULL information_schema TABLESPACES EXTENT_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema TABLESPACES AUTOEXTEND_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema TABLESPACES MAXIMUM_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema TABLESPACES NODEGROUP_ID bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema TABLESPACES TABLESPACE_COMMENT varchar 2048 6144 utf8 utf8_general_ci varchar(2048)
3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
......
...@@ -521,6 +521,29 @@ user_comment ...@@ -521,6 +521,29 @@ user_comment
Separator ----------------------------------------------------- Separator -----------------------------------------------------
TABLE_CATALOG def TABLE_CATALOG def
TABLE_SCHEMA information_schema TABLE_SCHEMA information_schema
TABLE_NAME TABLESPACES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
VERSION 10
ROW_FORMAT Fixed
TABLE_ROWS #TBLR#
AVG_ROW_LENGTH #ARL#
DATA_LENGTH #DL#
MAX_DATA_LENGTH #MDL#
INDEX_LENGTH #IL#
DATA_FREE #DF#
AUTO_INCREMENT NULL
CREATE_TIME #CRT#
UPDATE_TIME #UT#
CHECK_TIME #CT#
TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
TABLE_NAME TABLE_CONSTRAINTS TABLE_NAME TABLE_CONSTRAINTS
TABLE_TYPE SYSTEM VIEW TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY ENGINE MEMORY
...@@ -1159,6 +1182,29 @@ user_comment ...@@ -1159,6 +1182,29 @@ user_comment
Separator ----------------------------------------------------- Separator -----------------------------------------------------
TABLE_CATALOG def TABLE_CATALOG def
TABLE_SCHEMA information_schema TABLE_SCHEMA information_schema
TABLE_NAME TABLESPACES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
VERSION 10
ROW_FORMAT Fixed
TABLE_ROWS #TBLR#
AVG_ROW_LENGTH #ARL#
DATA_LENGTH #DL#
MAX_DATA_LENGTH #MDL#
INDEX_LENGTH #IL#
DATA_FREE #DF#
AUTO_INCREMENT NULL
CREATE_TIME #CRT#
UPDATE_TIME #UT#
CHECK_TIME #CT#
TABLE_COLLATION utf8_general_ci
CHECKSUM NULL
CREATE_OPTIONS #CO#
TABLE_COMMENT #TC#
user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
TABLE_NAME TABLE_CONSTRAINTS TABLE_NAME TABLE_CONSTRAINTS
TABLE_TYPE SYSTEM VIEW TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY ENGINE MEMORY
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
--disable_warnings --disable_warnings
--disable_query_log --disable_query_log
drop table if exists t1_will_crash; drop table if exists t1_will_crash;
call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
--enable_query_log --enable_query_log
--enable_warnings --enable_warnings
......
...@@ -1819,4 +1819,84 @@ repair table t1; ...@@ -1819,4 +1819,84 @@ repair table t1;
select * from t1 limit 1; select * from t1 limit 1;
drop table t1; drop table t1;
#
# Bug #40814 CSV engine does not parse \X characters when they occur in unquoted fields
#
--echo #
--echo # Test for the following cases
--echo # 1) integers and strings enclosed in quotes
--echo # 2) integers and strings not enclosed in quotes
--echo # 3) \X characters with quotes
--echo # 4) \X characters outside quotes
--echo #
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
--echo # remove the already existing .CSV file if any
--remove_file $MYSQLD_DATADIR/test/t1.CSV
--echo # create the .CSV file that contains the hard-coded data used in
--echo # testing
--write_file $MYSQLD_DATADIR/test/t1.CSV
1,"integer sans quotes"
1,string sans quotes
1,quotes"in between" strings
"1",Integer with quote and string with no quote
1,"escape sequence \n \" \\ \r \a within quotes"
1,escape sequence \n \" \\ \r \a without quotes
EOF
--cat_file $MYSQLD_DATADIR/test/t1.CSV
--echo # select from the table in which the data has been filled in using
--echo # the hard-coded .CSV file
SELECT * FROM t1;
DROP TABLE t1;
--echo # Test for the case when a field begins with a quote, but does not end in a
--echo # quote.
--echo # Note: This results in an error.
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
--echo # remove the already existing .CSV file if any
--remove_file $MYSQLD_DATADIR/test/t1.CSV
--echo # create the .CSV file that contains the hard-coded data used in
--echo # testing
--write_file $MYSQLD_DATADIR/test/t1.CSV
1,"string only at the beginning quotes
EOF
--cat_file $MYSQLD_DATADIR/test/t1.CSV
--echo # select from the table in which the data has been filled in using
--echo # the hard-coded .CSV file
--error ER_CRASHED_ON_USAGE
SELECT * FROM t1;
DROP TABLE t1;
--echo # Test for the case when a field ends with a quote, but does not begin in a
--echo # quote.
--echo # Note: This results in an error.
CREATE TABLE t1(c1 INT NOT NULL, c2 VARCHAR(50) NOT NULL) ENGINE=csv;
--echo # remove the already existing .CSV file if any
--remove_file $MYSQLD_DATADIR/test/t1.CSV
--echo # create the .CSV file that contains the hard-coded data used in
--echo # testing
--write_file $MYSQLD_DATADIR/test/t1.CSV
1,string with only ending quotes"
EOF
--cat_file $MYSQLD_DATADIR/test/t1.CSV
--echo # select from the table in which the data has been filled in using
--echo # the hard-coded .CSV file
--error ER_CRASHED_ON_USAGE
SELECT * FROM t1;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
--echo # Binary must be compiled with debug for crash to occur --echo # Binary must be compiled with debug for crash to occur
--source include/have_debug.inc --source include/have_debug.inc
call mtr.add_suppression("Got an error from thread_id=.*ha_myisam.cc:");
call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
SET GLOBAL delay_key_write=ALL; SET GLOBAL delay_key_write=ALL;
CREATE TABLE t1(a INT, CREATE TABLE t1(a INT,
......
...@@ -94,6 +94,11 @@ static bool ndbcluster_show_status(handlerton *hton, THD*, ...@@ -94,6 +94,11 @@ static bool ndbcluster_show_status(handlerton *hton, THD*,
static int ndbcluster_alter_tablespace(handlerton *hton, static int ndbcluster_alter_tablespace(handlerton *hton,
THD* thd, THD* thd,
st_alter_tablespace *info); st_alter_tablespace *info);
static int ndbcluster_fill_is_table(handlerton *hton,
THD *thd,
TABLE_LIST *tables,
COND *cond,
enum enum_schema_tables);
static int ndbcluster_fill_files_table(handlerton *hton, static int ndbcluster_fill_files_table(handlerton *hton,
THD *thd, THD *thd,
TABLE_LIST *tables, TABLE_LIST *tables,
...@@ -7403,7 +7408,7 @@ static int ndbcluster_init(void *p) ...@@ -7403,7 +7408,7 @@ static int ndbcluster_init(void *p)
h->alter_tablespace= ndbcluster_alter_tablespace; /* Show status */ h->alter_tablespace= ndbcluster_alter_tablespace; /* Show status */
h->partition_flags= ndbcluster_partition_flags; /* Partition flags */ h->partition_flags= ndbcluster_partition_flags; /* Partition flags */
h->alter_table_flags=ndbcluster_alter_table_flags; /* Alter table flags */ h->alter_table_flags=ndbcluster_alter_table_flags; /* Alter table flags */
h->fill_files_table= ndbcluster_fill_files_table; h->fill_is_table= ndbcluster_fill_is_table;
#ifdef HAVE_NDB_BINLOG #ifdef HAVE_NDB_BINLOG
ndbcluster_binlog_init_handlerton(); ndbcluster_binlog_init_handlerton();
#endif #endif
...@@ -7539,6 +7544,34 @@ ndbcluster_init_error: ...@@ -7539,6 +7544,34 @@ ndbcluster_init_error:
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/**
Used to fill in INFORMATION_SCHEMA* tables.
@param hton handle to the handlerton structure
@param thd the thread/connection descriptor
@param[in,out] tables the information schema table that is filled up
@param cond used for conditional pushdown to storage engine
@param schema_table_idx the table id that distinguishes the type of table
@return Operation status
*/
static int ndbcluster_fill_is_table(handlerton *hton,
THD *thd,
TABLE_LIST *tables,
COND *cond,
enum enum_schema_tables schema_table_idx)
{
int ret= 0;
if (schema_table_idx == SCH_FILES)
{
ret= ndbcluster_fill_files_table(hton, thd, tables, cond);
}
return ret;
}
static int ndbcluster_end(handlerton *hton, ha_panic_function type) static int ndbcluster_end(handlerton *hton, ha_panic_function type)
{ {
DBUG_ENTER("ndbcluster_end"); DBUG_ENTER("ndbcluster_end");
......
...@@ -125,6 +125,29 @@ ...@@ -125,6 +125,29 @@
*/ */
#define HA_BINLOG_ROW_CAPABLE (LL(1) << 34) #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
/*
When a multiple key conflict happens in a REPLACE command mysql
expects the conflicts to be reported in the ascending order of
key names.
For e.g.
CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
NULL, INDEX(c));
REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
MySQL expects the conflict with 'a' to be reported before the conflict with
'b'.
If the underlying storage engine does not report the conflicting keys in
ascending order, it causes unexpected errors when the REPLACE command is
executed.
This flag helps the underlying SE to inform the server that the keys are not
ordered.
*/
#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36)
/* /*
Set of all binlog flags. Currently only contain the capabilities Set of all binlog flags. Currently only contain the capabilities
...@@ -513,6 +536,47 @@ class st_alter_tablespace : public Sql_alloc ...@@ -513,6 +536,47 @@ class st_alter_tablespace : public Sql_alloc
/* The handler for a table type. Will be included in the TABLE structure */ /* The handler for a table type. Will be included in the TABLE structure */
struct TABLE; struct TABLE;
/*
Make sure that the order of schema_tables and enum_schema_tables are the same.
*/
enum enum_schema_tables
{
SCH_CHARSETS= 0,
SCH_COLLATIONS,
SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
SCH_COLUMNS,
SCH_COLUMN_PRIVILEGES,
SCH_ENGINES,
SCH_EVENTS,
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
SCH_PARTITIONS,
SCH_PLUGINS,
SCH_PROCESSLIST,
SCH_PROFILES,
SCH_REFERENTIAL_CONSTRAINTS,
SCH_PROCEDURES,
SCH_SCHEMATA,
SCH_SCHEMA_PRIVILEGES,
SCH_SESSION_STATUS,
SCH_SESSION_VARIABLES,
SCH_STATISTICS,
SCH_STATUS,
SCH_TABLES,
SCH_TABLESPACES,
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
SCH_VARIABLES,
SCH_VIEWS
};
struct TABLE_SHARE; struct TABLE_SHARE;
struct st_foreign_key_info; struct st_foreign_key_info;
typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
...@@ -677,9 +741,9 @@ struct handlerton ...@@ -677,9 +741,9 @@ struct handlerton
uint (*partition_flags)(); uint (*partition_flags)();
uint (*alter_table_flags)(uint flags); uint (*alter_table_flags)(uint flags);
int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info); int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
int (*fill_files_table)(handlerton *hton, THD *thd, int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
TABLE_LIST *tables, class Item *cond,
class Item *cond); enum enum_schema_tables);
uint32 flags; /* global handler flags */ uint32 flags; /* global handler flags */
/* /*
Those handlerton functions below are properly initialized at handler Those handlerton functions below are properly initialized at handler
......
...@@ -2472,6 +2472,17 @@ inline void kill_delayed_threads(void) {} ...@@ -2472,6 +2472,17 @@ inline void kill_delayed_threads(void) {}
#define IS_FILES_CHECKSUM 35 #define IS_FILES_CHECKSUM 35
#define IS_FILES_STATUS 36 #define IS_FILES_STATUS 36
#define IS_FILES_EXTRA 37 #define IS_FILES_EXTRA 37
#define IS_TABLESPACES_TABLESPACE_NAME 0
#define IS_TABLESPACES_ENGINE 1
#define IS_TABLESPACES_TABLESPACE_TYPE 2
#define IS_TABLESPACES_LOGFILE_GROUP_NAME 3
#define IS_TABLESPACES_EXTENT_SIZE 4
#define IS_TABLESPACES_AUTOEXTEND_SIZE 5
#define IS_TABLESPACES_MAXIMUM_SIZE 6
#define IS_TABLESPACES_NODEGROUP_ID 7
#define IS_TABLESPACES_TABLESPACE_COMMENT 8
void init_fill_schema_files_row(TABLE* table); void init_fill_schema_files_row(TABLE* table);
bool schema_table_store_record(THD *thd, TABLE *table); bool schema_table_store_record(THD *thd, TABLE *table);
......
...@@ -1322,6 +1322,23 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ...@@ -1322,6 +1322,23 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
static int last_uniq_key(TABLE *table,uint keynr) static int last_uniq_key(TABLE *table,uint keynr)
{ {
/*
When an underlying storage engine informs that the unique key
conflicts are not reported in the ascending order by setting
the HA_DUPLICATE_KEY_NOT_IN_ORDER flag, we cannot rely on this
information to determine the last key conflict.
The information about the last key conflict will be used to
do a replace of the new row on the conflicting row, rather
than doing a delete (of old row) + insert (of new row).
Hence check for this flag and disable replacing the last row
by returning 0 always. Returning 0 will result in doing
a delete + insert always.
*/
if (table->file->ha_table_flags() & HA_DUPLICATE_KEY_NOT_IN_ORDER)
return 0;
while (++keynr < table->s->keys) while (++keynr < table->s->keys)
if (table->key_info[keynr].flags & HA_NOSAME) if (table->key_info[keynr].flags & HA_NOSAME)
return 0; return 0;
......
...@@ -6221,32 +6221,33 @@ bool get_schema_tables_result(JOIN *join, ...@@ -6221,32 +6221,33 @@ bool get_schema_tables_result(JOIN *join,
DBUG_RETURN(result); DBUG_RETURN(result);
} }
struct run_hton_fill_schema_files_args struct run_hton_fill_schema_table_args
{ {
TABLE_LIST *tables; TABLE_LIST *tables;
COND *cond; COND *cond;
}; };
static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin, static my_bool run_hton_fill_schema_table(THD *thd, plugin_ref plugin,
void *arg) void *arg)
{ {
struct run_hton_fill_schema_files_args *args= struct run_hton_fill_schema_table_args *args=
(run_hton_fill_schema_files_args *) arg; (run_hton_fill_schema_table_args *) arg;
handlerton *hton= plugin_data(plugin, handlerton *); handlerton *hton= plugin_data(plugin, handlerton *);
if(hton->fill_files_table && hton->state == SHOW_OPTION_YES) if (hton->fill_is_table && hton->state == SHOW_OPTION_YES)
hton->fill_files_table(hton, thd, args->tables, args->cond); hton->fill_is_table(hton, thd, args->tables, args->cond,
get_schema_table_idx(args->tables->schema_table));
return false; return false;
} }
int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond) int hton_fill_schema_table(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
DBUG_ENTER("fill_schema_files"); DBUG_ENTER("hton_fill_schema_table");
struct run_hton_fill_schema_files_args args; struct run_hton_fill_schema_table_args args;
args.tables= tables; args.tables= tables;
args.cond= cond; args.cond= cond;
plugin_foreach(thd, run_hton_fill_schema_files, plugin_foreach(thd, run_hton_fill_schema_table,
MYSQL_STORAGE_ENGINE_PLUGIN, &args); MYSQL_STORAGE_ENGINE_PLUGIN, &args);
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -6828,6 +6829,29 @@ ST_FIELD_INFO referential_constraints_fields_info[]= ...@@ -6828,6 +6829,29 @@ ST_FIELD_INFO referential_constraints_fields_info[]=
}; };
ST_FIELD_INFO tablespaces_fields_info[]=
{
{"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
SKIP_OPEN_TABLE},
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLESPACE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL,
0, SKIP_OPEN_TABLE},
{"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL,
0, SKIP_OPEN_TABLE},
{"EXTENT_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE},
{"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE},
{"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE},
{"NODEGROUP_ID", 21, MYSQL_TYPE_LONGLONG, 0,
MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED, 0, SKIP_OPEN_TABLE},
{"TABLESPACE_COMMENT", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0,
SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
/* /*
Description of ST_FIELD_INFO in table.h Description of ST_FIELD_INFO in table.h
...@@ -6858,7 +6882,7 @@ ST_SCHEMA_TABLE schema_tables[]= ...@@ -6858,7 +6882,7 @@ ST_SCHEMA_TABLE schema_tables[]=
0, make_old_format, 0, -1, -1, 0, 0}, 0, make_old_format, 0, -1, -1, 0, 0},
#endif #endif
{"FILES", files_fields_info, create_schema_table, {"FILES", files_fields_info, create_schema_table,
fill_schema_files, 0, 0, -1, -1, 0, 0}, hton_fill_schema_table, 0, 0, -1, -1, 0, 0},
{"GLOBAL_STATUS", variables_fields_info, create_schema_table, {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
fill_status, make_old_format, 0, 0, -1, 0, 0}, fill_status, make_old_format, 0, 0, -1, 0, 0},
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
...@@ -6899,6 +6923,8 @@ ST_SCHEMA_TABLE schema_tables[]= ...@@ -6899,6 +6923,8 @@ ST_SCHEMA_TABLE schema_tables[]=
{"TABLES", tables_fields_info, create_schema_table, {"TABLES", tables_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE}, OPTIMIZE_I_S_TABLE},
{"TABLESPACES", tablespaces_fields_info, create_schema_table,
hton_fill_schema_table, 0, 0, -1, -1, 0, 0},
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, get_all_tables, 0, get_schema_constraints_record, 3, 4, 0,
OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY},
......
...@@ -878,47 +878,6 @@ typedef struct st_foreign_key_info ...@@ -878,47 +878,6 @@ typedef struct st_foreign_key_info
List<LEX_STRING> referenced_fields; List<LEX_STRING> referenced_fields;
} FOREIGN_KEY_INFO; } FOREIGN_KEY_INFO;
/*
Make sure that the order of schema_tables and enum_schema_tables are the same.
*/
enum enum_schema_tables
{
SCH_CHARSETS= 0,
SCH_COLLATIONS,
SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
SCH_COLUMNS,
SCH_COLUMN_PRIVILEGES,
SCH_ENGINES,
SCH_EVENTS,
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
SCH_PARTITIONS,
SCH_PLUGINS,
SCH_PROCESSLIST,
SCH_PROFILES,
SCH_REFERENTIAL_CONSTRAINTS,
SCH_PROCEDURES,
SCH_SCHEMATA,
SCH_SCHEMA_PRIVILEGES,
SCH_SESSION_STATUS,
SCH_SESSION_VARIABLES,
SCH_STATISTICS,
SCH_STATUS,
SCH_TABLES,
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
SCH_VARIABLES,
SCH_VIEWS
};
#define MY_I_S_MAYBE_NULL 1 #define MY_I_S_MAYBE_NULL 1
#define MY_I_S_UNSIGNED 2 #define MY_I_S_UNSIGNED 2
......
...@@ -660,6 +660,33 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -660,6 +660,33 @@ int ha_tina::find_current_row(uchar *buf)
memset(buf, 0, table->s->null_bytes); memset(buf, 0, table->s->null_bytes);
/*
Parse the line obtained using the following algorithm
BEGIN
1) Store the EOL (end of line) for the current row
2) Until all the fields in the current query have not been
filled
2.1) If the current character is a quote
2.1.1) Until EOL has not been reached
a) If end of current field is reached, move
to next field and jump to step 2.3
b) If current character is a \\ handle
\\n, \\r, \\, \\"
c) else append the current character into the buffer
before checking that EOL has not been reached.
2.2) If the current character does not begin with a quote
2.2.1) Until EOL has not been reached
a) If the end of field has been reached move to the
next field and jump to step 2.3
b) If current character begins with \\ handle
\\n, \\r, \\, \\"
c) else append the current character into the buffer
before checking that EOL has not been reached.
2.3) Store the current field value and jump to 2)
TERMINATE
*/
for (Field **field=table->field ; *field ; field++) for (Field **field=table->field ; *field ; field++)
{ {
char curr_char; char curr_char;
...@@ -668,19 +695,23 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -668,19 +695,23 @@ int ha_tina::find_current_row(uchar *buf)
if (curr_offset >= end_offset) if (curr_offset >= end_offset)
goto err; goto err;
curr_char= file_buff->get_value(curr_offset); curr_char= file_buff->get_value(curr_offset);
/* Handle the case where the first character is a quote */
if (curr_char == '"') if (curr_char == '"')
{ {
curr_offset++; // Incrementpast the first quote /* Increment past the first quote */
curr_offset++;
for(; curr_offset < end_offset; curr_offset++) /* Loop through the row to extract the values for the current field */
for ( ; curr_offset < end_offset; curr_offset++)
{ {
curr_char= file_buff->get_value(curr_offset); curr_char= file_buff->get_value(curr_offset);
// Need to convert line feeds! /* check for end of the current field */
if (curr_char == '"' && if (curr_char == '"' &&
(curr_offset == end_offset - 1 || (curr_offset == end_offset - 1 ||
file_buff->get_value(curr_offset + 1) == ',')) file_buff->get_value(curr_offset + 1) == ','))
{ {
curr_offset+= 2; // Move past the , and the " /* Move past the , and the " */
curr_offset+= 2;
break; break;
} }
if (curr_char == '\\' && curr_offset != (end_offset - 1)) if (curr_char == '\\' && curr_offset != (end_offset - 1))
...@@ -702,7 +733,7 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -702,7 +733,7 @@ int ha_tina::find_current_row(uchar *buf)
else // ordinary symbol else // ordinary symbol
{ {
/* /*
We are at final symbol and no last quote was found => If we are at final symbol and no last quote was found =>
we are working with a damaged file. we are working with a damaged file.
*/ */
if (curr_offset == end_offset - 1) if (curr_offset == end_offset - 1)
...@@ -713,15 +744,41 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -713,15 +744,41 @@ int ha_tina::find_current_row(uchar *buf)
} }
else else
{ {
for(; curr_offset < end_offset; curr_offset++) for ( ; curr_offset < end_offset; curr_offset++)
{ {
curr_char= file_buff->get_value(curr_offset); curr_char= file_buff->get_value(curr_offset);
/* Move past the ,*/
if (curr_char == ',') if (curr_char == ',')
{ {
curr_offset++; // Skip the , curr_offset++;
break; break;
} }
buffer.append(curr_char); if (curr_char == '\\' && curr_offset != (end_offset - 1))
{
curr_offset++;
curr_char= file_buff->get_value(curr_offset);
if (curr_char == 'r')
buffer.append('\r');
else if (curr_char == 'n' )
buffer.append('\n');
else if (curr_char == '\\' || curr_char == '"')
buffer.append(curr_char);
else /* This could only happed with an externally created file */
{
buffer.append('\\');
buffer.append(curr_char);
}
}
else
{
/*
We are at the final symbol and a quote was found for the
unquoted field => We are working with a damaged field.
*/
if (curr_offset == end_offset - 1 && curr_char == '"')
goto err;
buffer.append(curr_char);
}
} }
} }
......
...@@ -26,7 +26,8 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c ...@@ -26,7 +26,8 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c
mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c
mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c
mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c
rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c) rt_split.c sort.c sp_key.c ft_eval.h mi_extrafunc.h myisamdef.h
rt_index.h mi_rkey.c)
MYSQL_STORAGE_ENGINE(MYISAM) MYSQL_STORAGE_ENGINE(MYISAM)
......
...@@ -50,7 +50,7 @@ myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ ...@@ -50,7 +50,7 @@ myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \ noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \
fulltext.h ftdefs.h ft_test1.h ft_eval.h \ fulltext.h ftdefs.h ft_test1.h ft_eval.h \
ha_myisam.h ha_myisam.h mi_extrafunc.h
mi_test1_DEPENDENCIES= $(LIBRARIES) mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
......
...@@ -539,6 +539,45 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...) ...@@ -539,6 +539,45 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
va_end(args); va_end(args);
} }
/**
Report list of threads (and queries) accessing a table, thread_id of a
thread that detected corruption, ource file name and line number where
this corruption was detected, optional extra information (string).
This function is intended to be used when table corruption is detected.
@param[in] file MI_INFO object.
@param[in] message Optional error message.
@param[in] sfile Name of source file.
@param[in] sline Line number in source file.
@return void
*/
void _mi_report_crashed(MI_INFO *file, const char *message,
const char *sfile, uint sline)
{
THD *cur_thd;
LIST *element;
char buf[1024];
pthread_mutex_lock(&file->s->intern_lock);
if ((cur_thd= (THD*) file->in_use.data))
sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
sfile, sline);
else
sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline);
if (message)
sql_print_error("%s", message);
for (element= file->s->in_use; element; element= list_rest(element))
{
THD *thd= (THD*) element->data;
sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0)
: "Unknown thread accessing table");
}
pthread_mutex_unlock(&file->s->intern_lock);
}
} }
...@@ -1703,6 +1742,7 @@ int ha_myisam::delete_table(const char *name) ...@@ -1703,6 +1742,7 @@ int ha_myisam::delete_table(const char *name)
int ha_myisam::external_lock(THD *thd, int lock_type) int ha_myisam::external_lock(THD *thd, int lock_type)
{ {
file->in_use.data= thd;
return mi_lock_database(file, !table->s->tmp_table ? return mi_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ? lock_type : ((lock_type == F_UNLCK) ?
F_UNLCK : F_EXTRA_LCK)); F_UNLCK : F_EXTRA_LCK));
......
/* Copyright (C) 2000-2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
void _mi_report_crashed(MI_INFO *file __attribute__((unused)),
const char *message __attribute__((unused)),
const char *sfile __attribute__((unused)),
uint sline __attribute__((unused)))
{
}
...@@ -45,6 +45,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ...@@ -45,6 +45,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
++share->w_locks; ++share->w_locks;
++share->tot_locks; ++share->tot_locks;
info->lock_type= lock_type; info->lock_type= lock_type;
info->s->in_use= list_add(info->s->in_use, &info->in_use);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -136,6 +137,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ...@@ -136,6 +137,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
} }
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
info->lock_type= F_UNLCK; info->lock_type= F_UNLCK;
info->s->in_use= list_delete(info->s->in_use, &info->in_use);
break; break;
case F_RDLCK: case F_RDLCK:
if (info->lock_type == F_WRLCK) if (info->lock_type == F_WRLCK)
...@@ -182,6 +184,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ...@@ -182,6 +184,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->r_locks++; share->r_locks++;
share->tot_locks++; share->tot_locks++;
info->lock_type=lock_type; info->lock_type=lock_type;
info->s->in_use= list_add(info->s->in_use, &info->in_use);
break; break;
case F_WRLCK: case F_WRLCK:
if (info->lock_type == F_RDLCK) if (info->lock_type == F_RDLCK)
...@@ -231,6 +234,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ...@@ -231,6 +234,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
info->invalidator=info->s->invalidator; info->invalidator=info->s->invalidator;
share->w_locks++; share->w_locks++;
share->tot_locks++; share->tot_locks++;
info->s->in_use= list_add(info->s->in_use, &info->in_use);
break; break;
default: default:
break; /* Impossible */ break; /* Impossible */
......
...@@ -679,3 +679,5 @@ static void usage() ...@@ -679,3 +679,5 @@ static void usage()
my_print_help(my_long_options); my_print_help(my_long_options);
my_print_variables(my_long_options); my_print_variables(my_long_options);
} }
#include "mi_extrafunc.h"
...@@ -1055,3 +1055,5 @@ static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff) ...@@ -1055,3 +1055,5 @@ static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff)
} }
return; return;
} }
#include "mi_extrafunc.h"
...@@ -488,6 +488,8 @@ int test_update(MI_INFO *file,int id,int lock_type) ...@@ -488,6 +488,8 @@ int test_update(MI_INFO *file,int id,int lock_type)
return 0; return 0;
} }
#include "mi_extrafunc.h"
#else /* __NETWARE__ */ #else /* __NETWARE__ */
#include <stdio.h> #include <stdio.h>
......
...@@ -274,3 +274,5 @@ static void complain(int val) /* Kinda assert :-) */ ...@@ -274,3 +274,5 @@ static void complain(int val) /* Kinda assert :-) */
exit(1); exit(1);
} }
} }
#include "mi_extrafunc.h"
...@@ -1815,3 +1815,5 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...) ...@@ -1815,3 +1815,5 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
va_end(args); va_end(args);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#include "mi_extrafunc.h"
...@@ -166,6 +166,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */ ...@@ -166,6 +166,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
MI_COLUMNDEF *rec; /* Pointer to field information */ MI_COLUMNDEF *rec; /* Pointer to field information */
MI_PACK pack; /* Data about packed records */ MI_PACK pack; /* Data about packed records */
MI_BLOB *blobs; /* Pointer to blobs */ MI_BLOB *blobs; /* Pointer to blobs */
LIST *in_use; /* List of threads using this table */
char *unique_file_name; /* realpath() of index file */ char *unique_file_name; /* realpath() of index file */
char *data_file_name, /* Resolved path names from symlinks */ char *data_file_name, /* Resolved path names from symlinks */
*index_file_name; *index_file_name;
...@@ -243,6 +244,7 @@ struct st_myisam_info { ...@@ -243,6 +244,7 @@ struct st_myisam_info {
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */ DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */ MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */ MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
LIST in_use; /* Thread using this table */
char *filename; /* parameter to open filename */ char *filename; /* parameter to open filename */
uchar *buff, /* Temp area for key */ uchar *buff, /* Temp area for key */
*lastkey,*lastkey2; /* Last used search key */ *lastkey,*lastkey2; /* Last used search key */
...@@ -386,8 +388,10 @@ typedef struct st_mi_sort_param ...@@ -386,8 +388,10 @@ typedef struct st_mi_sort_param
#define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\ #define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
mi_int2store(x,boh); } mi_int2store(x,boh); }
#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
#define mi_report_crashed(A, B) _mi_report_crashed((A), (B), __FILE__, __LINE__)
#define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \ #define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
DBUG_PRINT("error", ("Marked table crashed")); \ DBUG_PRINT("error", ("Marked table crashed")); \
mi_report_crashed((x), 0); \
}while(0) }while(0)
#define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \ #define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \ STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
...@@ -765,6 +769,8 @@ int mi_open_keyfile(MYISAM_SHARE *share); ...@@ -765,6 +769,8 @@ int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share);
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
void mi_remap_file(MI_INFO *info, my_off_t size); void mi_remap_file(MI_INFO *info, my_off_t size);
void _mi_report_crashed(MI_INFO *file, const char *message,
const char *sfile, uint sline);
/* Functions needed by mi_check */ /* Functions needed by mi_check */
volatile int *killed_ptr(MI_CHECK *param); volatile int *killed_ptr(MI_CHECK *param);
......
...@@ -845,3 +845,5 @@ static my_bool cmp_filename(struct file_info *file_info, char * name) ...@@ -845,3 +845,5 @@ static my_bool cmp_filename(struct file_info *file_info, char * name)
return 1; return 1;
return strcmp(file_info->name,name) ? 1 : 0; return strcmp(file_info->name,name) ? 1 : 0;
} }
#include "mi_extrafunc.h"
...@@ -3245,4 +3245,4 @@ static int fakecmp(my_off_t **count1, my_off_t **count2) ...@@ -3245,4 +3245,4 @@ static int fakecmp(my_off_t **count1, my_off_t **count2)
} }
#endif #endif
#include "mi_extrafunc.h"
...@@ -468,3 +468,5 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) ...@@ -468,3 +468,5 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
exit(0); exit(0);
} }
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
#include "mi_extrafunc.h"
...@@ -562,3 +562,4 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) ...@@ -562,3 +562,4 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
#include "mi_extrafunc.h"
...@@ -1009,7 +1009,10 @@ int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) ...@@ -1009,7 +1009,10 @@ int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size)
int ha_myisammrg::external_lock(THD *thd, int lock_type) int ha_myisammrg::external_lock(THD *thd, int lock_type)
{ {
MYRG_TABLE *tmp;
DBUG_ASSERT(this->file->children_attached); DBUG_ASSERT(this->file->children_attached);
for (tmp= file->open_tables; tmp != file->end_table; tmp++)
tmp->table->in_use.data= thd;
return myrg_lock_database(file,lock_type); return myrg_lock_database(file,lock_type);
} }
......
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