diff options
author | unknown <msvensson@neptunus.(none)> | 2005-06-21 14:24:13 +0200 |
---|---|---|
committer | unknown <msvensson@neptunus.(none)> | 2005-06-21 14:24:13 +0200 |
commit | 2af65b1d712834884e0865c5b2e45cfa22ef36c5 (patch) | |
tree | a8d211fb6cdf815f6c61ca67e2a34afe7cafa94e | |
parent | 06b1e941090c9ec1d7f54d388cd618e529bf99eb (diff) | |
parent | c2a84d5fd2e3d86ab5dd75b13d6dac7a8a06256f (diff) | |
download | mariadb-git-2af65b1d712834884e0865c5b2e45cfa22ef36c5.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into neptunus.(none):/home/msvensson/mysql/mysql-4.1
client/mysqltest.c:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
-rw-r--r-- | client/mysqldump.c | 156 | ||||
-rw-r--r-- | client/mysqltest.c | 35 | ||||
-rw-r--r-- | mysql-test/mysql-test-run.sh | 3 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 87 | ||||
-rw-r--r-- | mysql-test/r/ndb_autodiscover.result | 20 | ||||
-rw-r--r-- | mysql-test/t/mysqldump.test | 93 | ||||
-rw-r--r-- | mysql-test/t/ndb_autodiscover.test | 21 | ||||
-rw-r--r-- | ndb/test/ndbapi/create_tab.cpp | 2 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 25 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 3 | ||||
-rw-r--r-- | sql/handler.cc | 95 | ||||
-rw-r--r-- | sql/handler.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 16 | ||||
-rw-r--r-- | sql/sql_table.cc | 18 |
14 files changed, 437 insertions, 142 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 7b18b1d92da..207235983da 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -57,6 +57,7 @@ #define EX_CONSCHECK 3 #define EX_EOM 4 #define EX_EOF 5 /* ferror for output file was got */ +#define EX_ILLEGAL_TABLE 6 /* index into 'show fields from table' */ @@ -140,14 +141,6 @@ const char *compatible_mode_names[]= TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, "", compatible_mode_names, NULL}; -#define TABLE_RULE_HASH_SIZE 16 - -typedef struct st_table_rule_ent -{ - char* key; /* dbname.tablename */ - uint key_len; -} TABLE_RULE_ENT; - HASH ignore_table; static struct my_option my_long_options[] = @@ -538,29 +531,21 @@ static void write_footer(FILE *sql_file) } /* write_footer */ -static void free_table_ent(TABLE_RULE_ENT* e) -{ - my_free((gptr) e, MYF(0)); -} - - -static byte* get_table_key(TABLE_RULE_ENT* e, uint* len, - my_bool not_used __attribute__((unused))) +byte* get_table_key(const char *entry, uint *length, + my_bool not_used __attribute__((unused))) { - *len= e->key_len; - return (byte*)e->key; + *length= strlen(entry); + return (byte*) entry; } void init_table_rule_hash(HASH* h) { - if(hash_init(h, charset_info, TABLE_RULE_HASH_SIZE, 0, 0, - (hash_get_key) get_table_key, - (hash_free_key) free_table_ent, 0)) + if(hash_init(h, charset_info, 16, 0, 0, + (hash_get_key) get_table_key, 0, 0)) exit(EX_EOM); } - static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) @@ -633,25 +618,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case (int) OPT_IGNORE_TABLE: { - uint len= (uint)strlen(argument); - TABLE_RULE_ENT* e; if (!strchr(argument, '.')) { fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n"); exit(1); } - /* len is always > 0 because we know the there exists a '.' */ - e= (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT) + len, MYF(MY_WME)); - if (!e) - exit(EX_EOM); - e->key= (char*)e + sizeof(TABLE_RULE_ENT); - e->key_len= len; - memcpy(e->key, argument, len); - if (!hash_inited(&ignore_table)) init_table_rule_hash(&ignore_table); - if(my_hash_insert(&ignore_table, (byte*)e)) + if (my_hash_insert(&ignore_table, (byte*)my_strdup(argument, MYF(0)))) exit(EX_EOM); break; } @@ -955,7 +930,28 @@ static char *quote_name(const char *name, char *buff, my_bool force) return buff; } /* quote_name */ +/* + Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>" + SYNOPSIS + quote_for_like + name - name of the table + buff - quoted name of the table + + DESCRIPTION + Quote \, _, ' and % characters + + Note: Because MySQL uses the C escape syntax in strings + (for example, '\n' to represent newline), you must double + any '\' that you use in your LIKE strings. For example, to + search for '\n', specify it as '\\n'. To search for '\', specify + it as '\\\\' (the backslashes are stripped once by the parser + and another time when the pattern match is done, leaving a + single backslash to be matched). + + Example: "t\1" => "t\\\\1" + +*/ static char *quote_for_like(const char *name, char *buff) { @@ -963,7 +959,13 @@ static char *quote_for_like(const char *name, char *buff) *to++= '\''; while (*name) { - if (*name == '\'' || *name == '_' || *name == '\\' || *name == '%') + if (*name == '\\') + { + *to++='\\'; + *to++='\\'; + *to++='\\'; + } + else if (*name == '\'' || *name == '_' || *name == '%') *to++= '\\'; *to++= *name++; } @@ -1114,6 +1116,7 @@ static uint getTableStructure(char *table, char* db) FILE *sql_file = md_result_file; int len; DBUG_ENTER("getTableStructure"); + DBUG_PRINT("enter", ("db: %s, table: %s", db, table)); if (!insert_pat_inited) { @@ -2165,6 +2168,7 @@ static int get_actual_table_name(const char *old_table_name, char query[50 + 2*NAME_LEN]; char show_name_buff[FN_REFLEN]; DBUG_ENTER("get_actual_table_name"); + DBUG_PRINT("enter", ("old_table_name: %s", old_table_name)); /* Check memory for quote_for_like() */ DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff)); @@ -2186,36 +2190,72 @@ static int get_actual_table_name(const char *old_table_name, row= mysql_fetch_row( tableRes ); strmake(new_table_name, row[0], buf_size-1); retval = 0; + DBUG_PRINT("info", ("new_table_name: %s", new_table_name)); } mysql_free_result(tableRes); } - return retval; + DBUG_PRINT("exit", ("retval: %d", retval)); + DBUG_RETURN(retval); } static int dump_selected_tables(char *db, char **table_names, int tables) { - uint numrows; + uint numrows, i; char table_buff[NAME_LEN*+3]; + char new_table_name[NAME_LEN]; + DYNAMIC_STRING lock_tables_query; + HASH dump_tables; + + DBUG_ENTER("dump_selected_tables"); if (init_dumping(db)) return 1; - if (lock_tables) + + /* Init hash table for storing the actual name of tables to dump */ + if (hash_init(&dump_tables, charset_info, 16, 0, 0, + (hash_get_key) get_table_key, 0, 0)) + exit(EX_EOM); + + init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024); + for (; tables > 0 ; tables-- , table_names++) { - DYNAMIC_STRING query; - int i; - init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); - for (i=0 ; i < tables ; i++) + /* the table name passed on commandline may be wrong case */ + if (!get_actual_table_name( *table_names, + new_table_name, sizeof(new_table_name) )) { - dynstr_append(&query, quote_name(table_names[i], table_buff, 1)); - dynstr_append(&query, " READ /*!32311 LOCAL */,"); + /* Add found table name to lock_tables_query */ + if (lock_tables) + { + dynstr_append(&lock_tables_query, + quote_name(new_table_name, table_buff, 1)); + dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,"); + } + + /* Add found table name to dump_tables list */ + if (my_hash_insert(&dump_tables, + (byte*)my_strdup(new_table_name, MYF(0)))) + exit(EX_EOM); + } - if (mysql_real_query(sock, query.str, query.length-1)) + else + { + my_printf_error(0,"Couldn't find table: \"%s\"\n", MYF(0), + *table_names); + safe_exit(EX_ILLEGAL_TABLE); + /* We shall countinue here, if --force was given */ + } + } + + if (lock_tables) + { + if (mysql_real_query(sock, lock_tables_query.str, + lock_tables_query.length-1)) DBerror(sock, "when doing LOCK TABLES"); /* We shall countinue here, if --force was given */ - dynstr_free(&query); } + dynstr_free(&lock_tables_query); if (flush_logs) { if (mysql_refresh(sock, REFRESH_LOG)) @@ -2224,20 +2264,20 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } if (opt_xml) print_xml_tag1(md_result_file, "", "database name=", db, "\n"); - for (; tables > 0 ; tables-- , table_names++) + + /* Dump each selected table */ + const char *table_name; + for (i= 0 ; i < dump_tables.records ; i++) { - char new_table_name[NAME_LEN]; - - /* the table name passed on commandline may be wrong case */ - if (!get_actual_table_name( *table_names, new_table_name, sizeof(new_table_name) )) - { - numrows = getTableStructure(new_table_name, db); - if (!dFlag && numrows > 0) - dumpTable(numrows, new_table_name); - } - my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); - order_by= 0; + table_name= hash_element(&dump_tables, i); + DBUG_PRINT("info",("Dumping table %s", table_name)); + numrows = getTableStructure(table_name, db); + if (!dFlag && numrows > 0) + dumpTable(numrows, table_name); } + hash_free(&dump_tables); + my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); + order_by= 0; if (opt_xml) { fputs("</database>\n", md_result_file); @@ -2245,7 +2285,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } if (lock_tables) mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); - return 0; + DBUG_RETURN(0); } /* dump_selected_tables */ diff --git a/client/mysqltest.c b/client/mysqltest.c index 131616b6f71..77736fc1fcc 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -787,7 +787,7 @@ int var_set(const char *var_name, const char *var_name_end, } else v = var_reg + digit; - return eval_expr(v, var_val, (const char**)&var_val_end); + DBUG_RETURN(eval_expr(v, var_val, (const char**)&var_val_end)); } @@ -961,9 +961,38 @@ static void do_exec(struct st_query* q) replace_dynstr_append_mem(ds, buf, strlen(buf)); } error= pclose(res_file); - if (error != 0) - die("command \"%s\" failed", cmd); + { + uint status= WEXITSTATUS(error); + if(q->abort_on_error) + die("At line %u: command \"%s\" failed", start_lineno, cmd); + else + { + DBUG_PRINT("info", + ("error: %d, status: %d", error, status)); + bool ok= 0; + uint i; + for (i=0 ; (uint) i < q->expected_errors ; i++) + { + DBUG_PRINT("info", ("expected error: %d", q->expected_errno[i].code.errnum)); + if ((q->expected_errno[i].type == ERR_ERRNO) && + (q->expected_errno[i].code.errnum == status)) + ok= 1; + verbose_msg("At line %u: command \"%s\" failed with expected error: %d", + start_lineno, cmd, status); + } + if (!ok) + die("At line: %u: command \"%s\" failed with wrong error: %d", + start_lineno, cmd, status); + } + } + else if (q->expected_errno[0].type == ERR_ERRNO && + q->expected_errno[0].code.errnum != 0) + { + /* Error code we wanted was != 0, i.e. not an expected success */ + die("At line: %u: command \"%s\" succeeded - should have failed with errno %d...", + start_lineno, cmd, q->expected_errno[0].code.errnum); + } if (!disable_result_log) { diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 7540a76317e..537840c1d33 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -689,6 +689,9 @@ MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root --soc if [ "x$USE_EMBEDDED_SERVER" = "x1" ]; then MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST -A --language=$LANGUAGE -A --datadir=$SLAVE_MYDDIR -A --character-sets-dir=$CHARSETSDIR" fi +# Save path and name of mysqldump +MYSQL_DUMP_DIR="$MYSQL_DUMP" +export MYSQL_DUMP_DIR MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT" MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR $EXTRA_MYSQLBINLOG_OPT" MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose" diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 845b0d1da45..50399c91ec9 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1349,3 +1349,90 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +CREATE DATABASE mysqldump_test_db; +USE mysqldump_test_db; +CREATE TABLE t1 ( a INT ); +CREATE TABLE t2 ( a INT ); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1), (2); + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +DROP TABLE t1, t2; +DROP DATABASE mysqldump_test_db; +create database mysqldump_test_db; +use mysqldump_test_db; +create table t1(a varchar(30) primary key, b int not null); +create table t2(a varchar(30) primary key, b int not null); +create table t3(a varchar(30) primary key, b int not null); +test_sequence +------ Testing with illegal table names ------ +MYSQL_DUMP_DIR: Couldn't find table: "\d-2-1.sql" + +MYSQL_DUMP_DIR: Couldn't find table: "\t1" + +MYSQL_DUMP_DIR: Couldn't find table: "\t1" + +MYSQL_DUMP_DIR: Couldn't find table: "\\t1" + +MYSQL_DUMP_DIR: Couldn't find table: "t\1" + +MYSQL_DUMP_DIR: Couldn't find table: "t\1" + +MYSQL_DUMP_DIR: Couldn't find table: "t/1" + +test_sequence +------ Testing with illegal database names ------ +MYSQL_DUMP_DIR: Got error: 1049: Unknown database 'mysqldump_test_d' when selecting the database +MYSQL_DUMP_DIR: Got error: 1102: Incorrect database name 'mysqld\ump_test_db' when selecting the database +drop table t1, t2, t3; +drop database mysqldump_test_db; diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index b7afb5918a4..b278d6eb048 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -93,7 +93,7 @@ name char(20), a int, b float, c char(24) ERROR 42S01: Table 't3' already exists show status like 'handler_discover%'; Variable_name Value -Handler_discover 1 +Handler_discover 0 create table IF NOT EXISTS t3( id int not null primary key, id2 int not null, @@ -101,7 +101,7 @@ name char(20) ) engine=ndb; show status like 'handler_discover%'; Variable_name Value -Handler_discover 2 +Handler_discover 0 SHOW CREATE TABLE t3; Table Create Table t3 CREATE TABLE `t3` ( @@ -114,7 +114,7 @@ id name 1 Explorer show status like 'handler_discover%'; Variable_name Value -Handler_discover 2 +Handler_discover 1 drop table t3; flush status; create table t7( @@ -358,6 +358,20 @@ Database mysql test use test; +CREATE TABLE sys.SYSTAB_0 (a int); +ERROR 42S01: Table 'SYSTAB_0' already exists +select * from sys.SYSTAB_0; +ERROR HY000: Failed to open 'SYSTAB_0', error while unpacking from engine +CREATE TABLE IF NOT EXISTS sys.SYSTAB_0 (a int); +show warnings; +Level Code Message +select * from sys.SYSTAB_0; +ERROR HY000: Failed to open 'SYSTAB_0', error while unpacking from engine +drop table sys.SYSTAB_0; +ERROR 42S02: Unknown table 'SYSTAB_0' +drop table IF EXISTS sys.SYSTAB_0; +Warnings: +Note 1051 Unknown table 'SYSTAB_0' CREATE TABLE t9 ( a int NOT NULL PRIMARY KEY, b int diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 9f3b412b814..349b1e96239 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -543,3 +543,96 @@ CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); --exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test DROP TABLE t1; + +# +# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data +# + +CREATE DATABASE mysqldump_test_db; +USE mysqldump_test_db; +CREATE TABLE t1 ( a INT ); +CREATE TABLE t2 ( a INT ); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1), (2); +--exec $MYSQL_DUMP --skip-comments --no-data mysqldump_test_db +--exec $MYSQL_DUMP --skip-comments --no-data mysqldump_test_db t1 t2 +DROP TABLE t1, t2; +DROP DATABASE mysqldump_test_db; + +# +# Testing with tables and databases that don't exists +# or contains illegal characters +# (Bug #9358 mysqldump crashes if tablename starts with \) +# +create database mysqldump_test_db; +use mysqldump_test_db; +create table t1(a varchar(30) primary key, b int not null); +create table t2(a varchar(30) primary key, b int not null); +create table t3(a varchar(30) primary key, b int not null); + +--disable_query_log +select '------ Testing with illegal table names ------' as test_sequence ; +--enable_query_log +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\d-2-1.sql" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\t1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\t1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\\\t1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t\1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t\\1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t/1" 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_1" + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T%1" + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T'1" + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_1" + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 6 +--exec $MYSQL_DUMP --compact --skip-comments "mysqldump_test_db" "T_" + +--disable_query_log +select '------ Testing with illegal database names ------' as test_sequence ; +--enable_query_log +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 2 +--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_d 2>&1 + +--replace_result $MYSQL_DUMP_DIR MYSQL_DUMP_DIR +--error 2 +--exec $MYSQL_DUMP --compact --skip-comments "mysqld\ump_test_db" 2>&1 + +drop table t1, t2, t3; +drop database mysqldump_test_db; + + diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index bd73a36fcab..49ed8c894fe 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -453,6 +453,27 @@ drop database test2; show databases; use test; +##################################################### +# Test that it's not possible to create tables +# with same name as NDB internal tables +# This will also test that it's not possible to create +# a table with tha same name as a table that can't be +# discovered( for example a table created via NDBAPI) + +--error 1050 +CREATE TABLE sys.SYSTAB_0 (a int); +--error 1105 +select * from sys.SYSTAB_0; + +CREATE TABLE IF NOT EXISTS sys.SYSTAB_0 (a int); +show warnings; +--error 1105 +select * from sys.SYSTAB_0; + +--error 1051 +drop table sys.SYSTAB_0; +drop table IF EXISTS sys.SYSTAB_0; + ###################################################### # Note! This should always be the last step in this # file, the table t9 will be used and dropped diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp index f3f18982ed0..283c83d30e0 100644 --- a/ndb/test/ndbapi/create_tab.cpp +++ b/ndb/test/ndbapi/create_tab.cpp @@ -77,8 +77,8 @@ int main(int argc, const char** argv){ */ // Connect to Ndb + Ndb::setConnectString(_connectstr); Ndb MyNdb( "TEST_DB" ); - MyNdb.setConnectString(_connectstr); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 88b7ff4dcb8..48d0a8127c9 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -4299,7 +4299,7 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name, { const NdbError err= dict->getNdbError(); if (err.code == 709) - DBUG_RETURN(1); + DBUG_RETURN(-1); ERR_RETURN(err); } DBUG_PRINT("info", ("Found table %s", tab->getName())); @@ -4307,13 +4307,15 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name, len= tab->getFrmLength(); if (len == 0 || tab->getFrmData() == NULL) { - DBUG_PRINT("No frm data found", - ("Table is probably created via NdbApi")); - DBUG_RETURN(2); + DBUG_PRINT("error", ("No frm data found.")); + DBUG_RETURN(1); } if (unpackfrm(&data, &len, tab->getFrmData())) - DBUG_RETURN(3); + { + DBUG_PRINT("error", ("Could not unpack table")); + DBUG_RETURN(1); + } *frmlen= len; *frmblob= data; @@ -4326,13 +4328,13 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name, */ -int ndbcluster_table_exists(THD* thd, const char *db, const char *name) +int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name) { uint len; const void* data; const NDBTAB* tab; Ndb* ndb; - DBUG_ENTER("ndbcluster_table_exists"); + DBUG_ENTER("ndbcluster_table_exists_in_engine"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); if (!(ndb= check_ndb_in_thd(thd))) @@ -4511,7 +4513,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, DBUG_PRINT("info", ("%s existed on disk", name)); // The .ndb file exists on disk, but it's not in list of tables in ndb // Verify that handler agrees table is gone. - if (ndbcluster_table_exists(thd, db, file_name) == 0) + if (ndbcluster_table_exists_in_engine(thd, db, file_name) == 0) { DBUG_PRINT("info", ("NDB says %s does not exists", file_name)); it.remove(); @@ -4562,7 +4564,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, while ((file_name=it2++)) { DBUG_PRINT("info", ("Table %s need discovery", name)); - if (ha_create_table_from_engine(thd, db, file_name, TRUE) == 0) + if (ha_create_table_from_engine(thd, db, file_name) == 0) files->push_back(thd->strdup(file_name)); } @@ -4638,11 +4640,8 @@ bool ndbcluster_init() pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST); ndbcluster_inited= 1; -#ifdef USE_DISCOVER_ON_STARTUP - if (ndb_discover_tables() != 0) - goto ndbcluster_init_error; -#endif DBUG_RETURN(FALSE); + ndbcluster_init_error: ndbcluster_end(); DBUG_RETURN(TRUE); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 439b4855147..5c1d121a157 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -275,7 +275,8 @@ int ndbcluster_discover(THD* thd, const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ndbcluster_find_files(THD *thd,const char *db,const char *path, const char *wild, bool dir, List<char> *files); -int ndbcluster_table_exists(THD* thd, const char *db, const char *name); +int ndbcluster_table_exists_in_engine(THD* thd, + const char *db, const char *name); int ndbcluster_drop_database(const char* path); void ndbcluster_print_error(int error, const NdbOperation *error_op); diff --git a/sql/handler.cc b/sql/handler.cc index f14564b6629..dacfc7d9ac5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1336,21 +1336,19 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, } /* - Try to discover table from engine and + Try to discover table from engine and if found, write the frm file to disk. - + RETURN VALUES: - 0 : Table existed in engine and created - on disk if so requested - 1 : Table does not exist - >1 : error + -1 : Table did not exists + 0 : Table created ok + > 0 : Error, table existed but could not be created */ -int ha_create_table_from_engine(THD* thd, - const char *db, - const char *name, - bool create_if_found) +int ha_create_table_from_engine(THD* thd, + const char *db, + const char *name) { int error; const void *frmblob; @@ -1359,45 +1357,47 @@ int ha_create_table_from_engine(THD* thd, HA_CREATE_INFO create_info; TABLE table; DBUG_ENTER("ha_create_table_from_engine"); - DBUG_PRINT("enter", ("name '%s'.'%s' create_if_found: %d", - db, name, create_if_found)); + DBUG_PRINT("enter", ("name '%s'.'%s'", + db, name)); bzero((char*) &create_info,sizeof(create_info)); - if ((error= ha_discover(thd, db, name, &frmblob, &frmlen))) - DBUG_RETURN(error); + if(error= ha_discover(thd, db, name, &frmblob, &frmlen)) + { + // Table could not be discovered and thus not created + DBUG_RETURN(error); + } + /* - Table exists in handler - frmblob and frmlen are set + Table exists in handler and could be discovered + frmblob and frmlen are set, write the frm to disk */ - if (create_if_found) + (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS); + // Save the frm file + if (writefrm(path, frmblob, frmlen)) { - (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS); - // Save the frm file - if ((error = writefrm(path, frmblob, frmlen))) - goto err_end; + my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR)); + DBUG_RETURN(2); + } - if (openfrm(path,"",0,(uint) READ_ALL, 0, &table)) - DBUG_RETURN(1); + if (openfrm(path,"",0,(uint) READ_ALL, 0, &table)) + DBUG_RETURN(3); - update_create_info_from_table(&create_info, &table); - create_info.table_options|= HA_CREATE_FROM_ENGINE; + update_create_info_from_table(&create_info, &table); + create_info.table_options|= HA_CREATE_FROM_ENGINE; - if (lower_case_table_names == 2 && - !(table.file->table_flags() & HA_FILE_BASED)) - { - /* Ensure that handler gets name in lower case */ - my_casedn_str(files_charset_info, path); - } - - error=table.file->create(path,&table,&create_info); - VOID(closefrm(&table)); + if (lower_case_table_names == 2 && + !(table.file->table_flags() & HA_FILE_BASED)) + { + /* Ensure that handler gets name in lower case */ + my_casedn_str(files_charset_info, path); } - -err_end: + error=table.file->create(path,&table,&create_info); + VOID(closefrm(&table)); my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR)); - DBUG_RETURN(error); + + DBUG_RETURN(error != 0); } static int NEAR_F delete_file(const char *name,const char *ext,int extflag) @@ -1507,14 +1507,15 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, Try to discover one table from handler(s) RETURN - 0 ok. In this case *frmblob and *frmlen are set - 1 error. frmblob and frmlen may not be set + -1 : Table did not exists + 0 : OK. In this case *frmblob and *frmlen are set + >0 : error. frmblob and frmlen may not be set */ int ha_discover(THD *thd, const char *db, const char *name, const void **frmblob, uint *frmlen) { - int error= 1; // Table does not exist in any handler + int error= -1; // Table does not exist in any handler DBUG_ENTER("ha_discover"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); #ifdef HAVE_NDBCLUSTER_DB @@ -1546,11 +1547,8 @@ ha_find_files(THD *thd,const char *db,const char *path, error= ndbcluster_find_files(thd, db, path, wild, dir, files); #endif DBUG_RETURN(error); - - } -#ifdef NOT_YET_USED /* Ask handler if the table exists in engine @@ -1561,20 +1559,19 @@ ha_find_files(THD *thd,const char *db,const char *path, # Error code */ -int ha_table_exists(THD* thd, const char* db, const char* name) +int ha_table_exists_in_engine(THD* thd, const char* db, const char* name) { - int error= 2; - DBUG_ENTER("ha_table_exists"); + int error= 0; + DBUG_ENTER("ha_table_exists_in_engine"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); #ifdef HAVE_NDBCLUSTER_DB if (have_ndbcluster == SHOW_OPTION_YES) - error= ndbcluster_table_exists(thd, db, name); + error= ndbcluster_table_exists_in_engine(thd, db, name); #endif + DBUG_PRINT("exit", ("error: %d", error)); DBUG_RETURN(error); } -#endif - /* Read first row between two ranges. diff --git a/sql/handler.h b/sql/handler.h index 75e83082d10..efcdee8f56c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -547,8 +547,7 @@ enum db_type ha_checktype(enum db_type database_type); my_bool ha_storage_engine_is_enabled(enum db_type database_type); int ha_create_table(const char *name, HA_CREATE_INFO *create_info, bool update_create_info); -int ha_create_table_from_engine(THD* thd, const char *db, const char *name, - bool create_if_found); +int ha_create_table_from_engine(THD* thd, const char *db, const char *name); int ha_delete_table(enum db_type db_type, const char *path); void ha_drop_database(char* path); int ha_init_key_cache(const char *name, KEY_CACHE *key_cache); @@ -574,6 +573,6 @@ int ha_discover(THD* thd, const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ha_find_files(THD *thd,const char *db,const char *path, const char *wild, bool dir,List<char>* files); -int ha_table_exists(THD* thd, const char* db, const char* name); +int ha_table_exists_in_engine(THD* thd, const char* db, const char* name); TYPELIB *ha_known_exts(void); int ha_start_consistent_snapshot(THD *thd); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e3c0efb83b8..b4c212afb3f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1375,9 +1375,19 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, trying to discover the table at the same time. */ if (discover_retry_count++ != 0) - goto err; - if (ha_create_table_from_engine(thd, db, name, TRUE) != 0) - goto err; + goto err; + if (ha_create_table_from_engine(thd, db, name) > 0) + { + /* Give right error message */ + thd->clear_error(); + DBUG_PRINT("error", ("Dicovery of %s/%s failed", db, name)); + my_printf_error(ER_UNKNOWN_ERROR, + "Failed to open '%-.64s', error while " + "unpacking from engine", + MYF(0), name); + + goto err; + } thd->clear_error(); // Clear error message continue; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e2e6ee23323..d7a07d17761 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -244,15 +244,18 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, /* remove form file and isam files */ build_table_path(path, sizeof(path), db, alias, reg_ext); } - if (drop_temporary || - (access(path,F_OK) && ha_create_table_from_engine(thd,db,alias,TRUE))) + if (drop_temporary || + (access(path,F_OK) && + ha_create_table_from_engine(thd, db, alias))) { + // Table was not found on disk and table can't be created from engine if (if_exists) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), table->real_name); else - error= 1; + error= 1; + } else { @@ -1394,15 +1397,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { bool create_if_not_exists = create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS; - if (!ha_create_table_from_engine(thd, db, table_name, - create_if_not_exists)) + if (ha_table_exists_in_engine(thd, db, table_name)) { - DBUG_PRINT("info", ("Table already existed in handler")); + DBUG_PRINT("info", ("Table with same name already existed in handler")); if (create_if_not_exists) { - create_info->table_existed= 1; // Mark that table existed - error= 0; + create_info->table_existed= 1; // Mark that table existed + error= 0; } else my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); |