diff options
323 files changed, 10062 insertions, 8162 deletions
diff --git a/.bzrignore b/.bzrignore index 13524cf8125..e80b1856a3b 100644 --- a/.bzrignore +++ b/.bzrignore @@ -759,6 +759,7 @@ ndb/tools/ndb_drop_table ndb/tools/ndb_select_all ndb/tools/ndb_select_count ndb/tools/ndb_show_tables +ndb/tools/ndb_test_platform ndb/tools/ndb_waiter pull.log regex/re diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index f09109774f9..84f6b60f4d9 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -156,6 +156,7 @@ nick@mysql.com nick@nick.leippe.com papa@gbichot.local patg@krsna.patg.net +patg@patrick-galbraiths-computer.local paul@central.snake.net paul@ice.local paul@ice.snake.net @@ -203,6 +204,7 @@ tim@bitch.mysql.fi tim@black.box tim@hundin.mysql.fi tim@sand.box +tim@siva.hindu.god tim@threads.polyesthetic.msg tim@white.box tim@work.mysql.com diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 8cad093bc5f..a7d347ba32f 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -288,6 +288,10 @@ unless ($opt_skip_manual) system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 or &abort("Could not update $file.texi in $target_dir/Docs/!"); } + system ("rm -f $target_dir/Docs/Images/Makefile*") == 0 + or &abort("Could not remove Makefiles in $target_dir/Docs/Images/!"); + system ("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images") == 0 + or &abort("Could not copy image files in $target_dir/Docs/Images/!"); } # diff --git a/Docs/Makefile.am b/Docs/Makefile.am index 034cec3b133..681046543bd 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -9,7 +9,7 @@ # If you know how to fix any of this more elegantly please mail # docs@mysql.com -TEXI2HTML_FLAGS = -iso -number +TEXI2HTML_FLAGS = -iso -number -acc DVIPS = dvips MAKEINFO = @MAKEINFO@ TEXINFO_TEX = Support/texinfo.tex @@ -24,6 +24,8 @@ BUILT_SOURCES = $(targets) manual_toc.html include.texi EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \ INSTALL-BINARY reservedwords.texi internals.texi +SUBDIRS = Images + all: $(targets) txt_files txt_files: ../INSTALL-SOURCE ../COPYING ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \ diff --git a/acinclude.m4 b/acinclude.m4 index 671e279a9f3..448bf7a2653 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1614,9 +1614,14 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [ --with-ndb-docs Include the NDB Cluster ndbapi and mgmapi documentation], [ndb_docs="$withval"], [ndb_docs=no]) + AC_ARG_WITH([ndb-port], + [ + --with-ndb-port Port for NDB Cluster management server], + [ndb_port="$withval"], + [ndb_port="default"]) AC_ARG_WITH([ndb-port-base], [ - --with-ndb-port-base Base port for NDB Cluster], + --with-ndb-port-base Base port for NDB Cluster transporters], [ndb_port_base="$withval"], [ndb_port_base="default"]) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 31588d5b013..ff90c77a2e8 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -229,7 +229,7 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, for (;;) { - uint packet_len = my_net_read(net); + ulong packet_len = my_net_read(net); if (packet_len == 0) { if (my_net_write(net, "", 0) || net_flush(net)) @@ -251,7 +251,13 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, return -1; } - if (my_write(file, (byte*) net->read_pos, packet_len,MYF(MY_WME|MY_NABP))) + if (packet_len > UINT_MAX) + { + sql_print_error("Illegal length of packet read from net"); + return -1; + } + if (my_write(file, (byte*) net->read_pos, + (uint) packet_len, MYF(MY_WME|MY_NABP))) return -1; } @@ -850,7 +856,15 @@ could be out of memory"); */ int4store(buf, (uint32)start_position); int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags); - logname_len = (uint) strlen(logname); + + size_s tlen = strlen(logname); + if (tlen > UINT_MAX) + { + fprintf(stderr,"Log name too long\n"); + error= 1; + goto err; + } + logname_len = (uint) tlen; int4store(buf + 6, 0); memcpy(buf + 10, logname, logname_len); if (simple_command(mysql, COM_BINLOG_DUMP, buf, logname_len + 10, 1)) diff --git a/client/mysqldump.c b/client/mysqldump.c index 2defee27c7e..f9cbc8f8789 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -37,7 +37,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.8" +#define DUMP_VERSION "10.9" #include <my_global.h> #include <my_sys.h> @@ -78,8 +78,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0,replace=0, ignore=0,opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0, - opt_alldbs=0,opt_create_db=0,opt_first_slave=0,opt_set_charset, - opt_autocommit=0,opt_master_data,opt_disable_keys=1,opt_xml=0, + opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,opt_set_charset, + opt_autocommit=0,opt_disable_keys=1,opt_xml=0, opt_delete_master_logs=0, tty_password=0, opt_single_transaction=0, opt_comments= 0, opt_compact= 0, opt_hex_blob=0; @@ -93,7 +93,9 @@ static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *err_ptr= 0; static char compatible_mode_normal_str[255]; static ulong opt_compatible_mode= 0; -static uint opt_mysql_port= 0, err_len= 0; +#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 +#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 +static uint opt_mysql_port= 0, err_len= 0, opt_master_data; static my_string opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; @@ -150,6 +152,9 @@ static struct my_option my_long_options[] = {"character-sets-dir", OPT_CHARSETS_DIR, "Directory where character sets are.", (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"comments", 'i', "Write additional information.", + (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, + 1, 0, 0, 0, 0, 0}, {"compatible", OPT_COMPATIBLE, "Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option is ignored with earlier server versions.", (gptr*) &opt_compatible_mode_str, (gptr*) &opt_compatible_mode_str, 0, @@ -185,8 +190,9 @@ static struct my_option my_long_options[] = (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delete-master-logs", OPT_DELETE_MASTER_LOGS, - "Delete logs on master after backup. This automatically enables --first-slave.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + "Delete logs on master after backup. This automatically enables --master-data.", + (gptr*) &opt_delete_master_logs, (gptr*) &opt_delete_master_logs, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"disable-keys", 'K', "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -205,13 +211,18 @@ static struct my_option my_long_options[] = (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...", (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"first-slave", 'x', "Locks all tables across all databases.", - (gptr*) &opt_first_slave, (gptr*) &opt_first_slave, 0, GET_BOOL, NO_ARG, + {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.", + (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"flush-logs", 'F', "Flush logs file in server before starting dump. " - "Note that if you dump many databases at once (using the option " - "--databases= or --all-databases), the logs will be flushed for " - "each database dumped.", + "Note that if you dump many databases at once (using the option " + "--databases= or --all-databases), the logs will be flushed for " + "each database dumped. The exception is when using --lock-all-tables " + "or --master-data: " + "in this case the logs will be flushed only once, corresponding " + "to the moment all tables are locked. So if you want your dump and " + "the log flush to happen at the same exact moment you should use " + "--lock-all-tables or --master-data with --flush-logs", (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Continue even if we get an sql-error.", @@ -219,24 +230,45 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, " + "VARBINARY, BLOB) in hexadecimal format.", + (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (gptr*) ¤t_host, (gptr*) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...", (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"lock-all-tables", 'x', "Locks all tables across all databases. This " + "is achieved by taking a global read lock for the duration of the whole " + "dump. Automatically turns --single-transaction and --lock-tables off.", + (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables, (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"master-data", OPT_MASTER_DATA, - "This causes the master position and filename to be appended to your output. This automatically enables --first-slave.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + "This causes the binary log position and filename to be appended to the " + "output. If equal to 1, will print it as a CHANGE MASTER command; if equal" + " to 2, that command will be prefixed with a comment symbol. " + "This option will turn --lock-all-tables on, unless " + "--single-transaction is specified too (in which case a " + "global read lock is only taken a short time at the beginning of the dump " + "- don't forget to read about --single-transaction below). In all cases " + "any action on logs will happen at the exact moment of the dump." + "Option automatically turns --lock-tables off.", + (gptr*) &opt_master_data, (gptr*) &opt_master_data, 0, + GET_UINT, REQUIRED_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0}, + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + (gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, + GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, + (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + (gptr*) &opt_net_buffer_length, (gptr*) &opt_net_buffer_length, 0, + GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, + MALLOC_OVERHEAD-1024, 1024, 0}, {"no-autocommit", OPT_AUTOCOMMIT, "Wrap tables with autocommit/commit statements.", (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"single-transaction", OPT_TRANSACTION, - "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", - (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}.", (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, @@ -248,13 +280,6 @@ static struct my_option my_long_options[] = {"no-set-names", 'N', "Deprecated. Use --skip-set-charset instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"set-charset", OPT_SET_CHARSET, - "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.", - (gptr*) &opt_set_charset, (gptr*) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1, - 0, 0, 0, 0, 0}, - {"set-variable", 'O', - "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -278,11 +303,31 @@ static struct my_option my_long_options[] = {"result-file", 'r', "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"set-charset", OPT_SET_CHARSET, + "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.", + (gptr*) &opt_set_charset, (gptr*) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1, + 0, 0, 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + /* + Note that the combination --single-transaction --master-data + will give bullet-proof binlog position only if server >=4.1.3. That's the + old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug. + */ + {"single-transaction", OPT_TRANSACTION, + "Creates a consistent snapshot by dumping all tables in a single " + "transaction. Works ONLY for tables stored in storage engines which " + "support multiversioning (currently only InnoDB does); the dump is NOT " + "guaranteed to be consistent for other storage engines. Option " + "automatically turns off --lock-tables.", + (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-opt", OPT_SKIP_OPTIMIZATION, "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -308,19 +353,6 @@ static struct my_option my_long_options[] = (gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", - (gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, - GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, - (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", - (gptr*) &opt_net_buffer_length, (gptr*) &opt_net_buffer_length, 0, - GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, - MALLOC_OVERHEAD-1024, 1024, 0}, - {"comments", 'i', "Write additional information.", - (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, - 1, 0, 0, 0, 0, 0}, - {"hex-blob", OPT_HEXBLOB, "Dump BLOBs in HEX.", - (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, 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} }; @@ -476,14 +508,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { switch (optid) { - case OPT_MASTER_DATA: - opt_master_data=1; - opt_first_slave=1; - break; - case OPT_DELETE_MASTER_LOGS: - opt_delete_master_logs=1; - opt_first_slave=1; - break; case 'p': if (argument) { @@ -531,7 +555,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_OPTIMIZE: extended_insert= opt_drop= opt_lock= quick= create_options= opt_disable_keys= lock_tables= opt_set_charset= 1; - if (opt_single_transaction) lock_tables=0; break; case (int) OPT_SKIP_OPTIMIZATION: extended_insert= opt_drop= opt_lock= quick= create_options= @@ -627,7 +650,19 @@ static int get_options(int *argc, char ***argv) "%s: You must use option --tab with --fields-...\n", my_progname); return(1); } - if (opt_single_transaction) + + /* Ensure consistency of the set of binlog & locking options */ + if (opt_delete_master_logs && !opt_master_data) + opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL; + if (opt_single_transaction && opt_lock_all_tables) + { + fprintf(stderr, "%s: You can't use --single-transaction and " + "--lock-all-tables at the same time.\n", my_progname); + return(1); + } + if (opt_master_data) + opt_lock_all_tables= !opt_single_transaction; + if (opt_single_transaction || opt_lock_all_tables) lock_tables= 0; if (enclosed && opt_enclosed) { @@ -674,6 +709,36 @@ static void DBerror(MYSQL *mysql, const char *when) } /* DBerror */ +/* + Sends a query to server, optionally reads result, prints error message if + some. + + SYNOPSIS + mysql_query_with_error_report() + mysql_con connection to use + res if non zero, result will be put there with mysql_store_result + query query to send to server + + RETURN VALUES + 0 query sending and (if res!=0) result reading went ok + 1 error +*/ + +static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, + const char *query) +{ + if (mysql_query(mysql_con, query) || + (res && !((*res)= mysql_store_result(mysql_con)))) + { + my_printf_error(0, "%s: Couldn't execute '%s': %s (%d)", + MYF(0), my_progname, query, + mysql_error(mysql_con), mysql_errno(mysql_con)); + return 1; + } + return 0; +} + + static void safe_exit(int error) { if (!first_error) @@ -721,12 +786,15 @@ static int dbConnect(char *host, char *user,char *passwd) DBerror(&mysql_connection, "when trying to connect"); return 1; } + /* + As we're going to set SQL_MODE, it would be lost on reconnect, so we + cannot reconnect. + */ + sock->reconnect= 0; sprintf(buff, "/*!40100 SET @@SQL_MODE=\"%s\" */", compatible_mode_normal_str); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, 0, buff)) { - fprintf(stderr, "%s: Can't set the compatible mode %s (error %s)\n", - my_progname, compatible_mode_normal_str, mysql_error(sock)); mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; @@ -965,7 +1033,7 @@ static uint getTableStructure(char *table, char* db) result_table= quote_name(table, table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (!opt_xml && !mysql_query(sock,insert_pat)) + if (!opt_xml && !mysql_query_with_error_report(sock, 0, insert_pat)) { /* using SHOW CREATE statement */ if (!tFlag) @@ -975,10 +1043,8 @@ static uint getTableStructure(char *table, char* db) MYSQL_FIELD *field; sprintf(buff,"show create table %s", result_table); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, 0, buff)) { - fprintf(stderr, "%s: Can't get CREATE TABLE for table %s (%s)\n", - my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1023,10 +1089,8 @@ static uint getTableStructure(char *table, char* db) mysql_free_result(tableRes); } sprintf(insert_pat,"show fields from %s", result_table); - if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &tableRes, insert_pat)) { - fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", - my_progname, result_table, mysql_error(sock)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -1066,10 +1130,8 @@ static uint getTableStructure(char *table, char* db) my_progname, mysql_error(sock)); sprintf(insert_pat,"show fields from %s", result_table); - if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &tableRes, insert_pat)) { - fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", - my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1163,7 +1225,7 @@ static uint getTableStructure(char *table, char* db) char buff[20+FN_REFLEN]; uint keynr,primary_key; sprintf(buff,"show keys from %s", result_table); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &tableRes, buff)) { if (mysql_errno(sock) == ER_WRONG_OBJECT) { @@ -1179,7 +1241,6 @@ static uint getTableStructure(char *table, char* db) DBUG_RETURN(0); } - tableRes=mysql_store_result(sock); /* Find first which key is primary key */ keynr=0; primary_key=INT_MAX; @@ -1243,7 +1304,7 @@ static uint getTableStructure(char *table, char* db) char show_name_buff[FN_REFLEN]; sprintf(buff,"show table status like %s", quote_for_like(table, show_name_buff)); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &tableRes, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) { /* If old MySQL version */ @@ -1253,8 +1314,7 @@ static uint getTableStructure(char *table, char* db) result_table,mysql_error(sock)); } } - else if (!(tableRes=mysql_store_result(sock)) || - !(row=mysql_fetch_row(tableRes))) + else if (!(row=mysql_fetch_row(tableRes))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", @@ -1459,22 +1519,14 @@ static void dumpTable(uint numFields, char *table) fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query(sock, query)) - { + if (mysql_query_with_error_report(sock, 0, query)) DBerror(sock, "when retrieving data from server"); - error= EX_CONSCHECK; - goto err; - } if (quick) res=mysql_use_result(sock); else res=mysql_store_result(sock); if (!res) - { DBerror(sock, "when retrieving data from server"); - error= EX_CONSCHECK; - goto err; - } if (verbose) fprintf(stderr, "-- Retrieving rows...\n"); if (mysql_num_fields(res) != numFields) @@ -1648,16 +1700,12 @@ static void dumpTable(uint numFields, char *table) fputs("</field>\n", md_result_file); } else if (opt_hex_blob && is_blob) - { /* sakaik got this idea. */ - ulong counter; - char xx[4]; - unsigned char *ptr= row[i]; + { + /* sakaik got the idea to to provide blob's in hex notation. */ + unsigned char *ptr= row[i], *end= ptr+ lengths[i]; fputs("0x", md_result_file); - for (counter = 0; counter < lengths[i]; counter++) - { - sprintf(xx, "%02X", ptr[counter]); - fputs(xx, md_result_file); - } + for (; ptr < end ; ptr++) + fprintf(md_result_file, "%02X", *ptr); } else unescape(md_result_file, row[i], lengths[i]); @@ -1809,13 +1857,8 @@ static int dump_all_databases() MYSQL_RES *tableres; int result=0; - if (mysql_query(sock, "SHOW DATABASES") || - !(tableres = mysql_store_result(sock))) - { - my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s", - MYF(0), mysql_error(sock)); + if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES")) return 1; - } while ((row = mysql_fetch_row(tableres))) { if (dump_all_tables_in_db(row[0])) @@ -1892,7 +1935,7 @@ static int init_dumping(char *database) sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s", qdatabase); - if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &dbinfo, qbuf)) { /* Old server version, dump generic CREATE DATABASE */ fprintf(md_result_file, @@ -1961,7 +2004,7 @@ static int dump_all_tables_in_db(char *database) check_io(md_result_file); } if (lock_tables) - mysql_query(sock,"UNLOCK TABLES"); + mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); return 0; } /* dump_all_tables_in_db */ @@ -2067,11 +2110,76 @@ static int dump_selected_tables(char *db, char **table_names, int tables) check_io(md_result_file); } if (lock_tables) - mysql_query(sock,"UNLOCK TABLES"); + mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); return 0; } /* dump_selected_tables */ +static int do_show_master_status(MYSQL *mysql_con) +{ + MYSQL_ROW row; + MYSQL_RES *master; + const char *comment_prefix= + (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : ""; + if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) + { + my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", + MYF(0), mysql_error(mysql_con)); + return 1; + } + else + { + row = mysql_fetch_row(master); + if (row && row[0] && row[1]) + { + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- Position to start replication or point-in-time " + "recovery from\n--\n\n"); + fprintf(md_result_file, + "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", + comment_prefix, row[0], row[1]); + check_io(md_result_file); + } + mysql_free_result(master); + } + return 0; +} + + +static int do_flush_tables_read_lock(MYSQL *mysql_con) +{ + return + mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES WITH READ LOCK"); +} + + +static int do_unlock_tables(MYSQL *mysql_con) +{ + return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"); +} + + +static int do_reset_master(MYSQL *mysql_con) +{ + return mysql_query_with_error_report(mysql_con, 0, "RESET MASTER"); +} + + +static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) +{ + /* + We use BEGIN for old servers. --single-transaction --master-data will fail + on old servers, but that's ok as it was already silently broken (it didn't + do a consistent read, so better tell people frankly, with the error). + */ + return (mysql_query_with_error_report(mysql_con, 0, + consistent_read_now ? + "START TRANSACTION " + "WITH CONSISTENT SNAPSHOT" : + "BEGIN")); +} + static ulong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, uint *err_len) @@ -2169,7 +2277,7 @@ static const char *check_if_ignore_table(const char *table_name) sprintf(buff,"show table status like %s", quote_for_like(table_name, show_name_buff)); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &res, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) { /* If old MySQL version */ @@ -2180,8 +2288,7 @@ static const char *check_if_ignore_table(const char *table_name) return 0; /* assume table is ok */ } } - if (!(res= mysql_store_result(sock)) || - !(row= mysql_fetch_row(res))) + if (!(row= mysql_fetch_row(res))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", @@ -2299,8 +2406,6 @@ static my_bool getViewStructure(char *table, char* db) int main(int argc, char **argv) { - MYSQL_ROW row; - MYSQL_RES *master; compatible_mode_normal_str[0]= 0; MY_INIT(argv[0]); @@ -2314,28 +2419,24 @@ int main(int argc, char **argv) if (!path) write_header(md_result_file, *argv); - if (opt_first_slave) - { - lock_tables=0; /* No other locks needed */ - if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } - } - else if (opt_single_transaction) + if ((opt_lock_all_tables || opt_master_data) && + do_flush_tables_read_lock(sock)) + goto err; + if (opt_single_transaction && start_transaction(sock, test(opt_master_data))) + goto err; + if (opt_delete_master_logs && do_reset_master(sock)) + goto err; + if (opt_lock_all_tables || opt_master_data) { - /* There is no sense to start transaction if all tables are locked */ - if (mysql_query(sock, "BEGIN")) - { - my_printf_error(0, "Error: Couldn't execute 'BEGIN': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } + if (flush_logs && mysql_refresh(sock, REFRESH_LOG)) + goto err; + flush_logs= 0; /* not anymore; that would not be sensible */ } + if (opt_master_data && do_show_master_status(sock)) + goto err; + if (opt_single_transaction && do_unlock_tables(sock)) // unlock but no commit! + goto err; + if (opt_alldbs) dump_all_databases(); else if (argc > 1 && !opt_databases) @@ -2348,57 +2449,16 @@ int main(int argc, char **argv) /* One or more databases, all tables */ dump_databases(argv); } - - if (opt_first_slave) - { - if (opt_delete_master_logs && mysql_query(sock, "FLUSH MASTER")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s", - MYF(0), mysql_error(sock)); - } - if (opt_master_data) - { - if (mysql_query(sock, "SHOW MASTER STATUS") || - !(master = mysql_store_result(sock))) - my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", - MYF(0), mysql_error(sock)); - else - { - row = mysql_fetch_row(master); - if (row && row[0] && row[1]) - { - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication from\n--\n\n"); - fprintf(md_result_file, - "CHANGE MASTER TO MASTER_LOG_FILE='%s', \ -MASTER_LOG_POS=%s ;\n",row[0],row[1]); - check_io(md_result_file); - } - mysql_free_result(master); - } - } - if (mysql_query(sock, "UNLOCK TABLES")) - my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s", - MYF(0), mysql_error(sock)); - } - else if (opt_single_transaction) /* Just to make it beautiful enough */ #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - { - /* - In case we were locking all tables, we did not start transaction - so there is no need to commit it. - */ - - /* This should just free locks as we did not change anything */ - if (mysql_query(sock, "COMMIT")) - { - my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s", - MYF(0), mysql_error(sock)); - } - } + /* + No reason to explicitely COMMIT the transaction, neither to explicitely + UNLOCK TABLES: these will be automatically be done by the server when we + disconnect now. Saves some code here, some network trips, adds nothing to + server. + */ +err: dbDisconnect(current_host); if (!path) write_footer(md_result_file); diff --git a/client/mysqltest.c b/client/mysqltest.c index 177f1bf75e2..4f55320e4f3 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3353,7 +3353,8 @@ static void init_var_hash(MYSQL *mysql) my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); my_hash_insert(&var_hash, (byte*) v); - + v= var_init(0,"DB", 2, db, 0); + my_hash_insert(&var_hash, (byte*) v); DBUG_VOID_RETURN; } diff --git a/configure.in b/configure.in index 5c322cf5394..d89d19179bd 100644 --- a/configure.in +++ b/configure.in @@ -480,7 +480,7 @@ if $PS p $$ 2> /dev/null | grep $0 > /dev/null then FIND_PROC="$PS p \$\$PID | grep mysqld > /dev/null" # Solaris -elif $PS -p $$ 2> /dev/null | grep $0 > /dev/null +elif $PS -fp $$ 2> /dev/null | grep $0 > /dev/null then FIND_PROC="$PS -p \$\$PID | grep mysqld > /dev/null" # BSD style @@ -3063,9 +3063,15 @@ AC_SUBST([NDB_DEFS]) AC_SUBST([ndb_cxxflags_fix]) +if test X"$ndb_port" = Xdefault +then + ndb_port="1186" +fi +AC_SUBST([ndb_port]) + if test X"$ndb_port_base" = Xdefault then - ndb_port_base="2200" + ndb_port_base="2202" fi AC_SUBST([ndb_port_base]) @@ -3104,7 +3110,6 @@ AC_CONFIG_FILES(ndb/Makefile ndb/include/Makefile dnl ndb/src/common/logger/Makefile dnl ndb/src/common/transporter/Makefile dnl ndb/src/common/mgmcommon/Makefile dnl - ndb/src/common/editline/Makefile dnl ndb/src/kernel/Makefile dnl ndb/src/kernel/error/Makefile dnl ndb/src/kernel/blocks/Makefile dnl @@ -3156,7 +3161,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl dbug/Makefile scripts/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl server-tools/Makefile server-tools/instance-manager/Makefile dnl - tests/Makefile Docs/Makefile support-files/Makefile dnl + tests/Makefile Docs/Makefile Docs/Images/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl netware/Makefile dnl include/mysql_version.h dnl diff --git a/dbug/dbug.c b/dbug/dbug.c index c5238eac122..d21b4e7801a 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -226,14 +226,15 @@ static my_bool init_done = FALSE; /* Set to TRUE when initialization done */ static struct state *stack=0; typedef struct st_code_state { - int lineno; /* Current debugger output line number */ - int level; /* Current function nesting level */ const char *func; /* Name of current user function */ const char *file; /* Name of current user file */ char **framep; /* Pointer to current frame */ - int jmplevel; /* Remember nesting level at setjmp () */ const char *jmpfunc; /* Remember current function for setjmp */ const char *jmpfile; /* Remember current file for setjmp */ + int lineno; /* Current debugger output line number */ + int level; /* Current function nesting level */ + int disable_output; /* Set to it if output is disabled */ + int jmplevel; /* Remember nesting level at setjmp () */ /* * The following variables are used to hold the state information @@ -246,8 +247,8 @@ typedef struct st_code_state { */ uint u_line; /* User source code line number */ - const char *u_keyword; /* Keyword for current macro */ int locked; /* If locked with _db_lock_file */ + const char *u_keyword; /* Keyword for current macro */ } CODE_STATE; /* Parse a debug command string */ @@ -369,8 +370,10 @@ static CODE_STATE *code_state(void) #define code_state() (&static_code_state) #define pthread_mutex_lock(A) {} #define pthread_mutex_unlock(A) {} -static CODE_STATE static_code_state = { 0,0,"?func","?file",NULL,0,NULL, - NULL,0,"?",0}; +static CODE_STATE static_code_state= +{ + "?func", "?file", NULL, NullS, NullS, 0,0,0,0,0,0, NullS +}; #endif @@ -727,9 +730,12 @@ char ***_sframep_ __attribute__((unused))) if (DoProfile ()) { long stackused; - if (*state->framep == NULL) { + if (*state->framep == NULL) + { stackused = 0; - } else { + } + else + { stackused = ((long)(*state->framep)) - ((long)(state->framep)); stackused = stackused > 0 ? stackused : -stackused; } @@ -743,7 +749,7 @@ char ***_sframep_ __attribute__((unused))) (void) fflush (_db_pfp_); } #endif - if (DoTrace (state)) + if (DoTrace(state)) { if (!state->locked) pthread_mutex_lock(&THR_LOCK_dbug); @@ -753,7 +759,7 @@ char ***_sframep_ __attribute__((unused))) dbug_flush (state); /* This does a unlock */ } #ifdef SAFEMALLOC - if (stack -> flags & SANITY_CHECK_ON) + if (stack->flags & SANITY_CHECK_ON && !state->disable_output) if (_sanity(_file_,_line_)) /* Check of safemalloc */ stack -> flags &= ~SANITY_CHECK_ON; #endif @@ -808,9 +814,11 @@ uint *_slevel_) else { #ifdef SAFEMALLOC - if (stack -> flags & SANITY_CHECK_ON) + if (stack->flags & SANITY_CHECK_ON && !state->disable_output) + { if (_sanity(*_sfile_,_line_)) stack->flags &= ~SANITY_CHECK_ON; + } #endif #ifndef THREAD if (DoProfile ()) @@ -953,7 +961,6 @@ uint length) int pos; char dbuff[90]; CODE_STATE *state; - /* Sasha: pre-my_thread_init() safety */ if (!(state=code_state())) return; @@ -993,6 +1000,25 @@ uint length) } } + +/* + Enable/Disable output for this thread + + SYNOPSIS + _db_output_() + flag 1 = enable output, 0 = disable_output + +*/ + +void _db_output_(uint flag) +{ + CODE_STATE *state; + if (!(state=code_state())) + return; + state->disable_output= !flag; +} + + /* * FUNCTION * @@ -1158,7 +1184,7 @@ static BOOLEAN DoTrace (CODE_STATE *state) { reg2 BOOLEAN trace=FALSE; - if (TRACING && + if (TRACING && !state->disable_output && state->level <= stack -> maxdepth && InList (stack -> functions, state->func) && InList (stack -> processes, _db_process_)) @@ -1194,7 +1220,7 @@ static BOOLEAN DoProfile () state=code_state(); profile = FALSE; - if (PROFILING && + if (PROFILING && !state->disable_output && state->level <= stack -> maxdepth && InList (stack -> p_functions, state->func) && InList (stack -> processes, _db_process_)) @@ -1268,7 +1294,7 @@ const char *keyword) if (!(state=code_state())) return FALSE; result = FALSE; - if (DEBUGGING && + if (DEBUGGING && !state->disable_output && state->level <= stack -> maxdepth && InList (stack -> functions, state->func) && InList (stack -> keywords, keyword) && diff --git a/include/my_dbug.h b/include/my_dbug.h index 4dd795cf4c0..cf32102b34b 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -39,6 +39,7 @@ extern void _db_pargs_(uint _line_,const char *keyword); extern void _db_doprnt_ _VARARGS((const char *format,...)); extern void _db_dump_(uint _line_,const char *keyword,const char *memory, uint length); +extern void _db_output_(); extern void _db_lock_file(); extern void _db_unlock_file(); @@ -67,6 +68,7 @@ extern void _db_unlock_file(); #define DEBUGGER_ON _no_db_=0 #define DBUG_LOCK_FILE { _db_lock_file(); } #define DBUG_UNLOCK_FILE { _db_unlock_file(); } +#define DBUG_OUTPUT(A) { _db_output_(A); } #define DBUG_ASSERT(A) assert(A) #define DBUG_EXECUTE_IF(keyword,a1) \ {if (_db_on_) {if (_db_strict_keyword_ (keyword)) { a1 }}} @@ -90,6 +92,7 @@ extern void _db_unlock_file(); #define DEBUGGER_ON #define DBUG_LOCK_FILE #define DBUG_UNLOCK_FILE +#define DBUG_OUTPUT(A) #define DBUG_ASSERT(A) {} #endif #ifdef __cplusplus diff --git a/include/my_global.h b/include/my_global.h index 0ace3123fae..369ba838698 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -370,6 +370,12 @@ int __void__; #define LINT_INIT(var) #endif +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(HAVE_purify) +#define PURIFY_OR_LINT_INIT(var) var=0 +#else +#define PURIFY_OR_LINT_INIT(var) +#endif + /* Define some useful general macros */ #if defined(__cplusplus) && defined(__GNUC__) #define max(a, b) ((a) >? (b)) diff --git a/include/my_sys.h b/include/my_sys.h index 0db661b7781..6a20f6aa9dd 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -221,6 +221,7 @@ extern ulong my_cache_w_requests, my_cache_write, my_cache_r_requests, my_cache_read; extern ulong my_blocks_used, my_blocks_changed; extern ulong my_file_opened,my_stream_opened, my_tmp_file_created; +extern uint mysys_usage_id; extern my_bool my_init_done; /* Point to current my_message() */ diff --git a/include/mysql.h b/include/mysql.h index 0a7ab09c57b..0edd3873192 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -490,6 +490,8 @@ MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, const char *wild); unsigned long STDCALL mysql_escape_string(char *to,const char *from, unsigned long from_length); +unsigned long STDCALL mysql_hex_string(char *to,const char *from, + unsigned long from_length); unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, unsigned long length); diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 1e190496fde..4ef23f446c9 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -12,7 +12,7 @@ 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 */ + Foundation, Inc., 59 Temple Placeo Suite 330, Boston, MA 02111-1307 USA */ /* Definefile for error messagenumbers */ @@ -387,4 +387,25 @@ #define ER_VIEW_NONUPD_CHECK 1368 #define ER_VIEW_CHECK_FAILED 1369 #define ER_SP_ACCESS_DENIED_ERROR 1370 -#define ER_ERROR_MESSAGES 371 +#define ER_RELAY_LOG_FAIL 1371 +#define ER_PASSWD_LENGTH 1372 +#define ER_UNKNOWN_TARGET_BINLOG 1373 +#define ER_IO_ERR_LOG_INDEX_READ 1374 +#define ER_BINLOG_PURGE_PROHIBITED 1375 +#define ER_FSEEK_FAIL 1376 +#define ER_BINLOG_PURGE_FATAL_ERR 1377 +#define ER_LOG_IN_USE 1378 +#define ER_LOG_PURGE_UNKNOWN_ERR 1379 +#define ER_RELAY_LOG_INIT 1380 +#define ER_NO_BINARY_LOGGING 1381 +#define ER_RESERVED_SYNTAX 1382 +#define ER_WSAS_FAILED 1383 +#define ER_DIFF_GROUPS_PROC 1384 +#define ER_NO_GROUP_FOR_PROC 1385 +#define ER_ORDER_WITH_PROC 1386 +#define ER_LOGING_PROHIBIT_CHANGING_OF 1387 +#define ER_NO_FILE_MAPPING 1388 +#define ER_WRONG_MAGIC 1389 +#define ER_PS_MANY_PARAM 1390 +#define ER_KEY_PART_0 1391 +#define ER_ERROR_MESSAGES 392 diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index bc08fc2437e..183c547ab2b 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2266,8 +2266,8 @@ dict_foreign_add_to_cache( /************************************************************************* Scans from pointer onwards. Stops if is at the start of a copy of -'string' where characters are compared without case sensitivity. Stops -also at '\0'. */ +'string' where characters are compared without case sensitivity, and +only outside `` or "" quotes. Stops also at '\0'. */ const char* dict_scan_to( @@ -2276,31 +2276,34 @@ dict_scan_to( const char* ptr, /* in: scan from */ const char* string) /* in: look for this */ { - ibool success; - ulint i; -loop: - if (*ptr == '\0') { - return(ptr); - } - - success = TRUE; - - for (i = 0; i < ut_strlen(string); i++) { - if (toupper((ulint)(ptr[i])) != toupper((ulint)(string[i]))) { - success = FALSE; + char quote = '\0'; + for (; *ptr; ptr++) { + if (*ptr == quote) { + /* Closing quote character: do not look for + starting quote or the keyword. */ + quote = '\0'; + } else if (quote) { + /* Within quotes: do nothing. */ + } else if (*ptr == '`' || *ptr == '"') { + /* Starting quote: remember the quote character. */ + quote = *ptr; + } else { + /* Outside quotes: look for the keyword. */ + ulint i; + for (i = 0; string[i]; i++) { + if (toupper((ulint)(ptr[i])) + != toupper((ulint)(string[i]))) { + goto nomatch; + } + } break; + nomatch: + ; } } - if (success) { - - return(ptr); - } - - ptr++; - - goto loop; + return(ptr); } /************************************************************************* @@ -2877,13 +2880,13 @@ loop: ut_a(success); - if (!isspace(*ptr)) { + if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') { goto loop; } - do { + while (isspace(*ptr)) { ptr++; - } while (isspace(*ptr)); + } /* read constraint name unless got "CONSTRAINT FOREIGN" */ if (ptr != ptr2) { diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 0f7cc8973db..85e4aaf1a05 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -342,13 +342,16 @@ dict_index_rec_get_sys_col( ut_ad(len == 7); return(trx_read_roll_ptr(field)); - } else if ((type == DATA_ROW_ID) || (type == DATA_MIX_ID)) { + } else if (type == DATA_TRX_ID) { + + return(trx_read_trx_id(field)); + } else if (type == DATA_MIX_ID) { return(mach_dulint_read_compressed(field)); } else { - ut_ad(type == DATA_TRX_ID); + ut_a(type == DATA_ROW_ID); - return(trx_read_trx_id(field)); + return(mach_read_from_6(field)); } } diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index 6726d7ca609..5c62640e011 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -1069,30 +1069,6 @@ trx_purge(void) } } - /* Determine how much data manipulation language (DML) statements - need to be delayed in order to reduce the lagging of the purge - thread. */ - srv_dml_needed_delay = 0; /* in microseconds; default: no delay */ - - /* If we cannot advance the 'purge view' because of an old - 'consistent read view', then the DML statements cannot be delayed. - Also, srv_max_purge_lag <= 0 means 'infinity'. */ - if (srv_max_purge_lag > 0 - && !UT_LIST_GET_LAST(trx_sys->view_list)) { - float ratio = (float) trx_sys->rseg_history_len - / srv_max_purge_lag; - if (ratio > ULINT_MAX / 10000) { - /* Avoid overflow: maximum delay is 4295 seconds */ - srv_dml_needed_delay = ULINT_MAX; - } else if (ratio > 1) { - /* If the history list length exceeds the - innodb_max_purge_lag, the - data manipulation statements are delayed - by at least 5000 microseconds. */ - srv_dml_needed_delay = (ulint) ((ratio - .5) * 10000); - } - } - purge_sys->view = read_view_oldest_copy_or_open_new(NULL, purge_sys->heap); mutex_exit(&kernel_mutex); diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 5c2dc9c7ba6..72ff44ecef3 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -30,7 +30,7 @@ include $(srcdir)/Makefile.shared libmysqlclient_la_SOURCES = $(target_sources) libmysqlclient_la_LIBADD = $(target_libadd) libmysqlclient_la_LDFLAGS = $(target_ldflags) -EXTRA_DIST = Makefile.shared +EXTRA_DIST = Makefile.shared libmysql.def noinst_HEADERS = client_settings.h # This is called from the toplevel makefile diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 9fba0327525..15f07667625 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -664,7 +664,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags) DBUG_RETURN(prepare_for_send(list)); err: - send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */ + my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 1df518a2712..2999482549c 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -656,6 +656,15 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (chk_index_down(param,info,&info->s->ft2_keyinfo,record, temp_buff,&tmp_keys,key_checksum,1)) goto err; + if (tmp_keys + subkeys) + { + mi_check_print_error(param, + "Number of words in the 2nd level tree " + "does not match the number in the header. " + "Parent word in on the page %s, offset %u", + llstr(page,llbuff), (uint) (old_keypos-buff)); + goto err; + } (*keys)+=tmp_keys-1; continue; } diff --git a/myisam/mi_write.c b/myisam/mi_write.c index dc596672a84..e059bbb569f 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -372,6 +372,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, /* popular word. two-level tree. going down */ my_off_t root=info->dupp_key_pos; keyinfo=&info->s->ft2_keyinfo; + get_key_full_length_rdonly(off, key); key+=off; keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */ error=_mi_ck_real_write_btree(info, keyinfo, key, 0, diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index ad02d304d1b..c4b3fae40f9 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -37,7 +37,7 @@ test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem CLEANFILES = $(test_SCRIPTS) $(test_DATA) INCLUDES = -I$(srcdir)/../include -I../include -I.. -bin_PROGRAMS = mysql_test_run_new +EXTRA_PROGRAMS = mysql_test_run_new noinst_HEADERS = my_manage.h mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c @@ -48,6 +48,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r + $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data @@ -70,6 +71,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data std_data/%.pem: diff --git a/mysql-test/init_db.sql b/mysql-test/init_db.sql index 4613e5c0274..63483af00d6 100644 --- a/mysql-test/init_db.sql +++ b/mysql-test/init_db.sql @@ -3,24 +3,56 @@ CREATE DATABASE test; USE mysql; -CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges'; +CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL,Db char(64) binary DEFAULT '' NOT NULL,User char(16) binary DEFAULT '' NOT NULL,Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,References_priv enum('N','Y') DEFAULT 'N' NOT NULL,Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,PRIMARY KEY Host (Host,Db,User),KEY User (User)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges'; + INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); - -CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges'; -CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(45) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges'; -INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); -INSERT INTO user VALUES ('','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); +CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL,Db char(64) binary DEFAULT '' NOT NULL,Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,References_priv enum('N','Y') DEFAULT 'N' NOT NULL,Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,PRIMARY KEY Host (Host,Db)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges'; -INSERT INTO user (host,user) values ('localhost',''); -INSERT INTO user (host,user) values ('',''); +CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL,User char(16) binary DEFAULT '' NOT NULL,Password char(41) binary DEFAULT '' NOT NULL,Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL,Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL,Process_priv enum('N','Y') DEFAULT 'N' NOT NULL,File_priv enum('N','Y') DEFAULT 'N' NOT NULL,Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,References_priv enum('N','Y') DEFAULT 'N' NOT NULL,Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,ssl_cipher BLOB NOT NULL,x509_issuer BLOB NOT NULL,x509_subject BLOB NOT NULL,max_questions int(11) unsigned DEFAULT 0 NOT NULL,max_updates int(11) unsigned DEFAULT 0 NOT NULL,max_connections int(11) unsigned DEFAULT 0 NOT NULL,PRIMARY KEY Host (Host,User)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; -CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions'; +INSERT INTO user VALUES ('%','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); +INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); +INSERT INTO user VALUES ('%','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0); -CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges'; +CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL,ret tinyint(1) DEFAULT '0' NOT NULL,dl char(128) DEFAULT '' NOT NULL,type enum ('function','aggregate') NOT NULL,PRIMARY KEY (name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions'; + +CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL,Db char(64) binary DEFAULT '' NOT NULL,User char(16) binary DEFAULT '' NOT NULL,Table_name char(64) binary DEFAULT '' NOT NULL,Grantor char(77) DEFAULT '' NOT NULL,Timestamp timestamp(14),Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL,Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,PRIMARY KEY (Host,Db,User,Table_name),KEY Grantor (Grantor)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges'; + +CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL,Db char(64) binary DEFAULT '' NOT NULL,User char(16) binary DEFAULT '' NOT NULL,Table_name char(64) binary DEFAULT '' NOT NULL,Column_name char(64) binary DEFAULT '' NOT NULL,Timestamp timestamp(14),Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,PRIMARY KEY (Host,Db,User,Table_name,Column_name)) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges'; + +CREATE TABLE help_topic (help_topic_id int unsigned not null,name varchar(64) not null,help_category_id smallint unsigned not null,description text not null,example text not null,url varchar(128) not null,primary key (help_topic_id),unique index (name)) engine=MyISAM CHARACTER SET utf8 comment='help topics'; + +CREATE TABLE help_category (help_category_id smallint unsigned not null,name varchar(64) not null,parent_category_id smallint unsigned null,url varchar(128) not null,primary key (help_category_id),unique index (name)) engine=MyISAM CHARACTER SET utf8 comment='help categories'; + +CREATE TABLE help_keyword (help_keyword_id int unsigned not null,name varchar(64) not null,primary key (help_keyword_id),unique index (name)) engine=MyISAM CHARACTER SET utf8 comment='help keywords'; + +CREATE TABLE help_relation (help_topic_id int unsigned not null references help_topic,help_keyword_id int unsigned not null references help_keyword,primary key (help_keyword_id, help_topic_id)) engine=MyISAM CHARACTER SET utf8 comment='keyword-topic relation'; + +CREATE TABLE time_zone_name (Name char(64) NOT NULL,Time_zone_id int unsigned NOT NULL,PRIMARY KEY Name (Name)) engine=MyISAM CHARACTER SET utf8 comment='Time zone names'; + +INSERT INTO time_zone_name (Name, Time_Zone_id) VALUES ('MET', 1), ('UTC', 2), ('Universal', 2), ('Europe/Moscow',3), ('leap/Europe/Moscow',4), ('Japan', 5); + + +CREATE TABLE time_zone (Time_zone_id int unsigned NOT NULL auto_increment,Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL,PRIMARY KEY TzId (Time_zone_id)) engine=MyISAM CHARACTER SET utf8 comment='Time zones'; + +INSERT INTO time_zone (Time_zone_id, Use_leap_seconds) VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y'), (5,'N'); + + +CREATE TABLE time_zone_transition (Time_zone_id int unsigned NOT NULL,Transition_time bigint signed NOT NULL,Transition_type_id int unsigned NOT NULL,PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)) engine=MyISAM CHARACTER SET utf8 comment='Time zone transitions'; + +INSERT INTO time_zone_transition (Time_zone_id, Transition_time, Transition_type_id) VALUES (1, -1693706400, 0) ,(1, -1680483600, 1),(1, -1663455600, 2) ,(1, -1650150000, 3),(1, -1632006000, 2) ,(1, -1618700400, 3),(1, -938905200, 2) ,(1, -857257200, 3),(1, -844556400, 2) ,(1, -828226800, 3),(1, -812502000, 2) ,(1, -796777200, 3),(1, 228877200, 2) ,(1, 243997200, 3),(1, 260326800, 2) ,(1, 276051600, 3),(1, 291776400, 2) ,(1, 307501200, 3),(1, 323830800, 2) ,(1, 338950800, 3),(1, 354675600, 2) ,(1, 370400400, 3),(1, 386125200, 2) ,(1, 401850000, 3),(1, 417574800, 2) ,(1, 433299600, 3),(1, 449024400, 2) ,(1, 465354000, 3),(1, 481078800, 2) ,(1, 496803600, 3),(1, 512528400, 2) ,(1, 528253200, 3),(1, 543978000, 2) ,(1, 559702800, 3),(1, 575427600, 2) ,(1, 591152400, 3),(1, 606877200, 2) ,(1, 622602000, 3),(1, 638326800, 2) ,(1, 654656400, 3),(1, 670381200, 2) ,(1, 686106000, 3),(1, 701830800, 2) ,(1, 717555600, 3),(1, 733280400, 2) ,(1, 749005200, 3),(1, 764730000, 2) ,(1, 780454800, 3),(1, 796179600, 2) ,(1, 811904400, 3),(1, 828234000, 2) ,(1, 846378000, 3),(1, 859683600, 2) ,(1, 877827600, 3),(1, 891133200, 2) ,(1, 909277200, 3),(1, 922582800, 2) ,(1, 941331600, 3),(1, 954032400, 2) ,(1, 972781200, 3),(1, 985482000, 2) ,(1, 1004230800, 3),(1, 1017536400, 2) ,(1, 1035680400, 3),(1, 1048986000, 2) ,(1, 1067130000, 3),(1, 1080435600, 2) ,(1, 1099184400, 3),(1, 1111885200, 2) ,(1, 1130634000, 3),(1, 1143334800, 2) ,(1, 1162083600, 3),(1, 1174784400, 2) ,(1, 1193533200, 3),(1, 1206838800, 2) ,(1, 1224982800, 3),(1, 1238288400, 2) ,(1, 1256432400, 3),(1, 1269738000, 2) ,(1, 1288486800, 3),(1, 1301187600, 2) ,(1, 1319936400, 3),(1, 1332637200, 2) ,(1, 1351386000, 3),(1, 1364691600, 2) ,(1, 1382835600, 3),(1, 1396141200, 2) ,(1, 1414285200, 3),(1, 1427590800, 2) ,(1, 1445734800, 3),(1, 1459040400, 2) ,(1, 1477789200, 3),(1, 1490490000, 2) ,(1, 1509238800, 3),(1, 1521939600, 2) ,(1, 1540688400, 3),(1, 1553994000, 2) ,(1, 1572138000, 3),(1, 1585443600, 2) ,(1, 1603587600, 3),(1, 1616893200, 2) ,(1, 1635642000, 3),(1, 1648342800, 2) ,(1, 1667091600, 3),(1, 1679792400, 2) ,(1, 1698541200, 3),(1, 1711846800, 2) ,(1, 1729990800, 3),(1, 1743296400, 2) ,(1, 1761440400, 3),(1, 1774746000, 2) ,(1, 1792890000, 3),(1, 1806195600, 2) ,(1, 1824944400, 3),(1, 1837645200, 2) ,(1, 1856394000, 3),(1, 1869094800, 2) ,(1, 1887843600, 3),(1, 1901149200, 2) ,(1, 1919293200, 3),(1, 1932598800, 2) ,(1, 1950742800, 3),(1, 1964048400, 2) ,(1, 1982797200, 3),(1, 1995498000, 2) ,(1, 2014246800, 3),(1, 2026947600, 2) ,(1, 2045696400, 3),(1, 2058397200, 2) ,(1, 2077146000, 3),(1, 2090451600, 2) ,(1, 2108595600, 3),(1, 2121901200, 2) ,(1, 2140045200, 3),(3, -1688265000, 2) ,(3, -1656819048, 1),(3, -1641353448, 2) ,(3, -1627965048, 3),(3, -1618716648, 1) ,(3, -1596429048, 3),(3, -1593829848, 5) ,(3, -1589860800, 4),(3, -1542427200, 5) ,(3, -1539493200, 6),(3, -1525323600, 5) ,(3, -1522728000, 4),(3, -1491188400, 7) ,(3, -1247536800, 4),(3, 354920400, 5) ,(3, 370728000, 4),(3, 386456400, 5) ,(3, 402264000, 4),(3, 417992400, 5) ,(3, 433800000, 4),(3, 449614800, 5) ,(3, 465346800, 8),(3, 481071600, 9) ,(3, 496796400, 8),(3, 512521200, 9) ,(3, 528246000, 8),(3, 543970800, 9) ,(3, 559695600, 8),(3, 575420400, 9) ,(3, 591145200, 8),(3, 606870000, 9) ,(3, 622594800, 8),(3, 638319600, 9) ,(3, 654649200, 8),(3, 670374000, 10) ,(3, 686102400, 11),(3, 695779200, 8) ,(3, 701812800, 5),(3, 717534000, 4) ,(3, 733273200, 9),(3, 748998000, 8) ,(3, 764722800, 9),(3, 780447600, 8) ,(3, 796172400, 9),(3, 811897200, 8) ,(3, 828226800, 9),(3, 846370800, 8) ,(3, 859676400, 9),(3, 877820400, 8) ,(3, 891126000, 9),(3, 909270000, 8) ,(3, 922575600, 9),(3, 941324400, 8) ,(3, 954025200, 9),(3, 972774000, 8) ,(3, 985474800, 9),(3, 1004223600, 8) ,(3, 1017529200, 9),(3, 1035673200, 8) ,(3, 1048978800, 9),(3, 1067122800, 8) ,(3, 1080428400, 9),(3, 1099177200, 8) ,(3, 1111878000, 9),(3, 1130626800, 8) ,(3, 1143327600, 9),(3, 1162076400, 8) ,(3, 1174777200, 9),(3, 1193526000, 8) ,(3, 1206831600, 9),(3, 1224975600, 8) ,(3, 1238281200, 9),(3, 1256425200, 8) ,(3, 1269730800, 9),(3, 1288479600, 8) ,(3, 1301180400, 9),(3, 1319929200, 8) ,(3, 1332630000, 9),(3, 1351378800, 8) ,(3, 1364684400, 9),(3, 1382828400, 8) ,(3, 1396134000, 9),(3, 1414278000, 8) ,(3, 1427583600, 9),(3, 1445727600, 8) ,(3, 1459033200, 9),(3, 1477782000, 8) ,(3, 1490482800, 9),(3, 1509231600, 8) ,(3, 1521932400, 9),(3, 1540681200, 8) ,(3, 1553986800, 9),(3, 1572130800, 8) ,(3, 1585436400, 9),(3, 1603580400, 8) ,(3, 1616886000, 9),(3, 1635634800, 8) ,(3, 1648335600, 9),(3, 1667084400, 8) ,(3, 1679785200, 9),(3, 1698534000, 8) ,(3, 1711839600, 9),(3, 1729983600, 8) ,(3, 1743289200, 9),(3, 1761433200, 8) ,(3, 1774738800, 9),(3, 1792882800, 8) ,(3, 1806188400, 9),(3, 1824937200, 8) ,(3, 1837638000, 9),(3, 1856386800, 8) ,(3, 1869087600, 9),(3, 1887836400, 8) ,(3, 1901142000, 9),(3, 1919286000, 8) ,(3, 1932591600, 9),(3, 1950735600, 8) ,(3, 1964041200, 9),(3, 1982790000, 8) ,(3, 1995490800, 9),(3, 2014239600, 8) ,(3, 2026940400, 9),(3, 2045689200, 8) ,(3, 2058390000, 9),(3, 2077138800, 8) ,(3, 2090444400, 9),(3, 2108588400, 8) ,(3, 2121894000, 9),(3, 2140038000, 8),(4, -1688265000, 2) ,(4, -1656819048, 1),(4, -1641353448, 2) ,(4, -1627965048, 3),(4, -1618716648, 1) ,(4, -1596429048, 3),(4, -1593829848, 5) ,(4, -1589860800, 4),(4, -1542427200, 5) ,(4, -1539493200, 6),(4, -1525323600, 5) ,(4, -1522728000, 4),(4, -1491188400, 7) ,(4, -1247536800, 4),(4, 354920409, 5) ,(4, 370728010, 4),(4, 386456410, 5) ,(4, 402264011, 4),(4, 417992411, 5) ,(4, 433800012, 4),(4, 449614812, 5) ,(4, 465346812, 8),(4, 481071612, 9) ,(4, 496796413, 8),(4, 512521213, 9) ,(4, 528246013, 8),(4, 543970813, 9) ,(4, 559695613, 8),(4, 575420414, 9) ,(4, 591145214, 8),(4, 606870014, 9) ,(4, 622594814, 8),(4, 638319615, 9) ,(4, 654649215, 8),(4, 670374016, 10) ,(4, 686102416, 11),(4, 695779216, 8) ,(4, 701812816, 5),(4, 717534017, 4) ,(4, 733273217, 9),(4, 748998018, 8) ,(4, 764722818, 9),(4, 780447619, 8) ,(4, 796172419, 9),(4, 811897219, 8) ,(4, 828226820, 9),(4, 846370820, 8) ,(4, 859676420, 9),(4, 877820421, 8) ,(4, 891126021, 9),(4, 909270021, 8) ,(4, 922575622, 9),(4, 941324422, 8) ,(4, 954025222, 9),(4, 972774022, 8) ,(4, 985474822, 9),(4, 1004223622, 8) ,(4, 1017529222, 9),(4, 1035673222, 8) ,(4, 1048978822, 9),(4, 1067122822, 8) ,(4, 1080428422, 9),(4, 1099177222, 8) ,(4, 1111878022, 9),(4, 1130626822, 8) ,(4, 1143327622, 9),(4, 1162076422, 8) ,(4, 1174777222, 9),(4, 1193526022, 8) ,(4, 1206831622, 9),(4, 1224975622, 8) ,(4, 1238281222, 9),(4, 1256425222, 8) ,(4, 1269730822, 9),(4, 1288479622, 8) ,(4, 1301180422, 9),(4, 1319929222, 8) ,(4, 1332630022, 9),(4, 1351378822, 8) ,(4, 1364684422, 9),(4, 1382828422, 8) ,(4, 1396134022, 9),(4, 1414278022, 8) ,(4, 1427583622, 9),(4, 1445727622, 8) ,(4, 1459033222, 9),(4, 1477782022, 8) ,(4, 1490482822, 9),(4, 1509231622, 8) ,(4, 1521932422, 9),(4, 1540681222, 8) ,(4, 1553986822, 9),(4, 1572130822, 8) ,(4, 1585436422, 9),(4, 1603580422, 8) ,(4, 1616886022, 9),(4, 1635634822, 8) ,(4, 1648335622, 9),(4, 1667084422, 8) ,(4, 1679785222, 9),(4, 1698534022, 8) ,(4, 1711839622, 9),(4, 1729983622, 8) ,(4, 1743289222, 9),(4, 1761433222, 8) ,(4, 1774738822, 9),(4, 1792882822, 8) ,(4, 1806188422, 9),(4, 1824937222, 8) ,(4, 1837638022, 9),(4, 1856386822, 8) ,(4, 1869087622, 9),(4, 1887836422, 8) ,(4, 1901142022, 9),(4, 1919286022, 8) ,(4, 1932591622, 9),(4, 1950735622, 8) ,(4, 1964041222, 9),(4, 1982790022, 8) ,(4, 1995490822, 9),(4, 2014239622, 8) ,(4, 2026940422, 9),(4, 2045689222, 8) ,(4, 2058390022, 9),(4, 2077138822, 8) ,(4, 2090444422, 9),(4, 2108588422, 8) ,(4, 2121894022, 9),(4, 2140038022, 8); + + +CREATE TABLE time_zone_transition_type (Time_zone_id int unsigned NOT NULL,Transition_type_id int unsigned NOT NULL,Offset int signed DEFAULT 0 NOT NULL,Is_DST tinyint unsigned DEFAULT 0 NOT NULL,Abbreviation char(8) DEFAULT '' NOT NULL,PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)) engine=MyISAM CHARACTER SET utf8 comment='Time zone transition types'; + +INSERT INTO time_zone_transition_type (Time_zone_id,Transition_type_id, Offset, Is_DST, Abbreviation) VALUES (1, 0, 7200, 1, 'MEST') ,(1, 1, 3600, 0, 'MET') ,(1, 2, 7200, 1, 'MEST') ,(1, 3, 3600, 0, 'MET') ,(2, 0, 0, 0, 'UTC') ,(3, 0, 9000, 0, 'MMT') ,(3, 1, 12648, 1, 'MST') ,(3, 2, 9048, 0, 'MMT') ,(3, 3, 16248, 1, 'MDST') ,(3, 4, 10800, 0, 'MSK') ,(3, 5, 14400, 1, 'MSD') ,(3, 6, 18000, 1, 'MSD') ,(3, 7, 7200, 0, 'EET') ,(3, 8, 10800, 0, 'MSK') ,(3, 9, 14400, 1, 'MSD') ,(3, 10, 10800, 1, 'EEST') ,(3, 11, 7200, 0, 'EET') ,(4, 0, 9000, 0, 'MMT') ,(4, 1, 12648, 1, 'MST') ,(4, 2, 9048, 0, 'MMT') ,(4, 3, 16248, 1, 'MDST') ,(4, 4, 10800, 0, 'MSK') ,(4, 5, 14400, 1, 'MSD') ,(4, 6, 18000, 1, 'MSD') ,(4, 7, 7200, 0, 'EET') ,(4, 8, 10800, 0, 'MSK') ,(4, 9, 14400, 1, 'MSD') ,(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET') ,(5, 0, 32400, 0, 'CJT') ,(5, 1, 32400, 0, 'JST'); + +CREATE TABLE time_zone_leap_second (Transition_time bigint signed NOT NULL,Correction int signed NOT NULL,PRIMARY KEY TranTime (Transition_time)) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; + +INSERT INTO time_zone_leap_second (Transition_time, Correction) VALUES (78796800, 1) ,(94694401, 2) ,(126230402, 3) ,(157766403, 4) ,(189302404, 5) ,(220924805, 6) ,(252460806, 7) ,(283996807, 8) ,(315532808, 9) ,(362793609, 10) ,(394329610, 11) ,(425865611, 12) ,(489024012, 13) ,(567993613, 14) ,(631152014, 15) ,(662688015, 16) ,(709948816, 17) ,(741484817, 18) ,(773020818, 19) ,(820454419, 20) ,(867715220, 21) ,(915148821, 22); -CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges'; diff --git a/mysql-test/my_manage.c b/mysql-test/my_manage.c index ba5c674d105..cc27558f131 100644 --- a/mysql-test/my_manage.c +++ b/mysql-test/my_manage.c @@ -30,7 +30,8 @@ #ifndef __WIN__ #include <sys/wait.h> #include <unistd.h> -#include <fnmatch.h> +#include <signal.h> +#include <fnmatch.h> /* FIXME HAVE_FNMATCH_H or something */ #else #include <direct.h> #include <stdlib.h> @@ -100,7 +101,7 @@ void init_args(arg_list_t *al) void add_arg(arg_list_t *al, const char *format, ...) { va_list ap; - char temp[PATH_MAX]; + char temp[FN_REFLEN]; ASSERT(al != NULL); @@ -230,10 +231,10 @@ int wait_for_server_start(char *bin_dir __attribute__((unused)), { arg_list_t al; int err= 0, i; - char trash[PATH_MAX]; + char trash[FN_REFLEN]; /* mysqladmin file */ - snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir); + snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir); /* args */ init_args(&al); @@ -490,9 +491,9 @@ int stop_server(char *bin_dir __attribute__((unused)), char *mysqladmin_file, { arg_list_t al; int err= 0; - char trash[PATH_MAX]; + char trash[FN_REFLEN]; - snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir); + snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir); /* args */ init_args(&al); @@ -548,7 +549,7 @@ int stop_server(char *bin_dir __attribute__((unused)), char *mysqladmin_file, #ifndef __WIN__ pid_t get_server_pid(char *pid_file) { - char buf[PATH_MAX]; + char buf[FN_REFLEN]; int fd, err; char *p; pid_t id= 0; @@ -556,7 +557,7 @@ pid_t get_server_pid(char *pid_file) /* discover id */ fd= open(pid_file, O_RDONLY); - err= read(fd, buf, PATH_MAX); + err= read(fd, buf, FN_REFLEN); close(fd); @@ -619,7 +620,7 @@ void del_tree(char *dir) #ifndef __WIN__ DIR *parent= opendir(dir); struct dirent *entry; - char temp[PATH_MAX]; + char temp[FN_REFLEN]; if (parent == NULL) { @@ -629,22 +630,36 @@ void del_tree(char *dir) while ((entry= readdir(parent)) != NULL) { /* create long name */ - snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name); + snprintf(temp, FN_REFLEN, "%s/%s", dir, entry->d_name); if (entry->d_name[0] == '.') { /* Skip */ } else - if (S_ISDIR(entry->d_type)) { - /* delete subdirectory */ - del_tree(temp); - } - else - { - /* remove file */ - remove(temp); +/* FIXME missing test in acinclude.m4 */ +#ifndef STRUCT_DIRENT_HAS_D_TYPE + struct stat st; + + if (lstat(entry->d_name, &st) == -1) + { + /* FIXME error */ + return; + } + if (S_ISDIR(st.st_mode)) +#else + if (S_ISDIR(entry->d_type)) +#endif + { + /* delete subdirectory */ + del_tree(temp); + } + else + { + /* remove file */ + remove(temp); + } } } /* remove directory */ @@ -652,10 +667,10 @@ void del_tree(char *dir) #else struct _finddata_t parent; intptr_t handle; - char temp[PATH_MAX]; - char mask[PATH_MAX]; + char temp[FN_REFLEN]; + char mask[FN_REFLEN]; - snprintf(mask,MAX_PATH,"%s/*.*",dir); + snprintf(mask,FN_REFLEN,"%s/*.*",dir); if ((handle=_findfirst(mask,&parent)) == -1L) { @@ -665,7 +680,7 @@ void del_tree(char *dir) do { /* create long name */ - snprintf(temp, PATH_MAX, "%s/%s", dir, parent.name); + snprintf(temp, FN_REFLEN, "%s/%s", dir, parent.name); if (parent.name[0] == '.') { /* Skip */ @@ -700,11 +715,11 @@ int removef(const char *format, ...) { #ifdef __NETWARE__ va_list ap; - char path[PATH_MAX]; + char path[FN_REFLEN]; va_start(ap, format); - vsnprintf(path, PATH_MAX, format, ap); + vsnprintf(path, FN_REFLEN, format, ap); va_end(ap); return remove(path); @@ -712,15 +727,15 @@ int removef(const char *format, ...) #eldef __WIN__ { va_list ap; - char path[PATH_MAX]; + char path[FN_REFLEN]; struct _finddata_t parent; intptr_t handle; - char temp[PATH_MAX]; + char temp[FN_REFLEN]; char *p; va_start(ap, format); - vsnprintf(path, PATH_MAX, format, ap); + vsnprintf(path, FN_REFLEN, format, ap); va_end(ap); @@ -739,7 +754,7 @@ int removef(const char *format, ...) { if (! (parent.attrib & _A_SUBDIR)) { - snprintf(temp, PATH_MAX, "%s/%s", path, parent.name); + snprintf(temp, FN_REFLEN, "%s/%s", path, parent.name); remove(temp); } }while (_findnext(handle,&parent) == 0); @@ -749,14 +764,14 @@ int removef(const char *format, ...) #else DIR *parent; struct dirent *entry; - char temp[PATH_MAX]; + char temp[FN_REFLEN]; va_list ap; - char path[PATH_MAX]; + char path[FN_REFLEN]; char *p; /* Get path with mask */ va_start(ap, format); - vsnprintf(path, PATH_MAX, format, ap); + vsnprintf(path, FN_REFLEN, format, ap); va_end(ap); @@ -775,10 +790,21 @@ int removef(const char *format, ...) while ((entry= readdir(parent)) != NULL) { /* entry is not directory and entry matches with mask */ +#ifndef STRUCT_DIRENT_HAS_D_TYPE + struct stat st; + + if (lstat(entry->d_name, &st) == -1) + { + return 1; + } + + if (!S_ISDIR(st.st_mode) && !fnmatch(p, entry->d_name,0)) +#else if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0)) +#endif { /* create long name */ - snprintf(temp, PATH_MAX, "%s/%s", path, entry->d_name); + snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name); /* Delete only files */ remove(temp); } @@ -795,7 +821,7 @@ int removef(const char *format, ...) void get_basedir(char *argv0, char *basedir) { - char temp[PATH_MAX]; + char temp[FN_REFLEN]; char *p; int position; diff --git a/mysql-test/my_manage.h b/mysql-test/my_manage.h index a61c693c22c..7e371d36ab1 100644 --- a/mysql-test/my_manage.h +++ b/mysql-test/my_manage.h @@ -52,8 +52,6 @@ int my_vsnprintf_(char *to, size_t n, const char* value, ...); #define TRY_MAX 5 #ifdef __WIN__ -#define PATH_MAX _MAX_PATH -#define NAME_MAX _MAX_FNAME #define kill(A,B) TerminateProcess((HANDLE)A,0) #define NOT_NEED_PID 0 #define MASTER_PID 1 diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 0d467e0a734..d273775725d 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -227,7 +227,7 @@ DO_CLIENT_GDB="" SLEEP_TIME_AFTER_RESTART=1 SLEEP_TIME_FOR_DELETE=10 SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables -SLEEP_TIME_FOR_SECOND_MASTER=30 +SLEEP_TIME_FOR_SECOND_MASTER=400 SLEEP_TIME_FOR_FIRST_SLAVE=400 SLEEP_TIME_FOR_SECOND_SLAVE=30 CHARACTER_SET=latin1 @@ -457,6 +457,9 @@ SMALL_SERVER="--key_buffer_size=1M --sort_buffer=256K --max_heap_table_size=1M" export MASTER_MYPORT MASTER_MYPORT1 SLAVE_MYPORT MYSQL_TCP_PORT MASTER_MYSOCK MASTER_MYSOCK1 +NDBCLUSTER_BASE_PORT=`expr $NDBCLUSTER_PORT + 2` +NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var" + if [ x$SOURCE_DIST = x1 ] ; then MY_BASEDIR=$MYSQL_TEST_DIR else @@ -941,11 +944,11 @@ start_ndbcluster() echo "Starting ndbcluster" if [ "$DO_BENCH" = 1 ] then - NDBCLUSTER_OPTS="" + NDBCLUSTER_EXTRA_OPTS="" else - NDBCLUSTER_OPTS="--small" + NDBCLUSTER_EXTRA_OPTS="--small" fi - ./ndb/ndbcluster --port-base=$NDBCLUSTER_PORT $NDBCLUSTER_OPTS --diskless --initial --data-dir=$MYSQL_TEST_DIR/var || exit 1 + ./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --diskless --initial || exit 1 NDB_CONNECTSTRING="host=localhost:$NDBCLUSTER_PORT" else NDB_CONNECTSTRING="$USE_RUNNING_NDBCLUSTER" @@ -963,7 +966,7 @@ stop_ndbcluster() if [ -z "$USE_RUNNING_NDBCLUSTER" ] then # Kill any running ndbcluster stuff - ./ndb/ndbcluster --data-dir=$MYSQL_TEST_DIR/var --port-base=$NDBCLUSTER_PORT --stop + ./ndb/ndbcluster $NDBCLUSTER_OPTS --stop fi fi } diff --git a/mysql-test/mysql_test_run_new.c b/mysql-test/mysql_test_run_new.c index 1e8a1dded51..d8bf731b398 100644 --- a/mysql-test/mysql_test_run_new.c +++ b/mysql-test/mysql_test_run_new.c @@ -73,25 +73,25 @@ const char *TEST_IGNORE= "[ignore]"; ******************************************************************************/ #ifdef __NETWARE__ -static char base_dir[PATH_MAX]= "sys:/mysql"; +static char base_dir[FN_REFLEN]= "sys:/mysql"; #else -static char base_dir[PATH_MAX]= ".."; +static char base_dir[FN_REFLEN]= ".."; #endif -static char db[PATH_MAX]= "test"; -static char user[PATH_MAX]= "root"; -static char password[PATH_MAX]= ""; +static char db[FN_LEN]= "test"; +static char user[FN_LEN]= "root"; +static char password[FN_LEN]= ""; int master_port= 9306; int slave_port= 9307; #if !defined(__NETWARE__) && !defined(__WIN__) -static char master_socket[PATH_MAX]= "./var/tmp/master.sock"; -static char slave_socket[PATH_MAX]= "./var/tmp/slave.sock"; +static char master_socket[FN_REFLEN]= "./var/tmp/master.sock"; +static char slave_socket[FN_REFLEN]= "./var/tmp/slave.sock"; #endif /* comma delimited list of tests to skip or empty string */ #ifndef __WIN__ -static char skip_test[PATH_MAX]= " lowercase_table3 , system_mysql_db_fix "; +static char skip_test[FN_REFLEN]= " lowercase_table3 , system_mysql_db_fix "; #else /* The most ignore testes contain the calls of system command @@ -110,7 +110,7 @@ static char skip_test[PATH_MAX]= " lowercase_table3 , system_mysql_db_fix "; mysqldump contains a command system rpl000001 makes non-exit loop...temporary skiped */ -static char skip_test[PATH_MAX]= +static char skip_test[FN_REFLEN]= " lowercase_table3 ," " system_mysql_db_fix ," " sp ," @@ -123,44 +123,44 @@ static char skip_test[PATH_MAX]= " mysqldump ," " rpl000001 "; #endif -static char ignore_test[PATH_MAX]= ""; - -static char bin_dir[PATH_MAX]; -static char mysql_test_dir[PATH_MAX]; -static char test_dir[PATH_MAX]; -static char mysql_tmp_dir[PATH_MAX]; -static char result_dir[PATH_MAX]; -static char master_dir[PATH_MAX]; -static char slave_dir[PATH_MAX]; -static char lang_dir[PATH_MAX]; -static char char_dir[PATH_MAX]; - -static char mysqladmin_file[PATH_MAX]; -static char mysqld_file[PATH_MAX]; -static char mysqltest_file[PATH_MAX]; +static char ignore_test[FN_REFLEN]= ""; + +static char bin_dir[FN_REFLEN]; +static char mysql_test_dir[FN_REFLEN]; +static char test_dir[FN_REFLEN]; +static char mysql_tmp_dir[FN_REFLEN]; +static char result_dir[FN_REFLEN]; +static char master_dir[FN_REFLEN]; +static char slave_dir[FN_REFLEN]; +static char lang_dir[FN_REFLEN]; +static char char_dir[FN_REFLEN]; + +static char mysqladmin_file[FN_REFLEN]; +static char mysqld_file[FN_REFLEN]; +static char mysqltest_file[FN_REFLEN]; #ifndef __WIN__ -static char master_pid[PATH_MAX]; -static char slave_pid[PATH_MAX]; -static char sh_file[PATH_MAX]= "/bin/sh"; +static char master_pid[FN_REFLEN]; +static char slave_pid[FN_REFLEN]; +static char sh_file[FN_REFLEN]= "/bin/sh"; #else static HANDLE master_pid; static HANDLE slave_pid; #endif -static char master_opt[PATH_MAX]= ""; -static char slave_opt[PATH_MAX]= ""; +static char master_opt[FN_REFLEN]= ""; +static char slave_opt[FN_REFLEN]= ""; -static char slave_master_info[PATH_MAX]= ""; +static char slave_master_info[FN_REFLEN]= ""; -static char master_init_script[PATH_MAX]= ""; -static char slave_init_script[PATH_MAX]= ""; +static char master_init_script[FN_REFLEN]= ""; +static char slave_init_script[FN_REFLEN]= ""; /* OpenSSL */ -static char ca_cert[PATH_MAX]; -static char server_cert[PATH_MAX]; -static char server_key[PATH_MAX]; -static char client_cert[PATH_MAX]; -static char client_key[PATH_MAX]; +static char ca_cert[FN_REFLEN]; +static char server_cert[FN_REFLEN]; +static char server_key[FN_REFLEN]; +static char client_cert[FN_REFLEN]; +static char client_key[FN_REFLEN]; int total_skip= 0; int total_pass= 0; @@ -254,18 +254,18 @@ void install_db(char *datadir) { arg_list_t al; int err; - char input[PATH_MAX]; - char output[PATH_MAX]; - char error[PATH_MAX]; + char input[FN_REFLEN]; + char output[FN_REFLEN]; + char error[FN_REFLEN]; /* input file */ #ifdef __NETWARE__ - snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir); + snprintf(input, FN_REFLEN, "%s/bin/init_db.sql", base_dir); #else - snprintf(input, PATH_MAX, "%s/mysql-test/init_db.sql", base_dir); + snprintf(input, FN_REFLEN, "%s/mysql-test/init_db.sql", base_dir); #endif - snprintf(output, PATH_MAX, "%s/install.out", datadir); - snprintf(error, PATH_MAX, "%s/install.err", datadir); + snprintf(output, FN_REFLEN, "%s/install.out", datadir); + snprintf(error, FN_REFLEN, "%s/install.err", datadir); /* args */ init_args(&al); @@ -302,10 +302,10 @@ void install_db(char *datadir) void mysql_install_db() { - char temp[PATH_MAX]; + char temp[FN_REFLEN]; /* var directory */ - snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var", mysql_test_dir); /* clean up old direcotry */ del_tree(temp); @@ -315,41 +315,41 @@ void mysql_install_db() mkdir(temp, S_IRWXU); /* create subdirectories */ mlog("Creating test-suite folders...\n"); - snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/run", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/tmp", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data/mysql", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data/test", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data/mysql", mysql_test_dir); mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data/test", mysql_test_dir); mkdir(temp, S_IRWXU); #else mkdir(temp); /* create subdirectories */ mlog("Creating test-suite folders...\n"); - snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/run", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/tmp", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data/mysql", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/master-data/test", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data/mysql", mysql_test_dir); mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/var/slave-data/test", mysql_test_dir); mkdir(temp); #endif @@ -372,10 +372,10 @@ void start_master() { arg_list_t al; int err; - char master_out[PATH_MAX]; - char master_err[PATH_MAX]; -/* char temp[PATH_MAX]; */ - char temp2[PATH_MAX]; + char master_out[FN_REFLEN]; + char master_err[FN_REFLEN]; +/* char temp[FN_REFLEN]; */ + char temp2[FN_REFLEN]; /* remove old berkeley db log files that can confuse the server */ removef("%s/log.*", master_dir); @@ -405,7 +405,7 @@ void start_master() FILE *fp; /* create an empty index file */ - snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir); + snprintf(temp, FN_REFLEN, "%s/test/t1.MYI", master_dir); fp= fopen(temp, "wb+"); fputs("1", fp); @@ -418,19 +418,19 @@ void start_master() } /* redirection files */ - snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out", + snprintf(master_out, FN_REFLEN, "%s/var/run/master%u.out", mysql_test_dir, restarts); - snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err", + snprintf(master_err, FN_REFLEN, "%s/var/run/master%u.err", mysql_test_dir, restarts); #ifndef __WIN__ - snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir); + snprintf(temp2,FN_REFLEN,"%s/var",mysql_test_dir); mkdir(temp2,S_IRWXU); - snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir); + snprintf(temp2,FN_REFLEN,"%s/var/log",mysql_test_dir); mkdir(temp2,S_IRWXU); #else - snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir); + snprintf(temp2,FN_REFLEN,"%s/var",mysql_test_dir); mkdir(temp2); - snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir); + snprintf(temp2,FN_REFLEN,"%s/var/log",mysql_test_dir); mkdir(temp2); #endif /* args */ @@ -539,8 +539,8 @@ void start_slave() { arg_list_t al; int err; - char slave_out[PATH_MAX]; - char slave_err[PATH_MAX]; + char slave_out[FN_REFLEN]; + char slave_err[FN_REFLEN]; /* skip? */ if (skip_slave) return; @@ -568,7 +568,7 @@ void start_slave() if (strinstr(slave_init_script, "rpl000016-slave.sh") != 0) { /* create empty master.info file */ - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); } else if (strinstr(slave_init_script, "rpl000017-slave.sh") != 0) @@ -576,7 +576,7 @@ void start_slave() FILE *fp; /* create a master.info file */ - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); fp= fopen(temp, "wb+"); fputs("master-bin.000001\n", fp); @@ -593,7 +593,7 @@ void start_slave() else if (strinstr(slave_init_script, "rpl_rotate_logs-slave.sh") != 0) { /* create empty master.info file */ - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); } #elif !defined(__WIN__) @@ -602,9 +602,9 @@ void start_slave() } /* redirection files */ - snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out", + snprintf(slave_out, FN_REFLEN, "%s/var/run/slave%u.out", mysql_test_dir, restarts); - snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err", + snprintf(slave_err, FN_REFLEN, "%s/var/run/slave%u.err", mysql_test_dir, restarts); /* args */ @@ -859,14 +859,14 @@ int read_option(char *opt_file, char *opt) { int fd, err; char *p; - char buf[PATH_MAX]; + char buf[FN_REFLEN]; /* copy current option */ - strncpy(buf, opt, PATH_MAX); + strncpy(buf, opt, FN_REFLEN); /* open options file */ fd= open(opt_file, O_RDONLY); - err= read(fd, opt, PATH_MAX); + err= read(fd, opt, FN_REFLEN); close(fd); if (err > 0) @@ -890,7 +890,7 @@ int read_option(char *opt_file, char *opt) /* check for $MYSQL_TEST_DIR */ if ((p= strstr(opt, "$MYSQL_TEST_DIR")) != NULL) { - char temp[PATH_MAX]; + char temp[FN_REFLEN]; *p= 0; @@ -925,7 +925,7 @@ int read_option(char *opt_file, char *opt) void run_test(char *test) { - char temp[PATH_MAX]; + char temp[FN_REFLEN]; const char *rstr; int skip= FALSE, ignore=FALSE; int restart= FALSE; @@ -933,13 +933,13 @@ void run_test(char *test) struct stat info; /* skip tests in the skip list */ - snprintf(temp, PATH_MAX, " %s ", test); + snprintf(temp, FN_REFLEN, " %s ", test); skip= (strinstr(skip_test, temp) != 0); if (skip == FALSE) ignore= (strinstr(ignore_test, temp) != 0); - snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test); - snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test); + snprintf(master_init_script, FN_REFLEN, "%s/%s-master.sh", test_dir, test); + snprintf(slave_init_script, FN_REFLEN, "%s/%s-slave.sh", test_dir, test); #ifdef __WIN__ if (! stat(master_init_script, &info)) skip= TRUE; @@ -957,14 +957,14 @@ void run_test(char *test) } else if (!skip) /* skip test? */ { - char test_file[PATH_MAX]; - char master_opt_file[PATH_MAX]; - char slave_opt_file[PATH_MAX]; - char slave_master_info_file[PATH_MAX]; - char result_file[PATH_MAX]; - char reject_file[PATH_MAX]; - char out_file[PATH_MAX]; - char err_file[PATH_MAX]; + char test_file[FN_REFLEN]; + char master_opt_file[FN_REFLEN]; + char slave_opt_file[FN_REFLEN]; + char slave_master_info_file[FN_REFLEN]; + char result_file[FN_REFLEN]; + char reject_file[FN_REFLEN]; + char out_file[FN_REFLEN]; + char err_file[FN_REFLEN]; int err; arg_list_t al; #ifdef __WIN__ @@ -981,20 +981,20 @@ void run_test(char *test) if (flag != skip_slave) restart= TRUE; /* create files */ - snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test); - snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test); - snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", + snprintf(master_opt_file, FN_REFLEN, "%s/%s-master.opt", test_dir, test); + snprintf(slave_opt_file, FN_REFLEN, "%s/%s-slave.opt", test_dir, test); + snprintf(slave_master_info_file, FN_REFLEN, "%s/%s.slave-mi", test_dir, test); - snprintf(reject_file, PATH_MAX, "%s/%s%s", + snprintf(reject_file, FN_REFLEN, "%s/%s%s", result_dir, test, REJECT_SUFFIX); - snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX); - snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX); + snprintf(out_file, FN_REFLEN, "%s/%s%s", result_dir, test, OUT_SUFFIX); + snprintf(err_file, FN_REFLEN, "%s/%s%s", result_dir, test, ERR_SUFFIX); /* netware specific files */ - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); + snprintf(test_file, FN_REFLEN, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); if (stat(test_file, &info)) { - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX); + snprintf(test_file, FN_REFLEN, "%s/%s%s", test_dir, test, TEST_SUFFIX); if (access(test_file,0)) { printf("Invalid test name %s, %s file not found\n",test,test_file); @@ -1002,11 +1002,11 @@ void run_test(char *test) } } - snprintf(result_file, PATH_MAX, "%s/%s%s", + snprintf(result_file, FN_REFLEN, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX); if (stat(result_file, &info)) { - snprintf(result_file, PATH_MAX, "%s/%s%s", + snprintf(result_file, FN_REFLEN, "%s/%s%s", result_dir, test, RESULT_SUFFIX); } @@ -1248,8 +1248,8 @@ void die(const char *msg) void setup(char *file __attribute__((unused))) { - char temp[PATH_MAX]; - char file_path[PATH_MAX*2]; + char temp[FN_REFLEN]; + char file_path[FN_REFLEN*2]; char *p; int position; @@ -1257,14 +1257,14 @@ void setup(char *file __attribute__((unused))) #ifdef __WIN__ _putenv( "TZ=GMT-3" ); #else - setenv("TZ", "GMT-3", TRUE); + putenv((char *)"TZ=GMT-3"); #endif /* find base dir */ #ifdef __NETWARE__ strcpy(temp, strlwr(file)); while ((p= strchr(temp, '\\')) != NULL) *p= '/'; #else - getcwd(temp, PATH_MAX); + getcwd(temp, FN_REFLEN); position= strlen(temp); temp[position]= '/'; temp[position+1]= 0; @@ -1284,100 +1284,100 @@ void setup(char *file __attribute__((unused))) #ifdef __NETWARE__ /* setup paths */ - snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir); - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); + snprintf(bin_dir, FN_REFLEN, "%s/bin", base_dir); + snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); + snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); + snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); + snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); + snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); + snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); + snprintf(lang_dir, FN_REFLEN, "%s/share/english", base_dir); + snprintf(char_dir, FN_REFLEN, "%s/share/charsets", base_dir); #ifdef HAVE_OPENSSL use_openssl= TRUE; #endif /* HAVE_OPENSSL */ /* OpenSSL paths */ - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); + snprintf(ca_cert, FN_REFLEN, "%s/SSL/cacert.pem", base_dir); + snprintf(server_cert, FN_REFLEN, "%s/SSL/server-cert.pem", base_dir); + snprintf(server_key, FN_REFLEN, "%s/SSL/server-key.pem", base_dir); + snprintf(client_cert, FN_REFLEN, "%s/SSL/client-cert.pem", base_dir); + snprintf(client_key, FN_REFLEN, "%s/SSL/client-key.pem", base_dir); /* setup files */ - snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); + snprintf(mysqld_file, FN_REFLEN, "%s/mysqld", bin_dir); + snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest", bin_dir); + snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin", bin_dir); + snprintf(master_pid, FN_REFLEN, "%s/var/run/master.pid", mysql_test_dir); + snprintf(slave_pid, FN_REFLEN, "%s/var/run/slave.pid", mysql_test_dir); #elif __WIN__ /* setup paths */ #ifdef _DEBUG - snprintf(bin_dir, PATH_MAX, "%s/client_debug", base_dir); + snprintf(bin_dir, FN_REFLEN, "%s/client_debug", base_dir); #else - snprintf(bin_dir, PATH_MAX, "%s/client_release", base_dir); + snprintf(bin_dir, FN_REFLEN, "%s/client_release", base_dir); #endif - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); + snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); + snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); + snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); + snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); + snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); + snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); + snprintf(lang_dir, FN_REFLEN, "%s/share/english", base_dir); + snprintf(char_dir, FN_REFLEN, "%s/share/charsets", base_dir); #ifdef HAVE_OPENSSL use_openssl= TRUE; #endif /* HAVE_OPENSSL */ /* OpenSSL paths */ - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); + snprintf(ca_cert, FN_REFLEN, "%s/SSL/cacert.pem", base_dir); + snprintf(server_cert, FN_REFLEN, "%s/SSL/server-cert.pem", base_dir); + snprintf(server_key, FN_REFLEN, "%s/SSL/server-key.pem", base_dir); + snprintf(client_cert, FN_REFLEN, "%s/SSL/client-cert.pem", base_dir); + snprintf(client_key, FN_REFLEN, "%s/SSL/client-key.pem", base_dir); /* setup files */ - snprintf(mysqld_file, PATH_MAX, "%s/mysqld.exe", bin_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest.exe", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin.exe", bin_dir); + snprintf(mysqld_file, FN_REFLEN, "%s/mysqld.exe", bin_dir); + snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest.exe", bin_dir); + snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin.exe", bin_dir); #else /* setup paths */ - snprintf(bin_dir, PATH_MAX, "%s/client", base_dir); - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/sql/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/sql/share/charsets", base_dir); + snprintf(bin_dir, FN_REFLEN, "%s/client", base_dir); + snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); + snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); + snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); + snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); + snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); + snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); + snprintf(lang_dir, FN_REFLEN, "%s/sql/share/english", base_dir); + snprintf(char_dir, FN_REFLEN, "%s/sql/share/charsets", base_dir); #ifdef HAVE_OPENSSL use_openssl= TRUE; #endif /* HAVE_OPENSSL */ /* OpenSSL paths */ - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); + snprintf(ca_cert, FN_REFLEN, "%s/SSL/cacert.pem", base_dir); + snprintf(server_cert, FN_REFLEN, "%s/SSL/server-cert.pem", base_dir); + snprintf(server_key, FN_REFLEN, "%s/SSL/server-key.pem", base_dir); + snprintf(client_cert, FN_REFLEN, "%s/SSL/client-cert.pem", base_dir); + snprintf(client_key, FN_REFLEN, "%s/SSL/client-key.pem", base_dir); /* setup files */ - snprintf(mysqld_file, PATH_MAX, "%s/sql/mysqld", base_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); + snprintf(mysqld_file, FN_REFLEN, "%s/sql/mysqld", base_dir); + snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest", bin_dir); + snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin", bin_dir); + snprintf(master_pid, FN_REFLEN, "%s/var/run/master.pid", mysql_test_dir); + snprintf(slave_pid, FN_REFLEN, "%s/var/run/slave.pid", mysql_test_dir); - snprintf(master_socket,PATH_MAX, "%s/var/tmp/master.sock", mysql_test_dir); - snprintf(slave_socket,PATH_MAX, "%s/var/tmp/slave.sock", mysql_test_dir); + snprintf(master_socket,FN_REFLEN, "%s/var/tmp/master.sock", mysql_test_dir); + snprintf(slave_socket,FN_REFLEN, "%s/var/tmp/slave.sock", mysql_test_dir); #endif /* create log file */ - snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir); + snprintf(temp, FN_REFLEN, "%s/mysql-test-run.log", mysql_test_dir); if ((log_fd= fopen(temp, "w+")) == NULL) { log_errno("Unable to create log file."); @@ -1386,46 +1386,47 @@ void setup(char *file __attribute__((unused))) /* prepare skip test list */ while ((p= strchr(skip_test, ',')) != NULL) *p= ' '; strcpy(temp, strlwr(skip_test)); - snprintf(skip_test, PATH_MAX, " %s ", temp); + snprintf(skip_test, FN_REFLEN, " %s ", temp); /* environment */ #ifdef __NETWARE__ setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); - snprintf(file_path, PATH_MAX*2, + snprintf(file_path, FN_REFLEN*2, "%s/client/mysqldump --no-defaults -u root --port=%u", bin_dir, master_port); setenv("MYSQL_DUMP", file_path, 1); - snprintf(file_path, PATH_MAX*2, + snprintf(file_path, FN_REFLEN*2, "%s/client/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); setenv("MYSQL_BINLOG", file_path, 1); #elif __WIN__ - snprintf(file_path,MAX_PATH,"MYSQL_TEST_DIR=%s",mysql_test_dir); + snprintf(file_path,FN_REFLEN,"MYSQL_TEST_DIR=%s",mysql_test_dir); _putenv(file_path); - snprintf(file_path, PATH_MAX*2, + snprintf(file_path, FN_REFLEN*2, "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -u root --port=%u", bin_dir, master_port); _putenv(file_path); - snprintf(file_path, PATH_MAX*2, + snprintf(file_path, FN_REFLEN*2, "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); _putenv(file_path); #else - setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); - snprintf(file_path, PATH_MAX*2, - "%s/mysqldump --no-defaults -u root --port=%u --socket=%s", + snprintf(file_path,FN_REFLEN,"MYSQL_TEST_DIR=%s",mysql_test_dir); + putenv(file_path); + snprintf(file_path, FN_REFLEN*2, + "MYSQL_DUMP=%s/mysqldump --no-defaults -u root --port=%u --socket=%s", bin_dir, master_port, master_socket); - setenv("MYSQL_DUMP", file_path, 1); - snprintf(file_path, PATH_MAX*2, - "%s/mysqlbinlog --no-defaults --local-load=%s", + putenv(file_path); + snprintf(file_path, FN_REFLEN*2, + "MYSQL_BINLOG=%s/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); - setenv("MYSQL_BINLOG", file_path, 1); + putenv(file_path); #endif #ifndef __WIN__ - setenv("MASTER_MYPORT", "9306", 1); - setenv("SLAVE_MYPORT", "9307", 1); - setenv("MYSQL_TCP_PORT", "3306", 1); + putenv((char *)"MASTER_MYPORT=9306"); + putenv((char *)"SLAVE_MYPORT=9307"); + putenv((char *)"MYSQL_TCP_PORT=3306"); #else _putenv("MASTER_MYPORT=9306"); _putenv("SLAVE_MYPORT=9307"); @@ -1461,7 +1462,7 @@ int main(int argc, char **argv) temp= strdup(strchr(argv[1],'=') + 1); for (token=str_tok(temp, ","); token != NULL; token=str_tok(NULL, ",")) { - if (strlen(ignore_test) + strlen(token) + 2 <= PATH_MAX-1) + if (strlen(ignore_test) + strlen(token) + 2 <= FN_REFLEN-1) sprintf(ignore_test+strlen(ignore_test), " %s ", token); else { @@ -1507,38 +1508,35 @@ int main(int argc, char **argv) { /* run all tests */ #ifndef __WIN__ - struct dirent **namelist; - int i,n; - char test[NAME_MAX]; - char *p; + struct dirent *entry; + DIR *parent; + char test[FN_LEN]; int position; - n= scandir(test_dir, &namelist, 0, alphasort); - if (n < 0) + /* FIXME are we sure the list is sorted if using readdir()? */ + if ((parent= opendir(test_dir)) == NULL) /* Not thread safe */ die("Unable to open tests directory."); else { - for (i= 0; i < n; i++) + while ((entry= readdir(parent)) != NULL) /* Not thread safe */ { - strcpy(test, strlwr(namelist[i]->d_name)); + strcpy(test, strlwr(entry->d_name)); /* find the test suffix */ if ((position= strinstr(test, TEST_SUFFIX)) != 0) { - p= test + position - 1; /* null terminate at the suffix */ - *p= 0; + *(test + position - 1)= '\0'; /* run test */ run_test(test); } - free(namelist[n]); } - free(namelist); + closedir(parent); } #else struct _finddata_t dir; intptr_t handle; - char test[NAME_MAX]; - char mask[PATH_MAX]; + char test[FN_LEN]; + char mask[FN_REFLEN]; char *p; int position; char **names= 0; @@ -1549,7 +1547,7 @@ int main(int argc, char **argv) /* single test */ single_test= FALSE; - snprintf(mask,MAX_PATH,"%s/*.test",test_dir); + snprintf(mask,FN_REFLEN,"%s/*.test",test_dir); if ((handle=_findfirst(mask,&dir)) == -1L) { @@ -1574,7 +1572,7 @@ int main(int argc, char **argv) *p= 0; /* insert test */ - *names= malloc(PATH_MAX); + *names= malloc(FN_REFLEN); strcpy(*names,test); names++; name_index++; diff --git a/mysql-test/ndb/Makefile.am b/mysql-test/ndb/Makefile.am index 3ed222344a6..502ccee099e 100644 --- a/mysql-test/ndb/Makefile.am +++ b/mysql-test/ndb/Makefile.am @@ -13,6 +13,8 @@ SUFFIXES = .sh .sh: @RM@ -f $@ $@-t @SED@ \ + -e 's!@''ndb_port''@!$(ndb_port)!g' \ + -e 's!@''ndb_port_base''@!$(ndb_port_base)!g' \ -e 's!@''ndbbindir''@!$(ndbbindir)!g' \ -e 's!@''ndbtoolsdir''@!$(ndbtoolsdir)!g' \ $< > $@-t diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh index 9c6b6093b93..60188705857 100644 --- a/mysql-test/ndb/ndbcluster.sh +++ b/mysql-test/ndb/ndbcluster.sh @@ -5,7 +5,8 @@ # This scripts starts the table handler ndbcluster # configurable parameters, make sure to change in mysqlcluterd as well -port_base="2200" +port=@ndb_port@ +port_base=@ndb_port_base@ fsdir=`pwd` # end configurable parameters @@ -22,6 +23,7 @@ if [ -d ../sql ] ; then exec_ndb=$ndbtop/src/kernel/ndbd exec_mgmtsrvr=$ndbtop/src/mgmsrv/ndb_mgmd exec_waiter=$ndbtop/tools/ndb_waiter + exec_test=$ndbtop/tools/ndb_test_platform exec_mgmtclient=$ndbtop/src/mgmclient/ndb_mgm else BINARY_DIST=1 @@ -34,9 +36,15 @@ else exec_mgmtsrvr=$BASEDIR/bin/ndb_mgmd fi exec_waiter=$BASEDIR/bin/ndb_waiter + exec_test=$BASEDIR/bin/ndb_test_platform exec_mgmtclient=$BASEDIR/bin/ndb_mgm fi +if $exec_test ; then :; else + echo "ndb not correctly compiled to support this platform" + exit 1 +fi + pidfile=ndbcluster.pid cfgfile=Ndb.cfg stop_ndb= @@ -77,6 +85,9 @@ while test $# -gt 0; do --data-dir=*) fsdir=`echo "$1" | sed -e "s;--data-dir=;;"` ;; + --port=*) + port=`echo "$1" | sed -e "s;--port=;;"` + ;; --port-base=*) port_base=`echo "$1" | sed -e "s;--port-base=;;"` ;; @@ -87,7 +98,7 @@ while test $# -gt 0; do shift done -fs_ndb="$fsdir/ndbcluster-$port_base" +fs_ndb="$fsdir/ndbcluster-$port" NDB_HOME= if [ ! -x "$fsdir" ]; then @@ -113,7 +124,7 @@ exec_ndb="$exec_ndb --no-defaults" exec_waiter="$exec_waiter --no-defaults" ndb_host="localhost" -ndb_mgmd_port=$port_base +ndb_mgmd_port=$port NDB_CONNECTSTRING="host=$ndb_host:$ndb_mgmd_port" export NDB_CONNECTSTRING @@ -151,10 +162,6 @@ if [ -d "$fs_ndb" ]; then :; else exit 1 fi -# set som help variables - -port_transporter=`expr $ndb_mgmd_port + 2` - # Start management server as deamon # Edit file system path and ports in config file @@ -169,7 +176,7 @@ sed \ -e s,"CHOOSE_HOSTNAME_".*,"$ndb_host",g \ -e s,"CHOOSE_FILESYSTEM","$fs_ndb",g \ -e s,"CHOOSE_PORT_MGM","$ndb_mgmd_port",g \ - -e s,"CHOOSE_PORT_TRANSPORTER","$port_transporter",g \ + -e s,"CHOOSE_PORT_TRANSPORTER","$port_base",g \ < ndb/ndb_config_2_node.ini \ > "$fs_ndb/config.ini" fi diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index f26ca4a5425..e0d484312e7 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -483,3 +483,13 @@ ERROR 42000: Incorrect table name 't1\\' rename table t1 to `t1\\`; ERROR 42000: Incorrect table name 't1\\' drop table t1; +create table t1 (a text) character set koi8r; +insert into t1 values (_koi8r'ÔÅÓÔ'); +select hex(a) from t1; +hex(a) +D4C5D3D4 +alter table t1 convert to character set cp1251; +select hex(a) from t1; +hex(a) +F2E5F1F2 +drop table t1; diff --git a/mysql-test/r/consistent_snapshot.result b/mysql-test/r/consistent_snapshot.result new file mode 100644 index 00000000000..90606abbe4e --- /dev/null +++ b/mysql-test/r/consistent_snapshot.result @@ -0,0 +1,15 @@ +drop table if exists t1; +create table t1 (a int) engine=innodb; +start transaction with consistent snapshot; +insert into t1 values(1); +select * from t1; +a +commit; +delete from t1; +start transaction; +insert into t1 values(1); +select * from t1; +a +1 +commit; +drop table t1; diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index 7c3ae52cbc9..d02ac0062f8 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -126,3 +126,43 @@ Field Type Null Key Default Extra a char(1) b enum('¤¢','¤¤') YES NULL DROP TABLE t1; +CREATE TABLE t1 +( +a INTEGER NOT NULL, +b VARCHAR(50) NOT NULL DEFAULT '', +PRIMARY KEY (a), +KEY b (b(10)) +) TYPE=InnoDB CHARACTER SET 'ujis' COLLATE 'ujis_japanese_ci'; +INSERT INTO t1 (a, b) VALUES (0, 'aaabbbcccddd'); +INSERT INTO t1 (a, b) VALUES (1, 'eeefffggghhh'); +INSERT INTO t1 (a, b) VALUES (2, 'iiijjjkkkl'); +SELECT t1.* FROM t1 WHERE b='aaabbbcccddd' ORDER BY a; +a b +0 aaabbbcccddd +SELECT t1.* FROM t1 WHERE b='eeefffggghhh' ORDER BY a; +a b +1 eeefffggghhh +SELECT t1.* FROM t1 WHERE b='iiijjjkkkl' ORDER BY a; +a b +2 iiijjjkkkl +DROP TABLE t1; +CREATE TABLE t1 +( +a INTEGER NOT NULL, +b VARCHAR(50) NOT NULL DEFAULT '', +PRIMARY KEY (a), +KEY b (b(10)) +) TYPE=MyISAM CHARACTER SET 'ujis' COLLATE 'ujis_japanese_ci'; +INSERT INTO t1 (a, b) VALUES (0, 'aaabbbcccddd'); +INSERT INTO t1 (a, b) VALUES (1, 'eeefffggghhh'); +INSERT INTO t1 (a, b) VALUES (2, 'iiijjjkkkl'); +SELECT t1.* FROM t1 WHERE b='aaabbbcccddd' ORDER BY a; +a b +0 aaabbbcccddd +SELECT t1.* FROM t1 WHERE b='eeefffggghhh' ORDER BY a; +a b +1 eeefffggghhh +SELECT t1.* FROM t1 WHERE b='iiijjjkkkl' ORDER BY a; +a b +2 iiijjjkkkl +DROP TABLE t1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 1f07ba0484f..98d9c332ab3 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -201,6 +201,9 @@ hex(unhex("1")) hex(unhex("12")) hex(unhex("123")) hex(unhex("1234")) hex(unhex( select length(unhex(md5("abrakadabra"))); length(unhex(md5("abrakadabra"))) 16 +select concat('a', quote(NULL)); +concat('a', quote(NULL)) +aNULL select reverse(""); reverse("") @@ -312,7 +315,7 @@ insert into t1 values ('one'),(NULL),('two'),('four'); select a, quote(a), isnull(quote(a)), quote(a) is null, ifnull(quote(a), 'n') from t1; a quote(a) isnull(quote(a)) quote(a) is null ifnull(quote(a), 'n') one 'one' 0 0 'one' -NULL NULL 1 1 n +NULL NULL 0 0 NULL two 'two' 0 0 'two' four 'four' 0 0 'four' drop table t1; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index d5b4aea81f6..1ac6165e383 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -134,6 +134,31 @@ ERROR HY000: Incorrect usage of DB GRANT and GLOBAL PRIVILEGES select 1; 1 1 +insert into mysql.user (host, user) values ('localhost', 'test11'); +insert into mysql.db (host, db, user, select_priv) values +('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); +alter table mysql.db order by db asc; +flush privileges; +show grants for test11@localhost; +Grants for test11@localhost +GRANT USAGE ON *.* TO 'test11'@'localhost' +GRANT SELECT ON `ab%`.* TO 'test11'@'localhost' +GRANT SELECT ON `a%`.* TO 'test11'@'localhost' +alter table mysql.db order by db desc; +flush privileges; +show grants for test11@localhost; +Grants for test11@localhost +GRANT USAGE ON *.* TO 'test11'@'localhost' +GRANT SELECT ON `ab%`.* TO 'test11'@'localhost' +GRANT SELECT ON `a%`.* TO 'test11'@'localhost' +delete from mysql.user where user='test11'; +delete from mysql.db where user='test11'; +create database mysqltest1; +grant usage on mysqltest1.* to test6123 identified by 'magic123'; +select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1"; +host db user select_priv insert_priv +delete from mysql.user where user='test6123'; +drop database mysqltest1; create table t1 (a int); grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION; show grants for drop_user2@localhost; @@ -229,25 +254,6 @@ GRANT SELECT (ËÏÌ) ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost' REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁ FROM ÀÚÅÒ@localhost; DROP DATABASE ÂÄ; SET NAMES latin1; -insert into mysql.user (host, user) values ('localhost', 'test11'); -insert into mysql.db (host, db, user, select_priv) values -('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); -alter table mysql.db order by db asc; -flush privileges; -show grants for test11@localhost; -Grants for test11@localhost -GRANT USAGE ON *.* TO 'test11'@'localhost' -GRANT SELECT ON `ab%`.* TO 'test11'@'localhost' -GRANT SELECT ON `a%`.* TO 'test11'@'localhost' -alter table mysql.db order by db desc; -flush privileges; -show grants for test11@localhost; -Grants for test11@localhost -GRANT USAGE ON *.* TO 'test11'@'localhost' -GRANT SELECT ON `ab%`.* TO 'test11'@'localhost' -GRANT SELECT ON `a%`.* TO 'test11'@'localhost' -delete from mysql.user where user='test11'; -delete from mysql.db where user='test11'; USE test; CREATE TABLE t1 (a int ); CREATE TABLE t2 LIKE t1; diff --git a/mysql-test/r/have_moscow_leap_timezone.require b/mysql-test/r/have_moscow_leap_timezone.require new file mode 100644 index 00000000000..f27452d7770 --- /dev/null +++ b/mysql-test/r/have_moscow_leap_timezone.require @@ -0,0 +1,2 @@ +from_unixtime(1072904422) +2004-01-01 00:00:00 diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 2e94974e953..86c9adf8cf6 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2; +drop table if exists t1,t2,t3; create table t1 (a int); select count(a) as b from t1 where a=0 having b > 0; b @@ -128,3 +128,203 @@ id description c 1 test 0 2 test2 0 drop table t1,t2,t3; +create table t1 (col1 int, col2 varchar(5), col_t1 int); +create table t2 (col1 int, col2 varchar(5), col_t2 int); +create table t3 (col1 int, col2 varchar(5), col_t3 int); +insert into t1 values(10,'hello',10); +insert into t1 values(20,'hello',20); +insert into t1 values(30,'hello',30); +insert into t1 values(10,'bye',10); +insert into t1 values(10,'sam',10); +insert into t1 values(10,'bob',10); +insert into t2 select * from t1; +insert into t3 select * from t1; +select count(*) from t1 group by col1 having col1 = 10; +count(*) +4 +select count(*) as count_col1 from t1 group by col1 having col1 = 10; +count_col1 +4 +select count(*) as count_col1 from t1 as tmp1 group by col1 having col1 = 10; +count_col1 +4 +select count(*) from t1 group by col2 having col2 = 'hello'; +count(*) +3 +select count(*) from t1 group by col2 having col1 = 10; +ERROR 42S22: Unknown column 'col1' in 'having clause' +select col1 as count_col1 from t1 as tmp1 group by col1 having col1 = 10; +count_col1 +10 +select col1 as count_col1 from t1 as tmp1 group by col1 having count_col1 = 10; +count_col1 +10 +select col1 as count_col1 from t1 as tmp1 group by count_col1 having col1 = 10; +count_col1 +10 +select col1 as count_col1 from t1 as tmp1 group by count_col1 having count_col1 = 10; +count_col1 +10 +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having col1 = 10; +count_col1 col2 +10 bob +10 bye +10 hello +10 sam +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having count_col1 = 10; +count_col1 col2 +10 bob +10 bye +10 hello +10 sam +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having col2 = 'hello'; +count_col1 col2 +10 hello +20 hello +30 hello +select col1 as count_col1,col2 as group_col2 from t1 as tmp1 group by col1,col2 having group_col2 = 'hello'; +count_col1 group_col2 +10 hello +20 hello +30 hello +select sum(col1) as co12 from t1 group by col2 having col2 10; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '10' at line 1 +select sum(col1) as co2, count(col2) as cc from t1 group by col1 having col1 =10; +co2 cc +40 4 +select t2.col2 from t2 group by t2.col1, t2.col2 having t1.col1 <= 10; +ERROR 42S22: Unknown column 't1.col1' in 'having clause' +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having t2.col1 <= 10); +col1 +10 +20 +30 +10 +10 +10 +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 +having t2.col1 <= +(select min(t3.col1) from t3)); +col1 +10 +20 +30 +10 +10 +10 +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having t1.col1 <= 10); +col1 +10 +10 +10 +10 +select t1.col1 as tmp_col from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having tmp_col <= 10); +tmp_col +10 +10 +10 +10 +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having col_t1 <= 10); +col1 +10 +10 +10 +10 +select sum(col1) from t1 +group by col_t1 +having (select col_t1 from t2 where col_t1 = col_t2 order by col_t2 limit 1); +sum(col1) +40 +20 +30 +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having col_t1 <= 10) +having col_t1 <= 20; +ERROR 42S22: Unknown column 'col_t1' in 'having clause' +select t1.col1 from t1 +where t1.col2 in +(select t2.col2 from t2 +group by t2.col1, t2.col2 having col_t1 <= 10) +group by col_t1 +having col_t1 <= 20; +col1 +10 +select col_t1, sum(col1) from t1 +group by col_t1 +having col_t1 > 10 and +exists (select sum(t2.col1) from t2 +group by t2.col2 having t2.col2 > 'b'); +col_t1 sum(col1) +20 20 +30 30 +select sum(col1) from t1 +group by col_t1 +having col_t1 in (select sum(t2.col1) from t2 +group by t2.col2, t2.col1 having t2.col1 = t1.col1); +ERROR 42S22: Unknown column 't1.col1' in 'having clause' +select sum(col1) from t1 +group by col_t1 +having col_t1 in (select sum(t2.col1) from t2 +group by t2.col2, t2.col1 having t2.col1 = col_t1); +sum(col1) +40 +20 +30 +select t1.col1, t2.col1 from t1, t2 where t1.col1 = t2.col1 +group by t1.col1, t2.col1 having col1 = 2; +ERROR 23000: Column 'col1' in having clause is ambiguous +select t1.col1*10+t2.col1 from t1,t2 where t1.col1=t2.col1 +group by t1.col1, t2.col1 having col1 = 2; +ERROR 23000: Column 'col1' in having clause is ambiguous +drop table t1, t2, t3; +create table t1 (s1 int); +insert into t1 values (1),(2),(3); +select count(*) from t1 group by s1 having s1 is null; +count(*) +select s1*0 as s1 from t1 group by s1 having s1 <> 0; +s1 +0 +0 +0 +Warnings: +Warning 1052 Column 's1' in having clause is ambiguous +select s1*0 from t1 group by s1 having s1 = 0; +s1*0 +select s1 from t1 group by 1 having 1 = 0; +s1 +select count(s1) from t1 group by s1 having count(1+1)=2; +count(s1) +select count(s1) from t1 group by s1 having s1*0=0; +count(s1) +1 +1 +1 +select * from t1 a, t1 b group by a.s1 having s1 is null; +ERROR 23000: Column 's1' in having clause is ambiguous +drop table t1; +create table t1 (s1 char character set latin1 collate latin1_german1_ci); +insert into t1 values ('ü'),('y'); +Warnings: +Warning 1265 Data truncated for column 's1' at row 1 +select s1,count(s1) from t1 +group by s1 collate latin1_swedish_ci having s1 = 'y'; +s1 count(s1) +y 1 +drop table t1; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result new file mode 100644 index 00000000000..3c35c6d557d --- /dev/null +++ b/mysql-test/r/information_schema.result @@ -0,0 +1,441 @@ +grant all privileges on test.* to mysqltest_1@localhost; +select * from information_schema.SCHEMATA where schema_name > 'm'; +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME +NULL mysql latin1 +NULL test latin1 +select schema_name from information_schema.schemata; +schema_name +mysql +test +show databases *; +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME +NULL mysql latin1 +NULL test latin1 +show databases like 't%'; +Database (t%) +test +show databases; +Database +mysql +test +show databases * where schema_name like 't%'; +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME +NULL test latin1 +show databases * where schema_name = 't%'; +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME +create database testtets; +create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b)); +create table test.t2(a int); +create table t3(a int, KEY a_data (a)); +create table testtets.t4(a int); +create view v1 (c) as select table_name from information_schema.TABLES; +select * from v1; +c +columns_priv +db +func +help_category +help_keyword +help_relation +help_topic +host +proc +tables_priv +time_zone +time_zone_leap_second +time_zone_name +time_zone_transition +time_zone_transition_type +user +t2 +t3 +v1 +t1 +t4 +select c,table_name from v1 +left join information_schema.TABLES v2 on (v1.c=v2.table_name) +where v1.c like "t%"; +c table_name +tables_priv tables_priv +time_zone time_zone +time_zone_leap_second time_zone_leap_second +time_zone_name time_zone_name +time_zone_transition time_zone_transition +time_zone_transition_type time_zone_transition_type +t2 t2 +t3 t3 +t1 t1 +t4 t4 +select c, v2.table_name from v1 +right join information_schema.TABLES v2 on (v1.c=v2.table_name) +where v1.c like "t%"; +c table_name +tables_priv tables_priv +time_zone time_zone +time_zone_leap_second time_zone_leap_second +time_zone_name time_zone_name +time_zone_transition time_zone_transition +time_zone_transition_type time_zone_transition_type +t2 t2 +t3 t3 +t1 t1 +t4 t4 +select table_name from information_schema.TABLES +where table_schema = "testtets" and table_name like "t%"; +table_name +t1 +t4 +select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT +NULL testtets t1 1 testtets string_data 1 b A NULL NULL NULL YES BTREE +show keys * where TABLE_SCHEMA Like "test%"; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT +NULL test t3 1 test a_data 1 a A NULL NULL NULL YES BTREE +NULL testtets t1 1 testtets string_data 1 b A NULL NULL NULL YES BTREE +show keys where INDEX_NAME = "a_data"; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t3 1 a_data 1 a A NULL NULL NULL YES BTREE +show tables like 't%'; +Tables_in_test (t%) +t2 +t3 +show tables * from test where table_name like 't%'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE +NULL test t2 +NULL test t3 +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t2 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +t3 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +show full columns from t3 like "a%"; +Field Type Collation Null Key Default Extra Privileges Comment +a int(11) NULL YES MUL NULL select,insert,update,references +show full columns from mysql.db like "Insert%"; +Field Type Collation Null Key Default Extra Privileges Comment +Insert_priv enum('N','Y') utf8_bin N select,insert,update,references +show full columns from v1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(64) latin1_swedish_ci select,insert,update,references +select * from information_schema.COLUMNS where table_name="t1" +and column_name= "a"; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME TYPE COLLATION_NAME IS_NULLABLE KEY COLUMN_DEFAULT EXTRA PRIVILEGES COMMENT +NULL testtets t1 a 1 int 0 11 4 0 NULL int(11) NULL YES NULL select,insert,update,references +show columns * where table_name = "t1"; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME TYPE COLLATION_NAME IS_NULLABLE KEY COLUMN_DEFAULT EXTRA PRIVILEGES COMMENT +NULL testtets t1 a 1 int 0 11 4 0 NULL int(11) NULL YES NULL +NULL testtets t1 b 2 varchar 30 30 30 31 latin1 varchar(30) latin1_swedish_ci YES MUL NULL +drop view v1; +drop tables testtets.t4, testtets.t1, t2, t3; +drop database testtets; +select * from information_schema.CHARACTER_SETS +where CHARACTER_SET_NAME like 'latin1%'; +CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +latin1 ISO 8859-1 West European latin1_swedish_ci 1 +SHOW CHARACTER SET LIKE 'latin1%'; +Charset Description Default collation Maxlen +latin1 ISO 8859-1 West European latin1_swedish_ci 1 +SHOW CHARACTER SET * LIKE 'latin1%'; +CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +latin1 ISO 8859-1 West European latin1_swedish_ci 1 +SHOW CHARACTER SET WHERE CHARACTER_SET_NAME like 'latin1%'; +Charset Description Default collation Maxlen +latin1 ISO 8859-1 West European latin1_swedish_ci 1 +SHOW CHARACTER SET CHARACTER_SET_NAME WHERE CHARACTER_SET_NAME like 'latin1%'; +CHARACTER_SET_NAME +latin1 +SHOW CHARACTER SET * WHERE CHARACTER_SET_NAME like 'latin1%'; +CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +latin1 ISO 8859-1 West European latin1_swedish_ci 1 +select * from information_schema.COLLATIONS +where COLLATION_NAME like 'latin1%'; +COLLATION_NAME Charset Id Default Compiled Sortlen +latin1_german1_ci latin1 5 0 +latin1_swedish_ci latin1 8 Yes Yes 1 +latin1_danish_ci latin1 15 0 +latin1_german2_ci latin1 31 Yes 2 +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 0 +latin1_general_cs latin1 49 0 +latin1_spanish_ci latin1 94 0 +SHOW COLLATION LIKE 'latin1%'; +Collation Charset Id Default Compiled Sortlen +latin1_german1_ci latin1 5 0 +latin1_swedish_ci latin1 8 Yes Yes 1 +latin1_danish_ci latin1 15 0 +latin1_german2_ci latin1 31 Yes 2 +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 0 +latin1_general_cs latin1 49 0 +latin1_spanish_ci latin1 94 0 +SHOW COLLATION * LIKE 'latin1%'; +COLLATION_NAME Charset Id Default Compiled Sortlen +latin1_german1_ci latin1 5 0 +latin1_swedish_ci latin1 8 Yes Yes 1 +latin1_danish_ci latin1 15 0 +latin1_german2_ci latin1 31 Yes 2 +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 0 +latin1_general_cs latin1 49 0 +latin1_spanish_ci latin1 94 0 +SHOW COLLATION WHERE COLLATION_NAME like 'latin1%'; +Collation Charset Id Default Compiled Sortlen +latin1_german1_ci latin1 5 0 +latin1_swedish_ci latin1 8 Yes Yes 1 +latin1_danish_ci latin1 15 0 +latin1_german2_ci latin1 31 Yes 2 +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 0 +latin1_general_cs latin1 49 0 +latin1_spanish_ci latin1 94 0 +SHOW COLLATION COLLATION_NAME WHERE COLLATION_NAME like 'latin1%'; +COLLATION_NAME +latin1_german1_ci +latin1_swedish_ci +latin1_danish_ci +latin1_german2_ci +latin1_bin +latin1_general_ci +latin1_general_cs +latin1_spanish_ci +SHOW COLLATION * WHERE COLLATION_NAME like 'latin1%'; +COLLATION_NAME Charset Id Default Compiled Sortlen +latin1_german1_ci latin1 5 0 +latin1_swedish_ci latin1 8 Yes Yes 1 +latin1_danish_ci latin1 15 0 +latin1_german2_ci latin1 31 Yes 2 +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 0 +latin1_general_cs latin1 49 0 +latin1_spanish_ci latin1 94 0 +select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY +where COLLATION_NAME like 'latin1%'; +COLLATION_NAME CHARACTER_SET_NAME +latin1_german1_ci latin1 +latin1_swedish_ci latin1 +latin1_danish_ci latin1 +latin1_german2_ci latin1 +latin1_bin latin1 +latin1_general_ci latin1 +latin1_general_cs latin1 +latin1_spanish_ci latin1 +create function sub1(i int) returns int +return i+1; +create procedure sel2() +begin +select * from t1; +select * from t2; +end| +show procedure status; +Db Name Type Definer Modified Created Security_type Comment +test sel2 PROCEDURE root@localhost # # DEFINER +show function status; +Db Name Type Definer Modified Created Security_type Comment +test sub1 FUNCTION root@localhost # # DEFINER +select a.ROUTINE_NAME from information_schema.ROUTINES a, +information_schema.SCHEMATA b where +a.ROUTINE_SCHEMA = b.SCHEMA_NAME; +ROUTINE_NAME +sel2 +sub1 +explain select a.ROUTINE_NAME from information_schema.ROUTINES a, +information_schema.SCHEMATA b where +a.ROUTINE_SCHEMA = b.SCHEMA_NAME; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE # ALL NULL NULL NULL NULL 2 +1 SIMPLE # ALL NULL NULL NULL NULL 2 Using where +select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, +mysql.proc b where a.ROUTINE_NAME = b.name; +ROUTINE_NAME name +sub1 sub1 +sel2 sel2 +select count(*) from information_schema.ROUTINES; +count(*) +2 +create view v0 (c) as select schema_name from information_schema.SCHEMATA; +select * from v0; +c +mysql +test +explain select * from v0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY # ALL NULL NULL NULL NULL 2 +create view v1 (c) as select table_name from information_schema.TABLES +where table_name="v1"; +select * from v1; +c +v1 +create view v2 (c) as select column_name from information_schema.COLUMNS +where table_name="v2"; +select * from v2; +c +c +create view v3 (c) as select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS +where CHARACTER_SET_NAME like "latin1%"; +select * from v3; +c +latin1 +create view v4 (c) as select COLLATION_NAME from information_schema.COLLATIONS +where COLLATION_NAME like "latin1%"; +select * from v4; +c +latin1_german1_ci +latin1_swedish_ci +latin1_danish_ci +latin1_german2_ci +latin1_bin +latin1_general_ci +latin1_general_cs +latin1_spanish_ci +show keys from v4; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +select * from information_schema.VIEWS where TABLE_NAME like "v%"; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE +NULL test v0 select `SCHEMATA`.`SCHEMA_NAME` AS `c` from `information_schema`.`SCHEMATA` NONE NO +NULL test v1 select `TABLES`.`TABLE_NAME` AS `c` from `information_schema`.`TABLES` where (`TABLES`.`TABLE_NAME` = _latin1'v1') NONE NO +NULL test v2 select `COLUMNS`.`COLUMN_NAME` AS `c` from `information_schema`.`COLUMNS` where (`COLUMNS`.`TABLE_NAME` = _latin1'v2') NONE NO +NULL test v3 select `CHARACTER_SETS`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`CHARACTER_SETS` where (`CHARACTER_SETS`.`CHARACTER_SET_NAME` like _latin1'latin1%') NONE NO +NULL test v4 select `COLLATIONS`.`COLLATION_NAME` AS `c` from `information_schema`.`COLLATIONS` where (`COLLATIONS`.`COLLATION_NAME` like _latin1'latin1%') NONE NO +drop view v0, v1, v2, v3, v4; +create table t1 (a int); +grant select,update,insert on t1 to mysqltest_1@localhost; +grant select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +grant all on test.* to mysqltest_1@localhost with grant option; +select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_1%'; +GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE +'mysqltest_1'@'localhost' NULL USAGE NO +select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE +'mysqltest_1'@'localhost' NULL test SELECT YES +'mysqltest_1'@'localhost' NULL test INSERT YES +'mysqltest_1'@'localhost' NULL test UPDATE YES +'mysqltest_1'@'localhost' NULL test DELETE YES +'mysqltest_1'@'localhost' NULL test CREATE YES +'mysqltest_1'@'localhost' NULL test DROP YES +'mysqltest_1'@'localhost' NULL test REFERENCES YES +'mysqltest_1'@'localhost' NULL test INDEX YES +'mysqltest_1'@'localhost' NULL test ALTER YES +'mysqltest_1'@'localhost' NULL test CREATE TEMPORARY TABLES YES +'mysqltest_1'@'localhost' NULL test LOCK TABLES YES +'mysqltest_1'@'localhost' NULL test CREATE VIEW YES +'mysqltest_1'@'localhost' NULL test SHOW VIEW YES +select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +'mysqltest_1'@'localhost' NULL test t1 SELECT NO +'mysqltest_1'@'localhost' NULL test t1 INSERT NO +'mysqltest_1'@'localhost' NULL test t1 UPDATE NO +select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +'mysqltest_1'@'localhost' NULL test t1 a SELECT NO +'mysqltest_1'@'localhost' NULL test t1 a INSERT NO +'mysqltest_1'@'localhost' NULL test t1 a UPDATE NO +'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +drop table t1; +create table t1 (a int null, primary key(a)); +alter table t1 add constraint constraint_1 unique (a); +alter table t1 add constraint unique key_1(a); +alter table t1 add constraint constraint_2 unique key_2(a); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + PRIMARY KEY (`a`), + UNIQUE KEY `constraint_1` (`a`), + UNIQUE KEY `key_1` (`a`), + UNIQUE KEY `key_2` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_SCHEMA= "test"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD +NULL test PRIMARY test t1 PRIMARY KEY NULL +NULL test constraint_1 test t1 UNIQUE NULL +NULL test key_1 test t1 UNIQUE NULL +NULL test key_2 test t1 UNIQUE NULL +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_SCHEMA= "test"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY test t1 a 1 NULL NULL NULL +NULL test constraint_1 test t1 a 1 NULL NULL NULL +NULL test key_1 test t1 a 1 NULL NULL NULL +NULL test key_2 test t1 a 1 NULL NULL NULL +drop table t1; +CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), +FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE, +FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE CASCADE) ENGINE=INNODB; +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_SCHEMA= "test"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD +NULL test PRIMARY test t1 PRIMARY KEY NULL +NULL test PRIMARY test t2 PRIMARY KEY NULL +NULL test t2_ibfk_1 test t2 FOREIGN KEY ON DELETE CASCADE +NULL test t2_ibfk_2 test t2 FOREIGN KEY ON UPDATE CASCADE +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_SCHEMA= "test"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY test t1 id 1 NULL NULL NULL +NULL test PRIMARY test t2 id 1 NULL NULL NULL +NULL test t2_ibfk_1 test t2 t1_id 1 test t1 id +NULL test t2_ibfk_2 test t2 t1_id 1 test t1 id +select table_name from information_schema.TABLES where table_schema like "test%"; +table_name +t1 +t2 +select table_name,column_name from information_schema.COLUMNS where table_schema like "test%"; +table_name column_name +t1 id +t2 id +t2 t1_id +select ROUTINE_NAME from information_schema.ROUTINES; +ROUTINE_NAME +sel2 +sub1 +delete from mysql.user where user='mysqltest_1'; +drop table t2; +drop table t1; +drop procedure sel2; +drop function sub1; +create table t1(a int); +create view v1 (c) as select a from t1 with check option; +create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION; +create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION; +select * from information_schema.views; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE +NULL test v1 select `test`.`t1`.`a` AS `c` from `test`.`t1` WITH CASCADED CHECK OPTION YES +NULL test v2 select `test`.`t1`.`a` AS `c` from `test`.`t1` WITH LOCAL CHECK OPTION YES +NULL test v3 select `test`.`t1`.`a` AS `c` from `test`.`t1` WITH CASCADED CHECK OPTION YES +grant select (a) on test.t1 to joe@localhost with grant option; +select * from INFORMATION_SCHEMA.COLUMN_PRIVILEGES; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE +'joe'@'localhost' NULL test t1 a SELECT YES +select * from INFORMATION_SCHEMA.TABLE_PRIVILEGES; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +'joe'@'localhost' NULL test t1 USAGE YES +drop view v1, v2, v3; +drop table t1; +delete from mysql.user where user='joe'; +delete from mysql.db where user='joe'; +delete from mysql.tables_priv where user='joe'; +delete from mysql.columns_priv where user='joe'; +flush privileges; +create procedure px5 () +begin +declare v int; +declare c cursor for select version from +information_schema.tables; +open c; +fetch c into v; +select v; +close c; +end;// +call px5()// +v +9 +call px5()// +v +9 diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index 228c7d325e5..3be73f6cc6a 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -4,11 +4,11 @@ DROP DATABASE IF EXISTS `test_$1`; CREATE TABLE T1 (a int); INSERT INTO T1 VALUES (1); SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -T1 BASE TABLE +Tables_in_test (T1) +T1 SHOW TABLES LIKE "t1"; -Tables_in_test (t1) table_type -T1 BASE TABLE +Tables_in_test (t1) +T1 SHOW CREATE TABLE T1; Table Create Table T1 CREATE TABLE `T1` ( @@ -16,37 +16,37 @@ T1 CREATE TABLE `T1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 RENAME TABLE T1 TO T2; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -T2 BASE TABLE +Tables_in_test (T2) +T2 SELECT * FROM t2; a 1 RENAME TABLE T2 TO t3; SHOW TABLES LIKE "T3"; -Tables_in_test (T3) table_type -t3 BASE TABLE +Tables_in_test (T3) +t3 RENAME TABLE T3 TO T1; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -T1 BASE TABLE +Tables_in_test (T1) +T1 ALTER TABLE T1 add b int; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -T1 BASE TABLE +Tables_in_test (T1) +T1 ALTER TABLE T1 RENAME T2; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -T2 BASE TABLE +Tables_in_test (T2) +T2 LOCK TABLE T2 WRITE; ALTER TABLE T2 drop b; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -T2 BASE TABLE +Tables_in_test (T2) +T2 UNLOCK TABLES; RENAME TABLE T2 TO T1; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -T1 BASE TABLE +Tables_in_test (T1) +T1 SELECT * from T1; a 1 @@ -59,11 +59,11 @@ DROP DATABASE `test_$1`; CREATE TABLE T1 (a int) engine=innodb; INSERT INTO T1 VALUES (1); SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -T1 BASE TABLE +Tables_in_test (T1) +T1 SHOW TABLES LIKE "t1"; -Tables_in_test (t1) table_type -T1 BASE TABLE +Tables_in_test (t1) +T1 SHOW CREATE TABLE T1; Table Create Table T1 CREATE TABLE `T1` ( @@ -71,37 +71,37 @@ T1 CREATE TABLE `T1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 RENAME TABLE T1 TO T2; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -t2 BASE TABLE +Tables_in_test (T2) +t2 SELECT * FROM t2; a 1 RENAME TABLE T2 TO t3; SHOW TABLES LIKE "T3"; -Tables_in_test (T3) table_type -t3 BASE TABLE +Tables_in_test (T3) +t3 RENAME TABLE T3 TO T1; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -t1 BASE TABLE +Tables_in_test (T1) +t1 ALTER TABLE T1 add b int; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -t1 BASE TABLE +Tables_in_test (T1) +t1 ALTER TABLE T1 RENAME T2; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -t2 BASE TABLE +Tables_in_test (T2) +t2 LOCK TABLE T2 WRITE; ALTER TABLE T2 drop b; SHOW TABLES LIKE "T2"; -Tables_in_test (T2) table_type -t2 BASE TABLE +Tables_in_test (T2) +t2 UNLOCK TABLES; RENAME TABLE T2 TO T1; SHOW TABLES LIKE "T1"; -Tables_in_test (T1) table_type -t1 BASE TABLE +Tables_in_test (T1) +t1 SELECT * from T1; a 1 @@ -124,10 +124,10 @@ drop table T1; create table T1 (A int); alter table T1 add index (A); show tables like 'T1%'; -Tables_in_test (T1%) table_type -T1 BASE TABLE +Tables_in_test (T1%) +T1 alter table t1 add index (A); show tables like 't1%'; -Tables_in_test (t1%) table_type -t1 BASE TABLE +Tables_in_test (t1%) +t1 drop table t1; diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index ced3ca61f80..2321a8998ac 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -5,7 +5,7 @@ def 1 8 1 1 N 32769 0 8 def 1.0 5 3 3 N 32769 1 8 def -1 8 1 2 N 32769 0 8 def hello 254 5 5 N 1 31 8 -def NULL 6 0 0 Y 32768 0 8 +def NULL 6 0 0 Y 32896 0 63 1 1.0 -1 hello NULL 1 1.0 -1 hello NULL create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10)); diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index 11bc9772276..abcb451df65 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -180,4 +180,25 @@ master-bin.000001 95 Query 1 # use `test`; BEGIN master-bin.000001 157 Query 1 # use `test`; insert into t1 values(16) master-bin.000001 239 Query 1 # use `test`; insert into t1 values(18) master-bin.000001 321 Query 1 # use `test`; COMMIT +delete from t1; +delete from t2; +alter table t2 type=MyISAM; +insert into t1 values (1); +begin; +select * from t1 for update; +a +1 +select (@before:=unix_timestamp())*0; +(@before:=unix_timestamp())*0 +0 +begin; + select * from t1 for update; +insert into t2 values (20); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select (@after:=unix_timestamp())*0; +(@after:=unix_timestamp())*0 +0 +select (@after-@before) >= 2; +(@after-@before) >= 2 +1 drop table t1,t2; diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index 4925aac8ac1..82ff4072378 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; flush status; create table t1( id int not null primary key, @@ -363,3 +363,8 @@ a int NOT NULL PRIMARY KEY, b int ) engine=ndb; insert t9 values(1, 2), (2,3), (3, 4), (4, 5); +create table t10 ( +a int not null primary key, +b blob +) engine=ndb; +insert into t10 values (1, 'kalle'); diff --git a/mysql-test/r/ndb_autodiscover2.result b/mysql-test/r/ndb_autodiscover2.result index 08803d997a5..91f018b5d02 100644 --- a/mysql-test/r/ndb_autodiscover2.result +++ b/mysql-test/r/ndb_autodiscover2.result @@ -8,3 +8,6 @@ show status like 'handler_discover%'; Variable_name Value Handler_discover 1 drop table t9; +select * from t10; +ERROR HY000: Got error 4263 'Invalid blob attributes or invalid blob parts table' from ndbcluster +drop table t10; diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index ba8ee820ad9..6ec5338acbe 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -400,6 +400,13 @@ b attr1 9413 9412 drop table test.t1, t2; drop database mysqltest; +drop database if exists ndbtest1; +create database ndbtest1; +use ndbtest1; +create table t1(id int) engine=ndbcluster; +drop database ndbtest1; +drop database ndbtest1; +ERROR HY000: Can't drop database 'ndbtest1'; database doesn't exist use test; create table t1 (a int primary key, b char(0)); insert into t1 values (1,""); diff --git a/mysql-test/r/ndb_index_ordered.result b/mysql-test/r/ndb_index_ordered.result index 2dc260ec43d..50f904af750 100644 --- a/mysql-test/r/ndb_index_ordered.result +++ b/mysql-test/r/ndb_index_ordered.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1, test1, test2; CREATE TABLE t1 ( a int unsigned NOT NULL PRIMARY KEY, b int unsigned not null, @@ -275,3 +275,38 @@ a b c 1 1 1 4 4 NULL drop table t1; +CREATE TABLE test1 ( +SubscrID int(11) NOT NULL auto_increment, +UsrID int(11) NOT NULL default '0', +PRIMARY KEY (SubscrID), +KEY idx_usrid (UsrID) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO test1 VALUES (2,224),(3,224),(1,224); +CREATE TABLE test2 ( +SbclID int(11) NOT NULL auto_increment, +SbcrID int(11) NOT NULL default '0', +PRIMARY KEY (SbclID), +KEY idx_sbcrid (SbcrID) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; +INSERT INTO test2 VALUES (3,2),(1,1),(2,1),(4,2); +select * from test1 order by 1; +SubscrID UsrID +1 224 +2 224 +3 224 +select * from test2 order by 1; +SbclID SbcrID +1 1 +2 1 +3 2 +4 2 +SELECT s.SubscrID,l.SbclID FROM test1 s left JOIN test2 l ON +l.SbcrID=s.SubscrID WHERE s.UsrID=224 order by 1, 2; +SubscrID SbclID +1 1 +1 2 +2 3 +2 4 +3 NULL +drop table test1; +drop table test2; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index f39bd0c6f6c..68fb9c3a34b 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -184,3 +184,97 @@ select count(*) from t1 where i=2 or i is null; count(*) 9 drop table t1; +set names latin2; +create table t1 select +null as c00, +if(1, null, 'string') as c01, +if(0, null, 'string') as c02, +ifnull(null, 'string') as c03, +ifnull('string', null) as c04, +case when 0 then null else 'string' end as c05, +case when 1 then null else 'string' end as c06, +coalesce(null, 'string') as c07, +coalesce('string', null) as c08, +least('string',null) as c09, +least(null, 'string') as c10, +greatest('string',null) as c11, +greatest(null, 'string') as c12, +nullif('string', null) as c13, +nullif(null, 'string') as c14, +trim('string' from null) as c15, +trim(null from 'string') as c16, +substring_index('string', null, 1) as c17, +substring_index(null, 'string', 1) as c18, +elt(1, null, 'string') as c19, +elt(1, 'string', null) as c20, +concat('string', null) as c21, +concat(null, 'string') as c22, +concat_ws('sep', 'string', null) as c23, +concat_ws('sep', null, 'string') as c24, +concat_ws(null, 'string', 'string') as c25, +make_set(3, 'string', null) as c26, +make_set(3, null, 'string') as c27, +export_set(3, null, 'off', 'sep') as c29, +export_set(3, 'on', null, 'sep') as c30, +export_set(3, 'on', 'off', null) as c31, +replace(null, 'from', 'to') as c32, +replace('str', null, 'to') as c33, +replace('str', 'from', null) as c34, +insert('str', 1, 2, null) as c35, +insert(null, 1, 2, 'str') as c36, +lpad('str', 10, null) as c37, +rpad(null, 10, 'str') as c38; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c00` binary(0) default NULL, + `c01` varchar(6) character set latin2 default NULL, + `c02` varchar(6) character set latin2 default NULL, + `c03` varchar(6) character set latin2 NOT NULL default '', + `c04` varchar(6) character set latin2 default NULL, + `c05` varchar(6) character set latin2 default NULL, + `c06` varchar(6) character set latin2 default NULL, + `c07` varchar(6) character set latin2 default NULL, + `c08` varchar(6) character set latin2 default NULL, + `c09` varchar(6) character set latin2 NOT NULL default '', + `c10` varchar(6) character set latin2 NOT NULL default '', + `c11` varchar(6) character set latin2 NOT NULL default '', + `c12` varchar(6) character set latin2 NOT NULL default '', + `c13` varchar(6) character set latin2 default NULL, + `c14` char(0) character set latin2 default NULL, + `c15` char(0) character set latin2 default NULL, + `c16` varchar(6) character set latin2 default NULL, + `c17` varchar(6) character set latin2 default NULL, + `c18` char(0) character set latin2 default NULL, + `c19` varchar(6) character set latin2 default NULL, + `c20` varchar(6) character set latin2 default NULL, + `c21` varchar(6) character set latin2 default NULL, + `c22` varchar(6) character set latin2 default NULL, + `c23` varchar(9) character set latin2 default NULL, + `c24` varchar(9) character set latin2 default NULL, + `c25` varchar(12) character set latin2 default NULL, + `c26` varchar(7) character set latin2 default NULL, + `c27` varchar(7) character set latin2 default NULL, + `c29` longtext character set latin2, + `c30` longtext character set latin2, + `c31` varchar(192) character set latin2 default NULL, + `c32` char(0) character set latin2 default NULL, + `c33` char(3) character set latin2 default NULL, + `c34` char(3) character set latin2 default NULL, + `c35` char(3) character set latin2 default NULL, + `c36` char(3) character set latin2 default NULL, + `c37` varchar(10) character set latin2 default NULL, + `c38` varchar(10) character set latin2 default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +select +case 'str' when 'STR' then 'str' when null then 'null' end as c01, +case 'str' when null then 'null' when 'STR' then 'str' end as c02, +field(null, 'str1', 'str2') as c03, +field('str1','STR1', null) as c04, +field('str1', null, 'STR1') as c05, +'string' in ('STRING', null) as c08, +'string' in (null, 'STRING') as c09; +c01 c02 c03 c04 c05 c08 c09 +str str 0 1 2 1 1 +set names latin1; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index fe7aa623023..e8d8e4063f1 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -1,4 +1,5 @@ -use test; +drop table if exists t5, t6, t7, t8; +drop database if exists mysqltest ; test_sequence ------ basic tests ------ drop table if exists t1, t9 ; @@ -553,7 +554,6 @@ execute stmt3; ERROR 42S01: Table 'new_t2' already exists rename table new_t2 to t2; drop table t2; -drop table if exists t5, t6, t7, t8 ; prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; execute stmt1 ; @@ -805,21 +805,24 @@ test_sequence ------ grant/revoke/drop affects a parallel session test ------ show grants for second_user@localhost ; ERROR 42000: There is no such grant defined for user 'second_user' on host 'localhost' -grant usage on test.* to second_user@localhost +create database mysqltest; +use mysqltest; +use test; +grant usage on mysqltest.* to second_user@localhost identified by 'looser' ; -grant select on test.t9 to second_user@localhost +grant select on mysqltest.t9 to second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' select current_user(); current_user() second_user@localhost show grants for current_user(); Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' prepare s_t9 from 'select c1 as my_col from t9 where c1= 1' ; execute s_t9 ; @@ -827,24 +830,24 @@ my_col 1 select a as my_col from t1; ERROR 42000: select command denied to user 'second_user'@'localhost' for table 't1' -grant select on test.t1 to second_user@localhost +grant select on mysqltest.t1 to second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t1` TO 'second_user'@'localhost' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' -drop table t9 ; +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t1` TO 'second_user'@'localhost' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t1` TO 'second_user'@'localhost' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col @@ -853,17 +856,17 @@ my_col 3 4 execute s_t9 ; -ERROR 42S02: Table 'test.t9' doesn't exist -revoke all privileges on test.t1 from second_user@localhost +ERROR 42S02: Table 'mysqltest.t9' doesn't exist +revoke all privileges on mysqltest.t1 from second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `test`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' execute s_t1 ; ERROR 42000: select command denied to user 'second_user'@'localhost' for table 't1' revoke all privileges, grant option from second_user@localhost ; @@ -874,4 +877,5 @@ drop user second_user@localhost ; commit ; show grants for second_user@localhost ; ERROR 42000: There is no such grant defined for user 'second_user' on host 'localhost' -drop table t1 ; +drop table t1,t9 ; +drop database mysqltest; diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 6773370fbc5..c64f513f0aa 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1789,7 +1789,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1819,7 +1819,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 09f19c3763c..adcf6064835 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1772,7 +1772,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1802,7 +1802,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 427fee8e757..cd36af07300 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1773,7 +1773,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1803,7 +1803,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 51d842ae000..3af0bfc7884 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1712,7 +1712,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1742,7 +1742,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 @@ -4721,7 +4721,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -4751,7 +4751,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 85cb8af652e..93f766c61e0 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1772,7 +1772,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1802,7 +1802,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index e90eff5d1cd..70118509d0b 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1749,7 +1749,7 @@ t5 CREATE TABLE `t5` ( `param10` bigint(20) default NULL, `const11` int(4) default NULL, `param11` bigint(20) default NULL, - `const12` char(0) default NULL, + `const12` binary(0) default NULL, `param12` bigint(20) default NULL, `param13` double default NULL, `param14` longtext, @@ -1779,7 +1779,7 @@ def test t5 t5 const10 const10 3 10 9 N 32769 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 -def test t5 t5 const12 const12 254 0 0 Y 0 0 8 +def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 def test t5 t5 param13 param13 5 20 0 Y 32768 31 63 def test t5 t5 param14 param14 252 16777215 0 Y 16 0 8 diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result index 2ffdb2c720a..9a002953b45 100644 --- a/mysql-test/r/rpl_charset.result +++ b/mysql-test/r/rpl_charset.result @@ -162,9 +162,9 @@ master-bin.000001 # Query 1 # use `mysqltest2`; drop database mysqltest2 master-bin.000001 # Query 1 # SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 # Query 1 # drop database mysqltest3 set global character_set_server=latin2; -ERROR HY000: Binary logging and replication forbid changing the global server character set or collation +ERROR HY000: Binary logging and replication forbid changing the global server character set, collation set global character_set_server=latin2; -ERROR HY000: Binary logging and replication forbid changing the global server character set or collation +ERROR HY000: Binary logging and replication forbid changing the global server character set, collation set one_shot @@character_set_server=latin5; set @@max_join_size=1000; select @@character_set_server; @@ -181,7 +181,7 @@ select @@character_set_server; @@character_set_server latin5 set one_shot max_join_size=10; -ERROR HY000: The SET ONE_SHOT syntax is reserved for purposes internal to the MySQL server +ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server set character_set_client=9999999; ERROR 42000: Unknown character set: '9999999' set collation_server=9999998; diff --git a/mysql-test/r/rpl_rewrite_db.result b/mysql-test/r/rpl_rewrite_db.result new file mode 100644 index 00000000000..2804b98dea1 --- /dev/null +++ b/mysql-test/r/rpl_rewrite_db.result @@ -0,0 +1,22 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +drop database if exists mysqltest1; +create database mysqltest1; +use mysqltest1; +create table t1 (a int); +insert into t1 values(9); +select * from mysqltest1.t1; +a +9 +show databases like 'mysqltest1'; +Database (mysqltest1) +mysqltest1 +select * from test.t1; +a +9 +drop table t1; +drop database mysqltest1; diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 85071e13555..cfd296fd44b 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -1,7 +1,7 @@ drop table if exists t1, t2, t3, t4; drop table if exists t1, t2, t3, t4; start slave; -ERROR HY000: Could not initialize master info structure; more error messages can be found in the MySQL error log +ERROR HY000: File 'TESTDIR/var/slave-data/master.info' not found (Errcode: 13) start slave; ERROR HY000: Could not initialize master info structure; more error messages can be found in the MySQL error log change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result index 6dc8f87393c..495fccd35a3 100644 --- a/mysql-test/r/rpl_timezone.result +++ b/mysql-test/r/rpl_timezone.result @@ -73,5 +73,5 @@ t 2001-09-09 03:46:40 1000000000 set global time_zone='MET'; -ERROR HY000: Binary logging and replication forbid changing of the global server time zone +ERROR HY000: Binary logging and replication forbid changing the global server time zone drop table t1, t2; diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index 23804e62ef5..25582796812 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -30,7 +30,7 @@ db1_secret select * from db1_secret.t1; ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret' create procedure db1_secret.dummy() begin end; -ERROR 42000: Unknown database 'db1_secret' +ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret' drop procedure db1_secret.dummy; ERROR 42000: PROCEDURE db1_secret.dummy does not exist call db1_secret.stamp(3); @@ -40,7 +40,7 @@ db1_secret select * from db1_secret.t1; ERROR 42000: Access denied for user ''@'localhost' to database 'db1_secret' create procedure db1_secret.dummy() begin end; -ERROR 42000: Unknown database 'db1_secret' +ERROR 42000: Access denied for user ''@'localhost' to database 'db1_secret' drop procedure db1_secret.dummy; ERROR 42000: PROCEDURE db1_secret.dummy does not exist select * from t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index bcabf693e4c..8745a274851 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1746,10 +1746,20 @@ drop table if exists t3| create procedure bug4904() begin declare continue handler for sqlstate 'HY000' begin end; -create table t2 as select * from t; +create table t2 as select * from t3; end| call bug4904()| +ERROR 42S02: Table 'test.t3' doesn't exist drop procedure bug4904| +create table t3 (s1 char character set latin1, s2 char character set latin2)| +create procedure bug4904 () +begin +declare continue handler for sqlstate 'HY000' begin end; +select s1 from t3 union select s2 from t3; +end| +call bug4904()| +drop procedure bug4904| +drop table t3| create procedure bug336(out y int) begin declare x int; diff --git a/mysql-test/r/timezone3.result b/mysql-test/r/timezone3.result new file mode 100644 index 00000000000..ec0b6045f93 --- /dev/null +++ b/mysql-test/r/timezone3.result @@ -0,0 +1,41 @@ +drop table if exists t1; +create table t1 (i int, c varchar(20)); +insert into t1 values +(unix_timestamp("2004-01-01 00:00:00"), "2004-01-01 00:00:00"); +insert into t1 values +(unix_timestamp("2004-03-28 01:59:59"), "2004-03-28 01:59:59"), +(unix_timestamp("2004-03-28 02:30:00"), "2004-03-28 02:30:00"), +(unix_timestamp("2004-03-28 03:00:00"), "2004-03-28 03:00:00"); +insert into t1 values +(unix_timestamp('2004-05-01 00:00:00'),'2004-05-01 00:00:00'); +insert into t1 values +(unix_timestamp('2004-10-31 01:00:00'),'2004-10-31 01:00:00'), +(unix_timestamp('2004-10-31 02:00:00'),'2004-10-31 02:00:00'), +(unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'), +(unix_timestamp('2004-10-31 04:00:00'),'2004-10-31 04:00:00'), +(unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'); +insert into t1 values +(unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), +(unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +select i, from_unixtime(i), c from t1; +i from_unixtime(i) c +1072904422 2004-01-01 00:00:00 2004-01-01 00:00:00 +1080428421 2004-03-28 01:59:59 2004-03-28 01:59:59 +1080428422 2004-03-28 03:00:00 2004-03-28 02:30:00 +1080428422 2004-03-28 03:00:00 2004-03-28 03:00:00 +1083355222 2004-05-01 00:00:00 2004-05-01 00:00:00 +1099170022 2004-10-31 01:00:00 2004-10-31 01:00:00 +1099177222 2004-10-31 02:00:00 2004-10-31 02:00:00 +1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 +1099184422 2004-10-31 04:00:00 2004-10-31 04:00:00 +1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 +362793608 1981-07-01 03:59:59 1981-07-01 03:59:59 +362793610 1981-07-01 04:00:00 1981-07-01 04:00:00 +drop table t1; +create table t1 (ts timestamp); +insert into t1 values (19730101235900), (20040101235900); +select * from t1; +ts +1973-01-01 23:59:00 +2004-01-01 23:59:00 +drop table t1; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 2a2e10dbbd5..b45aaea0cbe 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -174,3 +174,15 @@ create trigger tx1 before insert on t1 for each row set new.x1col = 'x'; insert into t1 values ('y'); drop trigger t1.tx1; drop table t1; +create table t1 (i int) engine=myisam; +insert into t1 values (1), (2); +create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i; +create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i; +set @del_before:=0, @del_after:= 0; +delete from t1; +select @del_before, @del_after; +@del_before @del_after +3 3 +drop trigger t1.trg1; +drop trigger t1.trg2; +drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 18fa7c2e374..f41e6c7e165 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1221,11 +1221,11 @@ ERROR 42000: FUNCTION test.x1 does not exist show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL -v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL FUNCTION test.x1 does not exist show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL -v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL FUNCTION test.x1 does not exist drop view v1; drop table t1; create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; diff --git a/mysql-test/std_data/Moscow_leap b/mysql-test/std_data/Moscow_leap Binary files differnew file mode 100644 index 00000000000..4994c005595 --- /dev/null +++ b/mysql-test/std_data/Moscow_leap diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index e46027ae8d9..66a4adc90fe 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -324,3 +324,15 @@ alter table t1 rename to `t1\\`; rename table t1 to `t1\\`; drop table t1; +# +# Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns +# +# The column's character set was changed but the actual data was not +# modified. In other words, the values were reinterpreted +# as UTF8 instead of being converted. +create table t1 (a text) character set koi8r; +insert into t1 values (_koi8r'ÔÅÓÔ'); +select hex(a) from t1; +alter table t1 convert to character set cp1251; +select hex(a) from t1; +drop table t1; diff --git a/mysql-test/t/client_test.test b/mysql-test/t/client_test.test index 830c5f1b8a2..66f5e69eb36 100644 --- a/mysql-test/t/client_test.test +++ b/mysql-test/t/client_test.test @@ -1,2 +1,2 @@ --disable_result_log ---exec $TESTS_BINDIR/client_test --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent +--exec $TESTS_BINDIR/client_test --no-defaults --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index 4598ca5ea15..8e1a92a586e 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -49,7 +49,7 @@ flush privileges; #show tables; connect (con1,localhost,test,gambling2,mysql); set password=""; ---error 1105 +--error 1372 set password='gambling3'; set password=old_password('gambling3'); show tables; diff --git a/mysql-test/t/consistent_snapshot.test b/mysql-test/t/consistent_snapshot.test new file mode 100644 index 00000000000..7afdae36325 --- /dev/null +++ b/mysql-test/t/consistent_snapshot.test @@ -0,0 +1,41 @@ +-- source include/have_innodb.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +### Test 1: +### - While a consistent snapshot transaction is executed, +### no external inserts should be visible to the transaction. + +connection con1; +create table t1 (a int) engine=innodb; +start transaction with consistent snapshot; + +connection con2; +insert into t1 values(1); + +connection con1; +select * from t1; # if consistent snapshot was set as expected, we +# should see nothing. +commit; + +### Test 2: +### - For any non-consistent snapshot transaction, external +### committed inserts should be visible to the transaction. + +delete from t1; +start transaction; # Now we omit WITH CONSISTENT SNAPSHOT + +connection con2; +insert into t1 values(1); + +connection con1; +select * from t1; # if consistent snapshot was not set, as expected, we +# should see 1. +commit; + +drop table t1; diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index e5405d9f1bd..9cfb6b14d7e 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -83,3 +83,39 @@ CREATE TABLE t1 ( SHOW CREATE TABLE t1; SHOW COLUMNS FROM t1; DROP TABLE t1; + +# +# Bug #6345 Unexpected behaviour with partial indices +# +--disable_warnings +CREATE TABLE t1 +( + a INTEGER NOT NULL, + b VARCHAR(50) NOT NULL DEFAULT '', + PRIMARY KEY (a), + KEY b (b(10)) +) TYPE=InnoDB CHARACTER SET 'ujis' COLLATE 'ujis_japanese_ci'; +--enable_warnings +INSERT INTO t1 (a, b) VALUES (0, 'aaabbbcccddd'); +INSERT INTO t1 (a, b) VALUES (1, 'eeefffggghhh'); +INSERT INTO t1 (a, b) VALUES (2, 'iiijjjkkkl'); +SELECT t1.* FROM t1 WHERE b='aaabbbcccddd' ORDER BY a; +SELECT t1.* FROM t1 WHERE b='eeefffggghhh' ORDER BY a; +SELECT t1.* FROM t1 WHERE b='iiijjjkkkl' ORDER BY a; +DROP TABLE t1; +--disable_warnings +CREATE TABLE t1 +( + a INTEGER NOT NULL, + b VARCHAR(50) NOT NULL DEFAULT '', + PRIMARY KEY (a), + KEY b (b(10)) +) TYPE=MyISAM CHARACTER SET 'ujis' COLLATE 'ujis_japanese_ci'; +--enable_warnings +INSERT INTO t1 (a, b) VALUES (0, 'aaabbbcccddd'); +INSERT INTO t1 (a, b) VALUES (1, 'eeefffggghhh'); +INSERT INTO t1 (a, b) VALUES (2, 'iiijjjkkkl'); +SELECT t1.* FROM t1 WHERE b='aaabbbcccddd' ORDER BY a; +SELECT t1.* FROM t1 WHERE b='eeefffggghhh' ORDER BY a; +SELECT t1.* FROM t1 WHERE b='iiijjjkkkl' ORDER BY a; +DROP TABLE t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 3eab694ee05..d5a3e80c417 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -83,6 +83,12 @@ select hex(unhex("1")), hex(unhex("12")), hex(unhex("123")), hex(unhex("1234")), select length(unhex(md5("abrakadabra"))); # +# Bug #6564: QUOTE(NULL +# + +select concat('a', quote(NULL)); + +# # Wrong usage of functions # diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 4b1601c245f..dfd5f4db7c6 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -98,6 +98,30 @@ GRANT FILE on mysqltest.* to mysqltest_1@localhost; select 1; -- To test that the previous command didn't cause problems # +# Bug #4898: User privileges depending on ORDER BY Settings of table db +# +insert into mysql.user (host, user) values ('localhost', 'test11'); +insert into mysql.db (host, db, user, select_priv) values +('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); +alter table mysql.db order by db asc; +flush privileges; +show grants for test11@localhost; +alter table mysql.db order by db desc; +flush privileges; +show grants for test11@localhost; +delete from mysql.user where user='test11'; +delete from mysql.db where user='test11'; + +# +# Bug#6123: GRANT USAGE inserts useless Db row +# +create database mysqltest1; +grant usage on mysqltest1.* to test6123 identified by 'magic123'; +select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1"; +delete from mysql.user where user='test6123'; +drop database mysqltest1; + +# # Test for 'drop user', 'revoke privileges, grant' # @@ -175,21 +199,6 @@ DROP DATABASE ÂÄ; SET NAMES latin1; # -# Bug #4898: User privileges depending on ORDER BY Settings of table db -# -insert into mysql.user (host, user) values ('localhost', 'test11'); -insert into mysql.db (host, db, user, select_priv) values -('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); -alter table mysql.db order by db asc; -flush privileges; -show grants for test11@localhost; -alter table mysql.db order by db desc; -flush privileges; -show grants for test11@localhost; -delete from mysql.user where user='test11'; -delete from mysql.db where user='test11'; - -# # Bug #5831: REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything # USE test; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 12a44fd75dc..b0fc600030b 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -2,7 +2,7 @@ # --disable_warnings -drop table if exists t1,t2; +drop table if exists t1,t2,t3; --enable_warnings create table t1 (a int); @@ -122,3 +122,196 @@ from t1 a left join t3 b on a.id=b.order_id group by a.id, a.description having (a.description is not null) and (c=0); drop table t1,t2,t3; + + +# +# Tests for WL#1972 CORRECT EVALUATION OF COLUMN REFERENCES IN THE HAVING CLAUSE +# Per the SAP VERI tests and WL#1972, MySQL must ensure that HAVING can +# correctly evaluate column references from the GROUP BY clause, even if the +# same references are not also found in the select list. +# + +# set global sql_mode='ansi'; +# set session sql_mode='ansi'; + +create table t1 (col1 int, col2 varchar(5), col_t1 int); +create table t2 (col1 int, col2 varchar(5), col_t2 int); +create table t3 (col1 int, col2 varchar(5), col_t3 int); + +insert into t1 values(10,'hello',10); +insert into t1 values(20,'hello',20); +insert into t1 values(30,'hello',30); +insert into t1 values(10,'bye',10); +insert into t1 values(10,'sam',10); +insert into t1 values(10,'bob',10); + +insert into t2 select * from t1; +insert into t3 select * from t1; + +select count(*) from t1 group by col1 having col1 = 10; +select count(*) as count_col1 from t1 group by col1 having col1 = 10; +select count(*) as count_col1 from t1 as tmp1 group by col1 having col1 = 10; +select count(*) from t1 group by col2 having col2 = 'hello'; +--error 1054 +select count(*) from t1 group by col2 having col1 = 10; +select col1 as count_col1 from t1 as tmp1 group by col1 having col1 = 10; +select col1 as count_col1 from t1 as tmp1 group by col1 having count_col1 = 10; +select col1 as count_col1 from t1 as tmp1 group by count_col1 having col1 = 10; +# ANSI: should return SQLSTATE 42000 Syntax error or access violation +# MySQL: returns 10 - because of GROUP BY name resolution +select col1 as count_col1 from t1 as tmp1 group by count_col1 having count_col1 = 10; +# ANSI: should return SQLSTATE 42000 Syntax error or access violation +# MySQL: returns 10 - because of GROUP BY name resolution +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having col1 = 10; +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having count_col1 = 10; +select col1 as count_col1,col2 from t1 as tmp1 group by col1,col2 having col2 = 'hello'; +select col1 as count_col1,col2 as group_col2 from t1 as tmp1 group by col1,col2 having group_col2 = 'hello'; +--error 1064 +select sum(col1) as co12 from t1 group by col2 having col2 10; +select sum(col1) as co2, count(col2) as cc from t1 group by col1 having col1 =10; +--error 1054 +select t2.col2 from t2 group by t2.col1, t2.col2 having t1.col1 <= 10; + + +# +# queries with nested sub-queries +# + +# the having column is resolved in the same query +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having t2.col1 <= 10); + +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 + having t2.col1 <= + (select min(t3.col1) from t3)); + +# the having column is resolved in the SELECT clause of the outer query - +# works in ANSI +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having t1.col1 <= 10); + +# the having column is resolved in the SELECT clause of the outer query - +# error in ANSI, works with MySQL extension +select t1.col1 as tmp_col from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having tmp_col <= 10); + +# the having column is resolved in the FROM clause of the outer query - +# works in ANSI +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having col_t1 <= 10); + +# Item_field must be resolved in the same way as Item_ref +select sum(col1) from t1 +group by col_t1 +having (select col_t1 from t2 where col_t1 = col_t2 order by col_t2 limit 1); + +# nested queries with HAVING, inner having column resolved in outer FROM clause +# the outer having column is not referenced in GROUP BY which results in an error +--error 1054 +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having col_t1 <= 10) +having col_t1 <= 20; + +# both having columns are resolved in the GROUP clause of the outer query +select t1.col1 from t1 +where t1.col2 in + (select t2.col2 from t2 + group by t2.col1, t2.col2 having col_t1 <= 10) +group by col_t1 +having col_t1 <= 20; + + +# +# nested HAVING clauses +# + +# non-correlated subqueries +select col_t1, sum(col1) from t1 +group by col_t1 +having col_t1 > 10 and + exists (select sum(t2.col1) from t2 + group by t2.col2 having t2.col2 > 'b'); + +# correlated subqueries - inner having column 't1.col2' resolves to +# the outer FROM clause, which cannot be used because the outer query +# is grouped +--error 1054 +select sum(col1) from t1 +group by col_t1 +having col_t1 in (select sum(t2.col1) from t2 + group by t2.col2, t2.col1 having t2.col1 = t1.col1); + +# correlated subqueries - inner having column 'col_t1' resolves to +# the outer GROUP clause +select sum(col1) from t1 +group by col_t1 +having col_t1 in (select sum(t2.col1) from t2 + group by t2.col2, t2.col1 having t2.col1 = col_t1); + +# +# queries with joins and ambiguous column names +# +--error 1052 +select t1.col1, t2.col1 from t1, t2 where t1.col1 = t2.col1 +group by t1.col1, t2.col1 having col1 = 2; + +--error 1052 +select t1.col1*10+t2.col1 from t1,t2 where t1.col1=t2.col1 +group by t1.col1, t2.col1 having col1 = 2; + +drop table t1, t2, t3; + +# More queries to test ANSI compatibility +create table t1 (s1 int); +insert into t1 values (1),(2),(3); + +select count(*) from t1 group by s1 having s1 is null; + +select s1*0 as s1 from t1 group by s1 having s1 <> 0; +# ANSI requires: 3 rows +# MySQL returns: 0 rows - because of GROUP BY name resolution + +select s1*0 from t1 group by s1 having s1 = 0; + +select s1 from t1 group by 1 having 1 = 0; + +select count(s1) from t1 group by s1 having count(1+1)=2; +# ANSI requires: 3 rows +# MySQL returns: 0 rows - because of GROUP BY name resolution + +select count(s1) from t1 group by s1 having s1*0=0; + +-- error 1052 +select * from t1 a, t1 b group by a.s1 having s1 is null; +# ANSI requires: 0 rows +# MySQL returns: +# "ERROR 1052 (23000): Column 's1' in having clause is ambiguous" +# I think the column is ambiguous in ANSI too. +# It is the same as: +# select a.s1, b.s1 from t1 a, t1 b group by a.s1 having s1 is null; +# currently we first check SELECT, thus s1 is ambiguous. + +drop table t1; + +create table t1 (s1 char character set latin1 collate latin1_german1_ci); +insert into t1 values ('ü'),('y'); + +select s1,count(s1) from t1 +group by s1 collate latin1_swedish_ci having s1 = 'y'; +# ANSI requires: 1 row, with count(s1) = 2 +# MySQL returns: 1 row, with count(s1) = 1 + +drop table t1; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test new file mode 100644 index 00000000000..fb1d15dbb4c --- /dev/null +++ b/mysql-test/t/information_schema.test @@ -0,0 +1,224 @@ + +# Test for information_schema.schemata & +# show databases + +grant all privileges on test.* to mysqltest_1@localhost; + +select * from information_schema.SCHEMATA where schema_name > 'm'; +select schema_name from information_schema.schemata; +show databases *; +show databases like 't%'; +show databases; +show databases * where schema_name like 't%'; +show databases * where schema_name = 't%'; + +# Test for information_schema.tables & +# show tables + +create database testtets; +create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b)); +create table test.t2(a int); +create table t3(a int, KEY a_data (a)); +create table testtets.t4(a int); +create view v1 (c) as select table_name from information_schema.TABLES; +select * from v1; +select c,table_name from v1 +left join information_schema.TABLES v2 on (v1.c=v2.table_name) +where v1.c like "t%"; + +select c, v2.table_name from v1 +right join information_schema.TABLES v2 on (v1.c=v2.table_name) +where v1.c like "t%"; + +select table_name from information_schema.TABLES +where table_schema = "testtets" and table_name like "t%"; + +select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; +show keys * where TABLE_SCHEMA Like "test%"; +show keys where INDEX_NAME = "a_data"; + +show tables like 't%'; +--replace_column 15 # 16 # +show tables * from test where table_name like 't%'; +--replace_column 12 # 13 # +show table status; +show full columns from t3 like "a%"; +show full columns from mysql.db like "Insert%"; +show full columns from v1; +select * from information_schema.COLUMNS where table_name="t1" +and column_name= "a"; +show columns * where table_name = "t1"; + +drop view v1; +drop tables testtets.t4, testtets.t1, t2, t3; +drop database testtets; + +# Test for information_schema.CHARACTER_SETS & +# SHOW CHARACTER SET + +select * from information_schema.CHARACTER_SETS +where CHARACTER_SET_NAME like 'latin1%'; +SHOW CHARACTER SET LIKE 'latin1%'; +SHOW CHARACTER SET * LIKE 'latin1%'; +SHOW CHARACTER SET WHERE CHARACTER_SET_NAME like 'latin1%'; +SHOW CHARACTER SET CHARACTER_SET_NAME WHERE CHARACTER_SET_NAME like 'latin1%'; +SHOW CHARACTER SET * WHERE CHARACTER_SET_NAME like 'latin1%'; + +# Test for information_schema.COLLATIONS & +# SHOW COLLATION + +select * from information_schema.COLLATIONS +where COLLATION_NAME like 'latin1%'; +SHOW COLLATION LIKE 'latin1%'; +SHOW COLLATION * LIKE 'latin1%'; +SHOW COLLATION WHERE COLLATION_NAME like 'latin1%'; +SHOW COLLATION COLLATION_NAME WHERE COLLATION_NAME like 'latin1%'; +SHOW COLLATION * WHERE COLLATION_NAME like 'latin1%'; + +select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY +where COLLATION_NAME like 'latin1%'; + +# Test for information_schema.ROUTINES & +# + +create function sub1(i int) returns int + return i+1; +delimiter |; +create procedure sel2() +begin + select * from t1; + select * from t2; +end| +delimiter ;| + +--replace_column 5 # 6 # +show procedure status; +--replace_column 5 # 6 # +show function status; +select a.ROUTINE_NAME from information_schema.ROUTINES a, +information_schema.SCHEMATA b where +a.ROUTINE_SCHEMA = b.SCHEMA_NAME; +--replace_column 3 # +explain select a.ROUTINE_NAME from information_schema.ROUTINES a, +information_schema.SCHEMATA b where +a.ROUTINE_SCHEMA = b.SCHEMA_NAME; + +select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, +mysql.proc b where a.ROUTINE_NAME = b.name; +select count(*) from information_schema.ROUTINES; + +# +# Test for views +# +create view v0 (c) as select schema_name from information_schema.SCHEMATA; +select * from v0; +--replace_column 3 # +explain select * from v0; +create view v1 (c) as select table_name from information_schema.TABLES +where table_name="v1"; +select * from v1; +create view v2 (c) as select column_name from information_schema.COLUMNS +where table_name="v2"; +select * from v2; +create view v3 (c) as select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS +where CHARACTER_SET_NAME like "latin1%"; +select * from v3; +create view v4 (c) as select COLLATION_NAME from information_schema.COLLATIONS +where COLLATION_NAME like "latin1%"; +select * from v4; +show keys from v4; +select * from information_schema.VIEWS where TABLE_NAME like "v%"; +drop view v0, v1, v2, v3, v4; + +# +# Test for privileges tables +# +create table t1 (a int); +grant select,update,insert on t1 to mysqltest_1@localhost; +grant select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +grant all on test.* to mysqltest_1@localhost with grant option; +select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_1%'; +select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%'; +select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%'; +select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +drop table t1; + + +# +# Test for KEY_COLUMN_USAGE & TABLE_CONSTRAINTS tables +# + +create table t1 (a int null, primary key(a)); +alter table t1 add constraint constraint_1 unique (a); +alter table t1 add constraint unique key_1(a); +alter table t1 add constraint constraint_2 unique key_2(a); +show create table t1; +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_SCHEMA= "test"; +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_SCHEMA= "test"; +drop table t1; + +CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), +FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE, +FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE CASCADE) ENGINE=INNODB; +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_SCHEMA= "test"; +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_SCHEMA= "test"; + +connect (user1,localhost,mysqltest_1,,); +connection user1; +select table_name from information_schema.TABLES where table_schema like "test%"; +select table_name,column_name from information_schema.COLUMNS where table_schema like "test%"; +select ROUTINE_NAME from information_schema.ROUTINES; +disconnect user1; +connection default; +delete from mysql.user where user='mysqltest_1'; +drop table t2; +drop table t1; +drop procedure sel2; +drop function sub1; + +create table t1(a int); +create view v1 (c) as select a from t1 with check option; +create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION; +create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION; +select * from information_schema.views; +grant select (a) on test.t1 to joe@localhost with grant option; +select * from INFORMATION_SCHEMA.COLUMN_PRIVILEGES; +select * from INFORMATION_SCHEMA.TABLE_PRIVILEGES; +drop view v1, v2, v3; +drop table t1; +delete from mysql.user where user='joe'; +delete from mysql.db where user='joe'; +delete from mysql.tables_priv where user='joe'; +delete from mysql.columns_priv where user='joe'; +flush privileges; + +delimiter //; +create procedure px5 () +begin +declare v int; +declare c cursor for select version from +information_schema.tables; +open c; +fetch c into v; +select v; +close c; +end;// + +call px5()// +call px5()// +delimiter ;// + + + + +
\ No newline at end of file diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index 8885f69e60c..0a86c1cd145 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -299,5 +299,5 @@ drop table t1; # create dedicated error code for this and # and change my_printf_error() to my_error ---error 1105 +--error 1391 create table t1 (c char(10), index (c(0))); diff --git a/mysql-test/t/mix_innodb_myisam_binlog-master.opt b/mysql-test/t/mix_innodb_myisam_binlog-master.opt new file mode 100644 index 00000000000..cb48f1aaf60 --- /dev/null +++ b/mysql-test/t/mix_innodb_myisam_binlog-master.opt @@ -0,0 +1 @@ +--loose-innodb_lock_wait_timeout=2 diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test index 00be4c83efc..11d3af11c42 100644 --- a/mysql-test/t/mix_innodb_myisam_binlog.test +++ b/mysql-test/t/mix_innodb_myisam_binlog.test @@ -184,4 +184,36 @@ select a from t1 order by a; # check that savepoints work :) --replace_column 5 # show binlog events from 95; +# Test for BUG#5714, where a MyISAM update in the transaction used to +# release row-level locks in InnoDB + +connect (con3,localhost,root,,); + +connection con3; +delete from t1; +delete from t2; +--disable_warnings +alter table t2 type=MyISAM; +--enable_warnings +insert into t1 values (1); +begin; +select * from t1 for update; + +connection con2; +select (@before:=unix_timestamp())*0; # always give repeatable output +begin; +send select * from t1 for update; + +connection con3; +insert into t2 values (20); + +connection con2; +--error 1205 +reap; +select (@after:=unix_timestamp())*0; # always give repeatable output +# verify that innodb_lock_wait_timeout was exceeded. When there was +# the bug, the reap would return immediately after the insert into t2. +select (@after-@before) >= 2; + +# cleanup drop table t1,t2; diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index 95b616fc7b2..fd7fe0e60d8 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -1,7 +1,7 @@ -- source include/have_ndb.inc --disable_warnings -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; --enable_warnings ################################################ @@ -472,5 +472,11 @@ system rm var/master-data/test/t9.frm ; # MySQL Server will have been restarted because it has a # ndb_autodiscover2-master.opt file. +create table t10 ( + a int not null primary key, + b blob +) engine=ndb; +insert into t10 values (1, 'kalle'); +--exec $NDB_TOOLS_DIR/ndb_drop_table -d test `$NDB_TOOLS_DIR/ndb_show_tables | grep BLOB` > /dev/null 2>&1 || true diff --git a/mysql-test/t/ndb_autodiscover2.test b/mysql-test/t/ndb_autodiscover2.test index cce75d5ca4f..11e1cc204f7 100644 --- a/mysql-test/t/ndb_autodiscover2.test +++ b/mysql-test/t/ndb_autodiscover2.test @@ -13,4 +13,7 @@ show status like 'handler_discover%'; drop table t9; +--error 1296 +select * from t10; +drop table t10; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index b62d2a8e0e1..2671223ada8 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -361,6 +361,21 @@ drop table test.t1, t2; drop database mysqltest; # +# BUG#6031 - DROP DATABASE doesn't drop database on first try +# + +--disable_warnings +drop database if exists ndbtest1; +--enable_warnings + +create database ndbtest1; +use ndbtest1; +create table t1(id int) engine=ndbcluster; +drop database ndbtest1; +--error 1008 +drop database ndbtest1; + +# # test support of char(0) # diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test index 64291c8ab97..53177511bc6 100644 --- a/mysql-test/t/ndb_index_ordered.test +++ b/mysql-test/t/ndb_index_ordered.test @@ -1,7 +1,7 @@ -- source include/have_ndb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1, test1, test2; --enable_warnings # @@ -146,3 +146,29 @@ select * from t1 use index (bc) where b IS NULL and c = 2 order by a; select * from t1 use index (bc) where b < 4 order by a; select * from t1 use index (bc) where b IS NOT NULL order by a; drop table t1; + +# +# Bug #6435 +CREATE TABLE test1 ( +SubscrID int(11) NOT NULL auto_increment, +UsrID int(11) NOT NULL default '0', +PRIMARY KEY (SubscrID), +KEY idx_usrid (UsrID) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; + +INSERT INTO test1 VALUES (2,224),(3,224),(1,224); + +CREATE TABLE test2 ( +SbclID int(11) NOT NULL auto_increment, +SbcrID int(11) NOT NULL default '0', +PRIMARY KEY (SbclID), +KEY idx_sbcrid (SbcrID) +) ENGINE=ndbcluster DEFAULT CHARSET=latin1; + +INSERT INTO test2 VALUES (3,2),(1,1),(2,1),(4,2); +select * from test1 order by 1; +select * from test2 order by 1; +SELECT s.SubscrID,l.SbclID FROM test1 s left JOIN test2 l ON +l.SbcrID=s.SubscrID WHERE s.UsrID=224 order by 1, 2; +drop table test1; +drop table test2; diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 027443c485a..4bc6a4f051a 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -122,3 +122,70 @@ explain select * from t1 where i=2 or i is null; select count(*) from t1 where i=2 or i is null; drop table t1; +# +# NULL has its own type BINARY(0) by default. +# But NULL should be weaker than a constant +# when mixing charsets/collations +# +set names latin2; +# Check that result type is taken from a non-null string +create table t1 select + null as c00, + if(1, null, 'string') as c01, + if(0, null, 'string') as c02, + ifnull(null, 'string') as c03, + ifnull('string', null) as c04, + case when 0 then null else 'string' end as c05, + case when 1 then null else 'string' end as c06, + coalesce(null, 'string') as c07, + coalesce('string', null) as c08, + least('string',null) as c09, + least(null, 'string') as c10, + greatest('string',null) as c11, + greatest(null, 'string') as c12, + nullif('string', null) as c13, + nullif(null, 'string') as c14, + trim('string' from null) as c15, + trim(null from 'string') as c16, + substring_index('string', null, 1) as c17, + substring_index(null, 'string', 1) as c18, + elt(1, null, 'string') as c19, + elt(1, 'string', null) as c20, + concat('string', null) as c21, + concat(null, 'string') as c22, + concat_ws('sep', 'string', null) as c23, + concat_ws('sep', null, 'string') as c24, + concat_ws(null, 'string', 'string') as c25, + make_set(3, 'string', null) as c26, + make_set(3, null, 'string') as c27, + export_set(3, null, 'off', 'sep') as c29, + export_set(3, 'on', null, 'sep') as c30, + export_set(3, 'on', 'off', null) as c31, + replace(null, 'from', 'to') as c32, + replace('str', null, 'to') as c33, + replace('str', 'from', null) as c34, + insert('str', 1, 2, null) as c35, + insert(null, 1, 2, 'str') as c36, + lpad('str', 10, null) as c37, + rpad(null, 10, 'str') as c38; + +show create table t1; +drop table t1; + +# +# Check that comparison is done according to +# non-null string collation, i.e. case insensitively, +# rather than according to NULL's collation, i.e. case sensitively +# +-- in field +select + case 'str' when 'STR' then 'str' when null then 'null' end as c01, + case 'str' when null then 'null' when 'STR' then 'str' end as c02, + field(null, 'str1', 'str2') as c03, + field('str1','STR1', null) as c04, + field('str1', null, 'STR1') as c05, + 'string' in ('STRING', null) as c08, + 'string' in (null, 'STRING') as c09; + +# Restore charset to the default value. +set names latin1; diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 89c49d087b7..1c2bb9260cb 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -8,7 +8,11 @@ # NOTE: PLEASE SEE THE DETAILED DESCRIPTION AT THE BOTTOM OF THIS FILE # BEFORE ADDING NEW TEST CASES HERE !!! -use test; +--disable_warnings +drop table if exists t5, t6, t7, t8; +drop database if exists mysqltest ; +--enable_warnings + --disable_query_log select '------ basic tests ------' as test_sequence ; --enable_query_log @@ -585,12 +589,9 @@ rename table new_t2 to t2; drop table t2; ## RENAME more than on TABLE within one statement # cases derived from client_test.c: test_rename() ---disable_warnings -drop table if exists t5, t6, t7, t8 ; ---enable_warnings prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; -# rename must fail, tc does not exist +# rename must fail, t7 does not exist --error 1017 execute stmt1 ; create table t7 (a int) ; @@ -859,15 +860,23 @@ select '------ grant/revoke/drop affects a parallel session test ------' --error 1141 show grants for second_user@localhost ; ## create a new user account by using GRANT statements on t9 -grant usage on test.* to second_user@localhost +create database mysqltest; +# create the tables (t1 and t9) used in many tests +use mysqltest; +--disable_query_log +--source include/ps_create.inc +--source include/ps_renew.inc +--enable_query_log +eval use $DB; +grant usage on mysqltest.* to second_user@localhost identified by 'looser' ; -grant select on test.t9 to second_user@localhost +grant select on mysqltest.t9 to second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; #### establish a second session to the new user account -connect (con3,localhost,second_user,looser,test); +connect (con3,localhost,second_user,looser,mysqltest); ## switch to the second session connection con3; # Who am I ? @@ -885,10 +894,10 @@ select a as my_col from t1; #### give access rights to t1 and drop table t9 ## switch back to the first session connection default; -grant select on test.t1 to second_user@localhost +grant select on mysqltest.t1 to second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; -drop table t9 ; +drop table mysqltest.t9 ; show grants for second_user@localhost ; @@ -907,7 +916,7 @@ execute s_t9 ; #### revoke the access rights to t1 ## switch back to the first session connection default; -revoke all privileges on test.t1 from second_user@localhost +revoke all privileges on mysqltest.t1 from second_user@localhost identified by 'looser' ; show grants for second_user@localhost ; @@ -932,8 +941,8 @@ commit ; --error 1141 show grants for second_user@localhost ; - -drop table t1 ; +drop table t1,t9 ; +drop database mysqltest; ##### RULES OF THUMB TO PRESERVE THE SYSTEMATICS OF THE PS TEST CASES ##### diff --git a/mysql-test/t/rpl_charset.test b/mysql-test/t/rpl_charset.test index 839fe5d377b..1bd72d059ab 100644 --- a/mysql-test/t/rpl_charset.test +++ b/mysql-test/t/rpl_charset.test @@ -112,10 +112,10 @@ sync_slave_with_master; # Check that we can't change global.collation_server -error 1105; +error 1387; set global character_set_server=latin2; connection master; -error 1105; +error 1387; set global character_set_server=latin2; # Check that SET ONE_SHOT is really one shot @@ -129,7 +129,7 @@ select @@character_set_server; select @@character_set_server; # ONE_SHOT on not charset/collation stuff is not allowed -error 1105; +error 1382; set one_shot max_join_size=10; # Test of wrong character set numbers; diff --git a/mysql-test/t/rpl_rewrite_db-slave.opt b/mysql-test/t/rpl_rewrite_db-slave.opt new file mode 100644 index 00000000000..b9cd29e9205 --- /dev/null +++ b/mysql-test/t/rpl_rewrite_db-slave.opt @@ -0,0 +1 @@ +"--replicate-rewrite-db=mysqltest1->test" diff --git a/mysql-test/t/rpl_rewrite_db.test b/mysql-test/t/rpl_rewrite_db.test new file mode 100644 index 00000000000..4cc8ae4b676 --- /dev/null +++ b/mysql-test/t/rpl_rewrite_db.test @@ -0,0 +1,19 @@ +source include/master-slave.inc; +--disable_warnings +drop database if exists mysqltest1; +--enable_warnings +create database mysqltest1; + +use mysqltest1; +create table t1 (a int); +insert into t1 values(9); +select * from mysqltest1.t1; +sync_slave_with_master; +show databases like 'mysqltest1'; # should be empty +select * from test.t1; +# cleanup +connection master; +drop table t1; +drop database mysqltest1; +sync_slave_with_master; + diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index c3c0ff5be10..63ddf495347 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -23,7 +23,8 @@ drop table if exists t1, t2, t3, t4; # START SLAVE will fail because it can't read the file (mode 000) # (system error 13) ---error 1201 +--replace_result $MYSQL_TEST_DIR TESTDIR +--error 1105 start slave; system chmod 600 var/slave-data/master.info; # It will fail again because the file is empty so the slave cannot get valuable diff --git a/mysql-test/t/rpl_timezone.test b/mysql-test/t/rpl_timezone.test index 8dff90a84cf..ebb58a9c880 100644 --- a/mysql-test/t/rpl_timezone.test +++ b/mysql-test/t/rpl_timezone.test @@ -76,7 +76,7 @@ select * from t2; # replication # connection master; ---error 1105 +--error 1387 set global time_zone='MET'; # Clean up diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index 2b53bbc528a..d1119499cf1 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -58,7 +58,7 @@ select db1_secret.db(); select * from db1_secret.t1; # ...and not this ---error 1049 +--error 1044 create procedure db1_secret.dummy() begin end; --error 1305 drop procedure db1_secret.dummy; @@ -78,7 +78,7 @@ select db1_secret.db(); select * from db1_secret.t1; # ...and not this ---error 1049 +--error 1044 create procedure db1_secret.dummy() begin end; --error 1305 drop procedure db1_secret.dummy; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 88d1b8c0356..ec1fb3e7452 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1870,13 +1870,28 @@ create procedure bug4904() begin declare continue handler for sqlstate 'HY000' begin end; - create table t2 as select * from t; + create table t2 as select * from t3; end| +-- error 1146 call bug4904()| drop procedure bug4904| +create table t3 (s1 char character set latin1, s2 char character set latin2)| + +create procedure bug4904 () +begin + declare continue handler for sqlstate 'HY000' begin end; + + select s1 from t3 union select s2 from t3; +end| + +call bug4904()| + +drop procedure bug4904| +drop table t3| + # # BUG#336 # diff --git a/mysql-test/t/timezone3-master.opt b/mysql-test/t/timezone3-master.opt new file mode 100644 index 00000000000..6910e6e6e8d --- /dev/null +++ b/mysql-test/t/timezone3-master.opt @@ -0,0 +1 @@ +--timezone=:$MYSQL_TEST_DIR/std_data/Moscow_leap diff --git a/mysql-test/t/timezone3.test b/mysql-test/t/timezone3.test new file mode 100644 index 00000000000..8910783cd85 --- /dev/null +++ b/mysql-test/t/timezone3.test @@ -0,0 +1,59 @@ +# +# Test of handling time zone with leap seconds. +# +# This test should be run with TZ=:$MYSQL_TEST_DIR/std_data/Moscow_leap +# This implies that this test should be run only on systems that interpret +# characters after colon in TZ variable as path to zoneinfo file. +# +# Check that we have successfully set time zone with leap seconds. +--require r/have_moscow_leap_timezone.require +disable_query_log; +select from_unixtime(1072904422); +enable_query_log; + +# Initial clean-up +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Let us check behavior of conversion from broken-down representation +# to time_t representation, for normal, non-existent and ambigious dates +# (This check is similar to the one in timezone2.test in 4.1) +# +create table t1 (i int, c varchar(20)); +# Normal value without DST +insert into t1 values + (unix_timestamp("2004-01-01 00:00:00"), "2004-01-01 00:00:00"); +# Values around and in spring time-gap +insert into t1 values + (unix_timestamp("2004-03-28 01:59:59"), "2004-03-28 01:59:59"), + (unix_timestamp("2004-03-28 02:30:00"), "2004-03-28 02:30:00"), + (unix_timestamp("2004-03-28 03:00:00"), "2004-03-28 03:00:00"); +# Normal value with DST +insert into t1 values + (unix_timestamp('2004-05-01 00:00:00'),'2004-05-01 00:00:00'); +# Ambiguos values (also check for determenism) +insert into t1 values + (unix_timestamp('2004-10-31 01:00:00'),'2004-10-31 01:00:00'), + (unix_timestamp('2004-10-31 02:00:00'),'2004-10-31 02:00:00'), + (unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'), + (unix_timestamp('2004-10-31 04:00:00'),'2004-10-31 04:00:00'), + (unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'); +# Test of leap +insert into t1 values + (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), + (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); + +select i, from_unixtime(i), c from t1; +drop table t1; + +# +# Test for bug #6387 "Queried timestamp values do not match the +# inserted". my_gmt_sec() function was not working properly if we +# had time zone with leap seconds +# +create table t1 (ts timestamp); +insert into t1 values (19730101235900), (20040101235900); +select * from t1; +drop table t1; diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index f842d561dc1..7dc976cf716 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -207,3 +207,20 @@ create trigger tx1 before insert on t1 for each row set new.x1col = 'x'; insert into t1 values ('y'); drop trigger t1.tx1; drop table t1; + +# +# Test for bug #5890 "Triggers fail for DELETE without WHERE". +# If we are going to delete all rows in table but DELETE triggers exist +# we should perform row-by-row deletion instead of using optimized +# delete_all_rows() method. +# +create table t1 (i int) engine=myisam; +insert into t1 values (1), (2); +create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i; +create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i; +set @del_before:=0, @del_after:= 0; +delete from t1; +select @del_before, @del_after; +drop trigger t1.trg1; +drop trigger t1.trg2; +drop table t1; diff --git a/mysys/default.c b/mysys/default.c index 198a6402b8b..d6d84f65d8b 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -37,6 +37,9 @@ #include "m_string.h" #include "m_ctype.h" #include <my_dir.h> +#ifdef __WIN__ +#include <winbase.h> +#endif char *defaults_extra_file=0; @@ -60,10 +63,10 @@ DATADIR, NullS, }; -#define default_ext ".cnf" /* extension for config file */ #ifdef __WIN__ -#include <winbase.h> -#define windows_ext ".ini" +static const char *f_extensions[]= { ".ini", ".cnf", 0 }; +#else +static const char *f_extensions[]= { ".cnf", 0 }; #endif /* @@ -81,8 +84,11 @@ struct handle_option_ctx }; static int search_default_file(Process_option_func func, void *func_ctx, - const char *dir, const char *config_file, - const char *ext); + const char *dir, const char *config_file); +static int search_default_file_with_ext(Process_option_func func, + void *func_ctx, + const char *dir, const char *ext, + const char *config_file); static char *remove_end_comment(char *ptr); @@ -137,8 +143,8 @@ static int search_files(const char *conf_file, int *argc, char ***argv, if (forced_default_file) { - if ((error= search_default_file(func, func_ctx, "", - forced_default_file, "")) < 0) + if ((error= search_default_file_with_ext(func, func_ctx, "", "", + forced_default_file)) < 0) goto err; if (error > 0) { @@ -149,8 +155,7 @@ static int search_files(const char *conf_file, int *argc, char ***argv, } else if (dirname_length(conf_file)) { - if ((error= search_default_file(func, func_ctx, NullS, conf_file, - default_ext)) < 0) + if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0) goto err; } else @@ -158,28 +163,30 @@ static int search_files(const char *conf_file, int *argc, char ***argv, #ifdef __WIN__ char system_dir[FN_REFLEN]; GetWindowsDirectory(system_dir,sizeof(system_dir)); - if ((search_default_file(func, func_ctx, system_dir, conf_file, - windows_ext))) + if ((search_default_file(func, func_ctx, system_dir, conf_file))) goto err; #endif #if defined(__EMX__) || defined(OS2) - if (getenv("ETC") && - (search_default_file(func, func_ctx, getenv("ETC"), conf_file, - default_ext)) < 0) + { + const char *etc; + if ((etc= getenv("ETC")) && + (search_default_file(func, func_ctx, etc, conf_file)) < 0) goto err; + } #endif for (dirs= default_directories ; *dirs; dirs++) { if (**dirs) { - if (search_default_file(func, func_ctx, *dirs, conf_file, default_ext) < 0) + if (search_default_file(func, func_ctx, *dirs, conf_file) < 0) goto err; } else if (defaults_extra_file) { - if (search_default_file(func, func_ctx, NullS, defaults_extra_file, - default_ext) < 0) + if (search_default_file(func, func_ctx, NullS, + defaults_extra_file) < 0) goto err; /* Fatal error */ + } } } @@ -226,22 +233,23 @@ int process_default_option_files(const char *conf_file, return search_files(conf_file, &argc, NULL, &args_used, func, func_ctx); } + /* The option handler for load_defaults. SYNOPSIS - handle_deault_option() - in_ctx Handler context. In this case it is a + handle_deault_option() + in_ctx Handler context. In this case it is a handle_option_ctx structure. - group_name The name of the group the option belongs to. - option The very option to be processed. It is already + group_name The name of the group the option belongs to. + option The very option to be processed. It is already prepared to be used in argv (has -- prefix) DESCRIPTION - - This handler checks whether a group is one of the listed and adds an option - to the array if yes. Some other handler can record, for instance, all groups - and their options, not knowing in advance the names and amount of groups. + This handler checks whether a group is one of the listed and adds an option + to the array if yes. Some other handler can record, for instance, all + groups and their options, not knowing in advance the names and amount of + groups. RETURN 0 - ok @@ -249,12 +257,12 @@ int process_default_option_files(const char *conf_file, */ static int handle_default_option(void *in_ctx, const char *group_name, - const char *option) + const char *option) { char *tmp; - struct handle_option_ctx *ctx; - ctx= (struct handle_option_ctx *) in_ctx; - if(find_type((char *)group_name, ctx->group, 3)) + struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx; + + if (find_type((char *)group_name, ctx->group, 3)) { if (!(tmp= alloc_root(ctx->alloc, (uint) strlen(option) + 1))) return 1; @@ -299,7 +307,7 @@ static int handle_default_option(void *in_ctx, const char *group_name, int load_defaults(const char *conf_file, const char **groups, - int *argc, char ***argv) + int *argc, char ***argv) { DYNAMIC_ARRAY args; TYPELIB group; @@ -405,18 +413,37 @@ void free_defaults(char **argv) } +static int search_default_file(Process_option_func opt_handler, + void *handler_ctx, + const char *dir, + const char *config_file) +{ + char **ext; + + for (ext= (char**) f_extensions; *ext; *ext++) + { + int error; + if ((error= search_default_file_with_ext(opt_handler, handler_ctx, + dir, *ext, + config_file)) < 0) + return error; + } + return 0; +} + + /* Open a configuration file (if exists) and read given options from it SYNOPSIS - search_default_file() + search_default_file_with_ext() opt_handler Option handler function. It is used to process every separate option. handler_ctx Pointer to the structure to store actual parameters of the function. dir directory to read - config_file Name of configuration file ext Extension for configuration file + config_file Name of configuration file group groups to read RETURN @@ -425,9 +452,11 @@ void free_defaults(char **argv) 1 File not found (Warning) */ -static int search_default_file(Process_option_func opt_handler, void *handler_ctx, - const char *dir, const char *config_file, - const char *ext) +static int search_default_file_with_ext(Process_option_func opt_handler, + void *handler_ctx, + const char *dir, + const char *ext, + const char *config_file) { char name[FN_REFLEN+10], buff[4096], curr_gr[4096], *ptr, *end; char *value, option[4096]; @@ -618,10 +647,11 @@ static char *remove_end_comment(char *ptr) void print_defaults(const char *conf_file, const char **groups) { #ifdef __WIN__ - bool have_ext=fn_ext(conf_file)[0] != 0; + my_bool have_ext= fn_ext(conf_file)[0] != 0; #endif - char name[FN_REFLEN]; + char name[FN_REFLEN], **ext; const char **dirs; + puts("\nDefault options are read from the following files in the given order:"); if (dirname_length(conf_file)) @@ -630,27 +660,43 @@ void print_defaults(const char *conf_file, const char **groups) { #ifdef __WIN__ GetWindowsDirectory(name,sizeof(name)); - printf("%s\\%s%s ",name,conf_file,have_ext ? "" : windows_ext); + if (!have_ext) + { + for (ext= (char**) f_extensions; *ext; *ext++) + printf("%s\\%s%s ", name, conf_file, *ext); + } + else + printf("%s\\%s ", name, conf_file); #endif #if defined(__EMX__) || defined(OS2) - if (getenv("ETC")) - printf("%s\\%s%s ", getenv("ETC"), conf_file, default_ext); + { + const char *etc; + + if ((etc= getenv("ETC"))) + { + for (ext= (char**) f_extensions; *ext; *ext++) + printf("%s\\%s%s ", etc, conf_file, *ext); + } + } #endif for (dirs=default_directories ; *dirs; dirs++) { - const char *pos; - char *end; - if (**dirs) - pos= *dirs; - else if (defaults_extra_file) - pos= defaults_extra_file; - else - continue; - end=convert_dirname(name, pos, NullS); - if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ - *end++='.'; - strxmov(end,conf_file,default_ext," ",NullS); - fputs(name,stdout); + for (ext= (char**) f_extensions; *ext; *ext++) + { + const char *pos; + char *end; + if (**dirs) + pos= *dirs; + else if (defaults_extra_file) + pos= defaults_extra_file; + else + continue; + end= convert_dirname(name, pos, NullS); + if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ + *end++='.'; + strxmov(end, conf_file, *ext, " ", NullS); + fputs(name,stdout); + } } puts(""); } diff --git a/mysys/my_error.c b/mysys/my_error.c index 8a377f63c7e..175f8cf516b 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -22,6 +22,15 @@ /* Define some external variables for error handling */ +/* + WARNING! + my_error family functions have to be used according following rules: + - if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N)) + - if message registered use my_error(ER_CODE, MYF(N), ...). + - With some special text of errror message use: + my_printf_error(ER_CODE, format, MYF(N), ...) +*/ + const char ** NEAR my_errmsg[MAXMAPS]={0,0,0,0}; char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; @@ -41,107 +50,22 @@ char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; the length value is ignored. */ -int my_error(int nr,myf MyFlags, ...) +int my_error(int nr, myf MyFlags, ...) { - va_list ap; - uint olen, plen; - reg1 const char *tpos; - reg2 char *endpos; - char * par; - char ebuff[ERRMSGSIZE+20]; - int prec_chars; /* output precision */ - my_bool prec_supplied; + const char *format; + va_list args; + char ebuff[ERRMSGSIZE + 20]; DBUG_ENTER("my_error"); - LINT_INIT(prec_chars); /* protected by prec_supplied */ - va_start(ap,MyFlags); DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno)); if (nr / ERRMOD == GLOB && my_errmsg[GLOB] == 0) init_glob_errs(); + format= my_errmsg[nr / ERRMOD][nr % ERRMOD]; - olen=(uint) strlen(tpos=my_errmsg[nr / ERRMOD][nr % ERRMOD]); - endpos=ebuff; - - while (*tpos) - { - if (tpos[0] != '%') - { - *endpos++= *tpos++; /* Copy ordinary char */ - continue; - } - if (*++tpos == '%') /* test if %% */ - { - olen--; - } - else - { - /* - Skip size/precision flags to be compatible with printf. - The only size/precision flag supported is "%.*s". - If "%.*u" or "%.*d" are encountered, the precision number is read - from the variable argument list but its value is ignored. - */ - prec_supplied= 0; - if (*tpos== '.') - { - tpos++; - olen--; - if (*tpos == '*') - { - tpos++; - olen--; - prec_chars= va_arg(ap, int); /* get length parameter */ - prec_supplied= 1; - } - } - - if (!prec_supplied) - { - while (my_isdigit(&my_charset_latin1, *tpos) || *tpos == '.' || - *tpos == '-') - tpos++; - - if (*tpos == 'l') /* Skip 'l' argument */ - tpos++; - } - - if (*tpos == 's') /* String parameter */ - { - par= va_arg(ap, char *); - plen= (uint) strlen(par); - if (prec_supplied && prec_chars > 0) - plen= min((uint)prec_chars, plen); - if (olen + plen < ERRMSGSIZE+2) /* Replace if possible */ - { - strmake(endpos, par, plen); - endpos+= plen; - tpos++; - olen+= plen-2; - continue; - } - } - else if (*tpos == 'd' || *tpos == 'u') /* Integer parameter */ - { - register int iarg; - iarg= va_arg(ap, int); - if (*tpos == 'd') - plen= (uint) (int10_to_str((long) iarg, endpos, -10) - endpos); - else - plen= (uint) (int10_to_str((long) (uint) iarg, endpos, 10) - endpos); - if (olen + plen < ERRMSGSIZE+2) /* Replace parameter if possible */ - { - endpos+= plen; - tpos++; - olen+= plen-2; - continue; - } - } - } - *endpos++= '%'; /* % used as % or unknown code */ - } - *endpos= '\0'; /* End of errmessage */ - va_end(ap); + va_start(args,MyFlags); + (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args); + va_end(args); DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags)); } @@ -160,11 +84,14 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...) { va_list args; char ebuff[ERRMSGSIZE+20]; + DBUG_ENTER("my_printf_error"); + DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d Format: %s", + error, MyFlags, errno, format)); va_start(args,MyFlags); - (void) vsprintf (ebuff,format,args); + (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args); va_end(args); - return (*error_handler_hook)(error, ebuff, MyFlags); + DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags)); } /* diff --git a/mysys/my_init.c b/mysys/my_init.c index 0ef938b434c..c32fcfe6a09 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -42,8 +42,8 @@ static void netware_init(); #define netware_init() #endif - -my_bool my_init_done=0; +my_bool my_init_done= 0; +uint mysys_usage_id= 0; /* Incremented for each my_init() */ static ulong atoi_octal(const char *str) { @@ -51,7 +51,7 @@ static ulong atoi_octal(const char *str) while (*str && my_isspace(&my_charset_latin1, *str)) str++; str2int(str, - (*str == '0' ? 8 : 10), /* Octalt or decimalt */ + (*str == '0' ? 8 : 10), /* Octalt or decimalt */ 0, INT_MAX, &tmp); return (ulong) tmp; } @@ -74,6 +74,9 @@ my_bool my_init(void) if (my_init_done) return 0; my_init_done=1; + mysys_usage_id++; + my_umask= 0660; /* Default umask for new files */ + my_umask_dir= 0700; /* Default umask for new directories */ #if defined(THREAD) && defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ #endif diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 6dcf58b44e2..f1ef357421b 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -733,6 +733,7 @@ extern "C" { int param, unsigned long long * value); int ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator*, int param, const char ** value); + int ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **); #ifdef __cplusplus } #endif diff --git a/ndb/include/ndb_types.h b/ndb/include/ndb_types.h index a2988dbae78..64b3f517934 100644 --- a/ndb/include/ndb_types.h +++ b/ndb/include/ndb_types.h @@ -21,11 +21,11 @@ #ifndef NDB_TYPES_H #define NDB_TYPES_H -typedef char Int8; +typedef signed char Int8; typedef unsigned char Uint8; -typedef short Int16; +typedef signed short Int16; typedef unsigned short Uint16; -typedef int Int32; +typedef signed int Int32; typedef unsigned int Uint32; typedef unsigned int UintR; @@ -45,10 +45,10 @@ typedef uintptr_t UintPtr; #if defined(WIN32) || defined(NDB_WIN32) typedef unsigned __int64 Uint64; -typedef __int64 Int64; +typedef signed __int64 Int64; #else typedef unsigned long long Uint64; -typedef long long Int64; +typedef signed long long Int64; #endif #endif diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 51a6895648f..a3115076624 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -369,7 +369,7 @@ public: */ bool getDistributionKey() const; /** @} *******************************************************************/ - + #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL void setTupleKey(bool); bool getTupleKey() const; @@ -490,6 +490,18 @@ public: * Get column definition via index in table. * @return null if none existing name */ + Column* getColumn(const int attributeId); + + /** + * Get column definition via name. + * @return null if none existing name + */ + Column* getColumn(const char * name); + + /** + * Get column definition via index in table. + * @return null if none existing name + */ const Column* getColumn(const int attributeId) const; /** @} *******************************************************************/ diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp index bb217adab5f..19aa604e4a1 100644 --- a/ndb/include/util/Bitmask.hpp +++ b/ndb/include/util/Bitmask.hpp @@ -105,6 +105,11 @@ public: static void bitXOR(unsigned size, Uint32 data[], const Uint32 data2[]); /** + * bitXORC - Bitwise (x ^ ~y) into first operand. + */ + static void bitXORC(unsigned size, Uint32 data[], const Uint32 data2[]); + + /** * contains - Check if all bits set in data2 are set in data */ static bool contains(unsigned size, Uint32 data[], const Uint32 data2[]); @@ -261,6 +266,14 @@ BitmaskImpl::bitXOR(unsigned size, Uint32 data[], const Uint32 data2[]) } } +inline void +BitmaskImpl::bitXORC(unsigned size, Uint32 data[], const Uint32 data2[]) +{ + for (unsigned i = 0; i < size; i++) { + data[i] ^= ~data2[i]; + } +} + inline bool BitmaskImpl::contains(unsigned size, Uint32 data[], const Uint32 data2[]) { @@ -452,6 +465,12 @@ public: BitmaskPOD<size>& bitXOR(const BitmaskPOD<size>& mask2); /** + * bitXORC - Bitwise (x ^ ~y) into first operand. + */ + static void bitXORC(Uint32 data[], const Uint32 data2[]); + BitmaskPOD<size>& bitXORC(const BitmaskPOD<size>& mask2); + + /** * contains - Check if all bits set in data2 (that) are also set in data (this) */ static bool contains(Uint32 data[], const Uint32 data2[]); @@ -713,6 +732,21 @@ BitmaskPOD<size>::bitXOR(const BitmaskPOD<size>& mask2) } template <unsigned size> +inline void +BitmaskPOD<size>::bitXORC(Uint32 data[], const Uint32 data2[]) +{ + BitmaskImpl::bitXORC(size,data, data2); +} + +template <unsigned size> +inline BitmaskPOD<size>& +BitmaskPOD<size>::bitXORC(const BitmaskPOD<size>& mask2) +{ + BitmaskPOD<size>::bitXORC(rep.data, mask2.rep.data); + return *this; +} + +template <unsigned size> char * BitmaskPOD<size>::getText(const Uint32 data[], char* buf) { diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp index 3860b9ca84b..2fad991e5f8 100644 --- a/ndb/include/util/SocketServer.hpp +++ b/ndb/include/util/SocketServer.hpp @@ -37,7 +37,7 @@ public: public: virtual ~Session() {} virtual void runSession(){} - virtual void stopSession(){} + virtual void stopSession(){ m_stop = true; } protected: friend class SocketServer; friend void* sessionThread_C(void*); @@ -98,6 +98,8 @@ public: */ void stopSessions(bool wait = false); + void foreachSession(void (*f)(SocketServer::Session*, void*), void *data); + private: struct SessionInstance { Service * m_service; diff --git a/ndb/src/common/Makefile.am b/ndb/src/common/Makefile.am index 7fcf2cab636..8733205eca2 100644 --- a/ndb/src/common/Makefile.am +++ b/ndb/src/common/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = portlib debugger util logger transporter mgmcommon editline +SUBDIRS = portlib debugger util logger transporter mgmcommon noinst_LTLIBRARIES = libcommon.la diff --git a/ndb/src/common/Makefile_old b/ndb/src/common/Makefile_old deleted file mode 100644 index ebde75bf3ec..00000000000 --- a/ndb/src/common/Makefile_old +++ /dev/null @@ -1,15 +0,0 @@ -include .defs.mk - -LIB_DIRS := \ - portlib \ - debugger \ - util \ - logger - -ifneq ($(USE_EDITLINE), N) -LIB_DIRS += editline -endif - -DIRS := transporter mgmcommon - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/debugger/Makefile_old b/ndb/src/common/debugger/Makefile_old deleted file mode 100644 index ac3a4475a54..00000000000 --- a/ndb/src/common/debugger/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := kernel -DIRS := signaldata - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := trace - -SOURCES = SignalLoggerManager.cpp DebuggerNames.cpp BlockNames.cpp LogLevel.cpp EventLogger.cpp GrepError.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/debugger/signaldata/Makefile_old b/ndb/src/common/debugger/signaldata/Makefile_old deleted file mode 100644 index bd00667b482..00000000000 --- a/ndb/src/common/debugger/signaldata/Makefile_old +++ /dev/null @@ -1,33 +0,0 @@ -include .defs.mk - -TYPE := ndbapi - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := signaldataprint - -SOURCES = TcKeyReq.cpp TcKeyConf.cpp TcKeyRef.cpp \ - TcRollbackRep.cpp \ - TupKey.cpp TupCommit.cpp LqhKey.cpp \ - FsOpenReq.cpp FsCloseReq.cpp FsRef.cpp FsConf.cpp FsReadWriteReq.cpp\ - SignalDataPrint.cpp SignalNames.cpp \ - ContinueB.cpp DihContinueB.cpp NdbfsContinueB.cpp \ - CloseComReqConf.cpp PackedSignal.cpp PrepFailReqRef.cpp \ - GCPSave.cpp DictTabInfo.cpp \ - AlterTable.cpp AlterTab.cpp \ - CreateTrig.cpp AlterTrig.cpp DropTrig.cpp \ - FireTrigOrd.cpp TrigAttrInfo.cpp \ - CreateIndx.cpp AlterIndx.cpp DropIndx.cpp TcIndx.cpp \ - IndxKeyInfo.cpp IndxAttrInfo.cpp \ - FsAppendReq.cpp ScanTab.cpp \ - BackupImpl.cpp BackupSignalData.cpp \ - UtilSequence.cpp UtilPrepare.cpp UtilDelete.cpp UtilExecute.cpp \ - LqhFrag.cpp DropTab.cpp PrepDropTab.cpp LCP.cpp MasterLCP.cpp \ - CopyGCI.cpp SystemError.cpp StartRec.cpp NFCompleteRep.cpp \ - FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \ - SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \ - CntrStart.cpp ReadNodesConf.cpp \ - UtilLock.cpp TuxMaint.cpp TupAccess.cpp AccLock.cpp \ - LqhTrans.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp index 3314f0bd097..a4cee38e06f 100644 --- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp +++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp @@ -16,65 +16,9 @@ -#include "GlobalSignalNumbers.h" -#include "signaldata/SignalDataPrint.hpp" -#include "signaldata/TcKeyReq.hpp" -#include "signaldata/TcKeyConf.hpp" -#include "signaldata/TcKeyRef.hpp" -#include "signaldata/LqhKey.hpp" -#include "signaldata/TupKey.hpp" -#include "signaldata/TupCommit.hpp" -#include "signaldata/FsOpenReq.hpp" -#include "signaldata/FsCloseReq.hpp" -#include "signaldata/FsReadWriteReq.hpp" -#include "signaldata/FsRef.hpp" -#include "signaldata/FsConf.hpp" -#include "signaldata/CloseComReqConf.hpp" -#include "signaldata/PackedSignal.hpp" -#include "signaldata/PrepFailReqRef.hpp" -#include "signaldata/DictTabInfo.hpp" -#include "signaldata/AlterTable.hpp" -#include "signaldata/AlterTab.hpp" -#include "signaldata/CreateTrig.hpp" -#include "signaldata/AlterTrig.hpp" -#include "signaldata/DropTrig.hpp" -#include "signaldata/FireTrigOrd.hpp" -#include "signaldata/TrigAttrInfo.hpp" -#include "signaldata/CreateIndx.hpp" -#include "signaldata/AlterIndx.hpp" -#include "signaldata/DropIndx.hpp" -#include "signaldata/TcIndx.hpp" -#include "signaldata/IndxKeyInfo.hpp" -#include "signaldata/IndxAttrInfo.hpp" -#include <signaldata/FsAppendReq.hpp> -#include <signaldata/BackupSignalData.hpp> -#include <signaldata/BackupImpl.hpp> -#include <signaldata/UtilSequence.hpp> -#include <signaldata/UtilPrepare.hpp> -#include <signaldata/UtilExecute.hpp> -#include <signaldata/ScanTab.hpp> -#include <signaldata/ScanFrag.hpp> -#include <signaldata/LqhFrag.hpp> -#include <signaldata/LqhTransConf.hpp> -#include <signaldata/DropTab.hpp> -#include <signaldata/PrepDropTab.hpp> -#include <signaldata/LCP.hpp> -#include <signaldata/MasterLCP.hpp> -#include <signaldata/CopyGCIReq.hpp> -#include <signaldata/SystemError.hpp> -#include <signaldata/StartRec.hpp> -#include <signaldata/NFCompleteRep.hpp> -#include <signaldata/SignalDroppedRep.hpp> -#include <signaldata/FailRep.hpp> -#include <signaldata/DisconnectRep.hpp> -#include <signaldata/SumaImpl.hpp> -#include <signaldata/NdbSttor.hpp> -#include <signaldata/CreateFragmentation.hpp> -#include <signaldata/UtilLock.hpp> -#include <signaldata/CntrStart.hpp> -#include <signaldata/ReadNodesConf.hpp> -#include <signaldata/TuxMaint.hpp> -#include <signaldata/AccLock.hpp> +#include <GlobalSignalNumbers.h> +#include <signaldata/SignalData.hpp> +#include <signaldata/SignalDataPrint.hpp> /** * This is the register @@ -254,9 +198,11 @@ SignalDataPrintFunctions[] = { ,{ 0, 0 } }; -template class Bitmask<1>; -template class Bitmask<2>; -template class Bitmask<4>; +#include <Bitmask.hpp> + template struct BitmaskPOD<1>; template struct BitmaskPOD<2>; template struct BitmaskPOD<4>; +template class Bitmask<1>; +template class Bitmask<2>; +template class Bitmask<4>; diff --git a/ndb/src/common/editline/MANIFEST b/ndb/src/common/editline/MANIFEST deleted file mode 100644 index dc8b4b36f88..00000000000 --- a/ndb/src/common/editline/MANIFEST +++ /dev/null @@ -1,15 +0,0 @@ -File Name Description --------------------------------------------------------- -README Release notes and copyright -MANIFEST This shipping list -Make.os9 OS-9 makefile -Makefile Unix makefile -complete.c Filename completion routines -editline.3 Manual page for editline library -editline.c Line-editing routines -editline_internal.h Internal library header file -os9.h OS-9-specific declarations -sysos9.c OS-9-specific routines -sysunix.c Unix-specific routines -testit.c Test driver -unix.h Unix-specific declarations diff --git a/ndb/src/common/editline/Makefile.am b/ndb/src/common/editline/Makefile.am deleted file mode 100644 index 4f53bdc6326..00000000000 --- a/ndb/src/common/editline/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ - -noinst_LIBRARIES = libeditline.a - -libeditline_a_SOURCES = complete.c editline.c sysunix.c - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/ndb/include -DEFS = -DANSI_ARROWS -DHAVE_TCGETATTR -DSYS_UNIX - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/ndb/src/common/editline/Makefile_old b/ndb/src/common/editline/Makefile_old deleted file mode 100644 index 800df8f0f31..00000000000 --- a/ndb/src/common/editline/Makefile_old +++ /dev/null @@ -1,18 +0,0 @@ -include .defs.mk - -TYPE := - -ARCHIVE_TARGET := editline - -CFLAGS += -DANSI_ARROWS -DHAVE_TCGETATTR -DSYS_UNIX - -ifeq ($(NDB_OS), WIN32) -SOURCES = editline_win32.c -else -SOURCES = complete.c editline.c sysunix.c -endif - -DIRS := test - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/common/editline/README b/ndb/src/common/editline/README deleted file mode 100644 index 537c7bd8611..00000000000 --- a/ndb/src/common/editline/README +++ /dev/null @@ -1,53 +0,0 @@ --- -NOTE: This version has been modified by Ericsson/Alzato. Please -see the cvs changelog for more details. --- - -$Revision: 1.2 $ - -This is a line-editing library. It can be linked into almost any -program to provide command-line editing and recall. - -It is call-compatible with the FSF readline library, but it is a -fraction of the size (and offers fewer features). It does not use -standard I/O. It is distributed under a "C News-like" copyright. - -Configuration is done in the Makefile. Type "make testit" to get -a small slow shell for testing. - -This contains some changes since the posting to comp.sources.misc: - - Bugfix for completion on absolute pathnames. - - Better handling of M-n versus showing raw 8bit chars. - - Better signal handling. - - Now supports termios/termio/sgttyb ioctl's. - - Add M-m command to toggle how 8bit data is displayed. -The following changes, made since the last public release, come from -J.G. Vons <vons@cesar.crbca1.sinet.slb.com>: - - History-searching no longer redraws the line wrong - - Added ESC-ESC as synonym for ESC-? - - SIGQUIT (normally ^\) now sends a signal, not indicating EOF. - - Fixed some typo's and unclear wording in the manpage. - - Fixed completion when all entries shared a common prefix. - - Fixed some meta-char line-redrawing bugs. - -Enjoy, - Rich $alz - <rsalz@osf.org> - - Copyright 1992,1993 Simmule Turner and Rich Salz. All rights reserved. - - This software is not subject to any license of the American Telephone - and Telegraph Company or of the Regents of the University of California. - - Permission is granted to anyone to use this software for any purpose on - any computer system, and to alter it and redistribute it freely, subject - to the following restrictions: - 1. The authors are not responsible for the consequences of use of this - software, no matter how awful, even if they arise from flaws in it. - 2. The origin of this software must not be misrepresented, either by - explicit claim or by omission. Since few users ever read sources, - credits must appear in the documentation. - 3. Altered versions must be plainly marked as such, and must not be - misrepresented as being the original software. Since few users - ever read sources, credits must appear in the documentation. - 4. This notice may not be removed or altered. diff --git a/ndb/src/common/editline/complete.c b/ndb/src/common/editline/complete.c deleted file mode 100644 index c524a88c678..00000000000 --- a/ndb/src/common/editline/complete.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -*- c-basic-offset: 4; -*- -** $Revision: 1.8 $ -** -** History and file completion functions for editline library. -*/ -#include "editline_internal.h" - - -/* -** strcmp-like sorting predicate for qsort. -*/ -static int -compare(const void *p1, const void *p2) -{ - const char **v1; - const char **v2; - - v1 = (const char **)p1; - v2 = (const char **)p2; - return strcmp(*v1, *v2); -} - -/* -** Fill in *avp with an array of names that match file, up to its length. -** Ignore . and .. . -*/ -static int -FindMatches(char *dir, char *file, char ***avp) -{ - char **av; - char **new; - char *p; - DIR *dp; - struct dirent *ep; - size_t ac; - size_t len; - - if ((dp = opendir(dir)) == NULL) - return 0; - - av = NULL; - ac = 0; - len = strlen(file); - while ((ep = readdir(dp)) != NULL) { - p = ep->d_name; - if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))) - continue; - if (len && strncmp(p, file, len) != 0) - continue; - - if ((ac % MEM_INC) == 0) { - if ((new = malloc(sizeof(char*) * (ac + MEM_INC))) == NULL) - break; - if (ac) { - memcpy(new, av, ac * sizeof (char **)); - free(av); - } - *avp = av = new; - } - - if ((av[ac] = strdup(p)) == NULL) { - if (ac == 0) - free(av); - break; - } - ac++; - } - - /* Clean up and return. */ - (void)closedir(dp); - if (ac) - qsort(av, ac, sizeof (char **), compare); - return ac; -} - -/* -** Split a pathname into allocated directory and trailing filename parts. -*/ -static int -SplitPath(char *path, char **dirpart, char ** filepart) -{ - static char DOT[] = "."; - char *dpart; - char *fpart; - - if ((fpart = strrchr(path, '/')) == NULL) { - if ((dpart = strdup(DOT)) == NULL) - return -1; - if ((fpart = strdup(path)) == NULL) { - free(dpart); - return -1; - } - } - else { - if ((dpart = strdup(path)) == NULL) - return -1; - dpart[fpart - path + 1] = '\0'; - if ((fpart = strdup(++fpart)) == NULL) { - free(dpart); - return -1; - } - } - *dirpart = dpart; - *filepart = fpart; - return 0; -} - -/* -** Attempt to complete the pathname, returning an allocated copy. -** Fill in *unique if we completed it, or set it to 0 if ambiguous. -*/ -char * -rl_complete(char *pathname,int *unique) -{ - char **av; - char *dir; - char *file; - char *new; - char *p; - size_t ac; - size_t end; - size_t i; - size_t j; - size_t len; - size_t new_len; - size_t p_len; - - if (SplitPath(pathname, &dir, &file) < 0) - return NULL; - if ((ac = FindMatches(dir, file, &av)) == 0) { - free(dir); - free(file); - return NULL; - } - - p = NULL; - len = strlen(file); - if (ac == 1) { - /* Exactly one match -- finish it off. */ - *unique = 1; - j = strlen(av[0]) - len + 2; - p_len = sizeof(char) * (j + 1); - if ((p = malloc(p_len)) != NULL) { - memcpy(p, av[0] + len, j); - new_len = sizeof(char) * (strlen(dir) + strlen(av[0]) + 2); - new = malloc(new_len); - if(new != NULL) { - snprintf(new, new_len, "%s/%s", dir, av[0]); - rl_add_slash(new, p, p_len); - free(new); - } - } - } - else { - /* Find largest matching substring. */ - for (*unique = 0, i = len, end = strlen(av[0]); i < end; i++) - for (j = 1; j < ac; j++) - if (av[0][i] != av[j][i]) - goto breakout; -breakout: - if (i > len) { - j = i - len + 1; - if ((p = malloc(sizeof(char) * j)) != NULL) { - memcpy(p, av[0] + len, j); - p[j - 1] = '\0'; - } - } - } - - /* Clean up and return. */ - free(dir); - free(file); - for (i = 0; i < ac; i++) - free(av[i]); - free(av); - return p; -} - -/* -** Return all possible completions. -*/ -int -rl_list_possib(char *pathname, char ***avp) -{ - char *dir; - char *file; - int ac; - - if (SplitPath(pathname, &dir, &file) < 0) - return 0; - ac = FindMatches(dir, file, avp); - free(dir); - free(file); - return ac; -} diff --git a/ndb/src/common/editline/editline.3 b/ndb/src/common/editline/editline.3 deleted file mode 100644 index 159cc7f87bb..00000000000 --- a/ndb/src/common/editline/editline.3 +++ /dev/null @@ -1,178 +0,0 @@ -.\" $Revision: 1.1 $ -.TH EDITLINE 3 -.SH NAME -editline \- command-line editing library with history -.SH SYNOPSIS -.nf -.B "char *" -.B "readline(prompt)" -.B " char *prompt;" - -.B "void" -.B "add_history(line)" -.B " char *line;" -.fi -.SH DESCRIPTION -.I Editline -is a library that provides an line-editing interface with text recall. -It is intended to be compatible with the -.I readline -library provided by the Free Software Foundation, but much smaller. -The bulk of this manual page describes the user interface. -.PP -The -.I readline -routine returns a line of text with the trailing newline removed. -The data is returned in a buffer allocated with -.IR malloc (3), -so the space should be released with -.IR free (3) -when the calling program is done with it. -Before accepting input from the user, the specified -.I prompt -is displayed on the terminal. -.PP -The -.I add_history -routine makes a copy of the specified -.I line -and adds it to the internal history list. -.SS "User Interface" -A program that uses this library provides a simple emacs-like editing -interface to its users. -A line may be edited before it is sent to the calling program by typing either -control characters or escape sequences. -A control character, shown as a caret followed by a letter, is typed by -holding down the ``control'' key while the letter is typed. -For example, ``^A'' is a control-A. -An escape sequence is entered by typing the ``escape'' key followed by one or -more characters. -The escape key is abbreviated as ``ESC''. -Note that unlike control keys, case matters in escape sequences; ``ESC\ F'' -is not the same as ``ESC\ f''. -.PP -An editing command may be typed anywhere on the line, not just at the -beginning. -In addition, a return may also be typed anywhere on the line, not just at -the end. -.PP -Most editing commands may be given a repeat count, -.IR n , -where -.I n -is a number. -To enter a repeat count, type the escape key, the number, and then -the command to execute. -For example, ``ESC\ 4\ ^f'' moves forward four characters. -If a command may be given a repeat count then the text ``[n]'' is given at the -end of its description. -.PP -The following control characters are accepted: -.RS -.nf -.ta \w'ESC DEL 'u -^A Move to the beginning of the line -^B Move left (backwards) [n] -^D Delete character [n] -^E Move to end of line -^F Move right (forwards) [n] -^G Ring the bell -^H Delete character before cursor (backspace key) [n] -^I Complete filename (tab key); see below -^J Done with line (return key) -^K Kill to end of line (or column [n]) -^L Redisplay line -^M Done with line (alternate return key) -^N Get next line from history [n] -^P Get previous line from history [n] -^R Search backward (forward if [n]) through history for text; -\& prefixing the string with a caret (^) forces it to -\& match only at the beginning of a history line -^T Transpose characters -^V Insert next character, even if it is an edit command -^W Wipe to the mark -^X^X Exchange current location and mark -^Y Yank back last killed text -^[ Start an escape sequence (escape key) -^]c Move forward to next character ``c'' -^? Delete character before cursor (delete key) [n] -.fi -.RE -.PP -The following escape sequences are provided. -.RS -.nf -.ta \w'ESC DEL 'u -ESC\ ^H Delete previous word (backspace key) [n] -ESC\ DEL Delete previous word (delete key) [n] -ESC\ ESC Show possible completions; see below -ESC\ SP Set the mark (space key); see ^X^X and ^Y above -ESC\ . Get the last (or [n]'th) word from previous line -ESC\ ? Show possible completions; see below -ESC\ < Move to start of history -ESC\ > Move to end of history -ESC\ b Move backward a word [n] -ESC\ d Delete word under cursor [n] -ESC\ f Move forward a word [n] -ESC\ l Make word lowercase [n] -ESC\ m Toggle if 8bit chars display as themselves or with -\& an ``M\-'' prefix -ESC\ u Make word uppercase [n] -ESC\ y Yank back last killed text -ESC\ w Make area up to mark yankable -ESC\ nn Set repeat count to the number nn -ESC\ C Read from environment variable ``_C_'', where C is -\& an uppercase letter -.fi -.RE -.PP -The -.I editline -library has a small macro facility. -If you type the escape key followed by an uppercase letter, -.IR C , -then the contents of the environment variable -.I _C_ -are read in as if you had typed them at the keyboard. -For example, if the variable -.I _L_ -contains the following: -.RS -^A^Kecho '^V^[[H^V^[[2J'^M -.RE -Then typing ``ESC L'' will move to the beginning of the line, kill the -entire line, enter the echo command needed to clear the terminal (if your -terminal is like a VT-100), and send the line back to the shell. -.PP -The -.I editline -library also does filename completion. -Suppose the root directory has the following files in it: -.RS -.nf -.ta \w'core 'u -bin vmunix -core vmunix.old -.fi -.RE -If you type ``rm\ /v'' and then the tab key. -.I Editline -will then finish off as much of the name as possible by adding ``munix''. -Because the name is not unique, it will then beep. -If you type the escape key followed by either a question mark or another -escape, it will display the two choices. -If you then type a period and a tab, the library will finish off the filename -for you: -.RS -.nf -.RI "rm /v[TAB]" munix ".[TAB]" old -.fi -.RE -The tab key is shown by ``[TAB]'' and the automatically-entered text -is shown in italics. -.SH "BUGS AND LIMITATIONS" -Cannot handle lines more than 80 columns. -.SH AUTHORS -Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy> -and Rich $alz <rsalz@osf.org>. -Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>. diff --git a/ndb/src/common/editline/editline.c b/ndb/src/common/editline/editline.c deleted file mode 100644 index 886dac2793b..00000000000 --- a/ndb/src/common/editline/editline.c +++ /dev/null @@ -1,1498 +0,0 @@ -/* -*- c-basic-offset: 4; -*- -** $Revision: 1.6 $ -** -** Main editing routines for editline library. -*/ -#include <ndb_global.h> - -#include "editline_internal.h" -#include <signal.h> - -/* -** Manifest constants. -*/ -#define SCREEN_WIDTH 80 -#define SCREEN_ROWS 24 -#define NO_ARG (-1) -#define DEL 127 -#define TAB '\t' -#define CTL(x) ((x) & 0x1F) -#define ISCTL(x) ((x) && (x) < ' ') -#define UNCTL(x) ((x) + 64) -#define META(x) ((x) | 0x80) -#define ISMETA(x) ((x) & 0x80) -#define UNMETA(x) ((x) & 0x7F) -#define MAPSIZE 32 -#define METAMAPSIZE 16 -#if !defined(HIST_SIZE) -#define HIST_SIZE 20 -#endif /* !defined(HIST_SIZE) */ - -/* -** Command status codes. -*/ -typedef enum _STATUS { - CSdone, CSeof, CSmove, CSdispatch, CSstay, CSsignal -} STATUS; - -/* -** The type of case-changing to perform. -*/ -typedef enum _CASE { - TOupper, TOlower -} CASE; - -/* -** Key to command mapping. -*/ -typedef struct _KEYMAP { - char Key; - char Active; - STATUS (*Function)(); -} KEYMAP; - -/* -** Command history structure. -*/ -typedef struct _HISTORY { - int Size; - int Pos; - char *Lines[HIST_SIZE]; -} HISTORY; - -/* -** Globals. -*/ -int rl_eof; -int rl_erase; -int rl_intr; -int rl_kill; -int rl_quit; -#if defined(DO_SIGTSTP) -int rl_susp; -#endif /* defined(DO_SIGTSTP) */ - -static char NIL[] = ""; -static const char *Input = NIL; -static char *Line; -static const char *Prompt; -static char *Yanked; -static char *Screen; -static char NEWLINE[]= CRLF; -static HISTORY H; -static int Repeat; -static int End; -static int Mark; -static int OldPoint; -static int Point; -static int PushBack; -static int Pushed; -static int Signal; -static KEYMAP Map[MAPSIZE]; -static KEYMAP MetaMap[METAMAPSIZE]; -static size_t Length; -static size_t ScreenCount; -static size_t ScreenSize; -static char *backspace; -static int TTYwidth; -static int TTYrows; - -/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ -int rl_meta_chars = 1; - -/* -** Declarations. -*/ -static char *editinput(); - -#if defined(USE_TERMCAP) -extern char *getenv(); -extern char *tgetstr(); -extern int tgetent(); -extern int tgetnum(); -#endif /* defined(USE_TERMCAP) */ - -/* -** TTY input/output functions. -*/ - -static void -TTYflush() -{ - if (ScreenCount) { - (void)write(1, Screen, ScreenCount); - ScreenCount = 0; - } -} - -static void -TTYput(const char c) -{ - Screen[ScreenCount] = c; - if (++ScreenCount >= ScreenSize - 1) { - ScreenSize += SCREEN_INC; - Screen = realloc(Screen, sizeof(char) * ScreenSize); - /* XXX what to do if realloc failes? */ - } -} - -static void -TTYputs(const char *p) -{ - while (*p) - TTYput(*p++); -} - -static void -TTYshow(char c) -{ - if (c == DEL) { - TTYput('^'); - TTYput('?'); - } - else if (c == TAB) { - /* XXX */ - } - else if (ISCTL(c)) { - TTYput('^'); - TTYput(UNCTL(c)); - } - else if (rl_meta_chars && ISMETA(c)) { - TTYput('M'); - TTYput('-'); - TTYput(UNMETA(c)); - } - else - TTYput(c); -} - -static void -TTYstring(char *p) -{ - while (*p) - TTYshow(*p++); -} - -static int -TTYget() -{ - char c; - - TTYflush(); - if (Pushed) { - Pushed = 0; - return PushBack; - } - if (*Input) - return *Input++; - return read(0, &c, (size_t)1) == 1 ? c : EOF; -} - -#define TTYback() (backspace ? TTYputs((const char *)backspace) : TTYput('\b')) - -static void -TTYbackn(int n) -{ - while (--n >= 0) - TTYback(); -} - -static void -TTYinfo() -{ - static int init; -#if defined(USE_TERMCAP) - char *term; - char buff[2048]; - char *bp; - char *p; -#endif /* defined(USE_TERMCAP) */ -#if defined(TIOCGWINSZ) - struct winsize W; -#endif /* defined(TIOCGWINSZ) */ - - if (init) { -#if defined(TIOCGWINSZ) - /* Perhaps we got resized. */ - if (ioctl(0, TIOCGWINSZ, &W) >= 0 - && W.ws_col > 0 && W.ws_row > 0) { - TTYwidth = (int)W.ws_col; - TTYrows = (int)W.ws_row; - } -#endif /* defined(TIOCGWINSZ) */ - return; - } - init++; - - TTYwidth = TTYrows = 0; -#if defined(USE_TERMCAP) - bp = &buff[0]; - if ((term = getenv("TERM")) == NULL) - term = "dumb"; - if (tgetent(buff, term) < 0) { - TTYwidth = SCREEN_WIDTH; - TTYrows = SCREEN_ROWS; - return; - } - p = tgetstr("le", &bp); - backspace = p ? strdup(p) : NULL; - TTYwidth = tgetnum("co"); - TTYrows = tgetnum("li"); -#endif /* defined(USE_TERMCAP) */ - -#if defined(TIOCGWINSZ) - if (ioctl(0, TIOCGWINSZ, &W) >= 0) { - TTYwidth = (int)W.ws_col; - TTYrows = (int)W.ws_row; - } -#endif /* defined(TIOCGWINSZ) */ - - if (TTYwidth <= 0 || TTYrows <= 0) { - TTYwidth = SCREEN_WIDTH; - TTYrows = SCREEN_ROWS; - } -} - - -/* -** Print an array of words in columns. -*/ -static void -columns(int ac, char **av) -{ - char *p; - int i; - int j; - int k; - int len; - int skip; - int longest; - int cols; - - /* Find longest name, determine column count from that. */ - for (longest = 0, i = 0; i < ac; i++) - if ((j = strlen((char *)av[i])) > longest) - longest = j; - cols = TTYwidth / (longest + 3); - - TTYputs((const char *)NEWLINE); - for (skip = ac / cols + 1, i = 0; i < skip; i++) { - for (j = i; j < ac; j += skip) { - for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) - TTYput(*p); - if (j + skip < ac) - while (++len < longest + 3) - TTYput(' '); - } - TTYputs((const char *)NEWLINE); - } -} - -static void -reposition() -{ - int i; - char *p; - - TTYput('\r'); - TTYputs((const char *)Prompt); - for (i = Point, p = Line; --i >= 0; p++) - TTYshow(*p); -} - -static void -left(STATUS Change) -{ - char c; - - TTYback(); - if (Point) { - c = Line[Point - 1]; - if (c == TAB) { - /* XXX */ - } - else if (ISCTL(c)) - TTYback(); - else if (rl_meta_chars && ISMETA(c)) { - TTYback(); - TTYback(); - } - } - if (Change == CSmove) - Point--; -} - -static void -right(STATUS Change) -{ - TTYshow(Line[Point]); - if (Change == CSmove) - Point++; -} - -static STATUS -ring_bell() -{ - TTYput('\07'); - TTYflush(); - return CSstay; -} - -static STATUS -do_macro(int c) -{ - char name[4]; - - name[0] = '_'; - name[1] = c; - name[2] = '_'; - name[3] = '\0'; - - if ((Input = (char *)getenv((char *)name)) == NULL) { - Input = NIL; - return ring_bell(); - } - return CSstay; -} - -static STATUS -do_forward(STATUS move) -{ - int i; - char *p; - - i = 0; - do { - p = &Line[Point]; - for ( ; Point < End && (*p == ' ' || !isalnum((int)*p)); Point++, p++) - if (move == CSmove) - right(CSstay); - - for (; Point < End && isalnum((int)*p); Point++, p++) - if (move == CSmove) - right(CSstay); - - if (Point == End) - break; - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -do_case(CASE type) -{ - int i; - int end; - int count; - char *p; - - (void)do_forward(CSstay); - if (OldPoint != Point) { - if ((count = Point - OldPoint) < 0) - count = -count; - Point = OldPoint; - if ((end = Point + count) > End) - end = End; - for (i = Point, p = &Line[i]; i < end; i++, p++) { - if (type == TOupper) { - if (islower((int)*p)) - *p = toupper((int)*p); - } - else if (isupper((int)*p)) - *p = tolower((int)*p); - right(CSmove); - } - } - return CSstay; -} - -static STATUS -case_down_word() -{ - return do_case(TOlower); -} - -static STATUS -case_up_word() -{ - return do_case(TOupper); -} - -static void -ceol() -{ - int extras; - int i; - char *p; - - for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) { - TTYput(' '); - if (*p == TAB) { - /* XXX */ - } - else if (ISCTL(*p)) { - TTYput(' '); - extras++; - } - else if (rl_meta_chars && ISMETA(*p)) { - TTYput(' '); - TTYput(' '); - extras += 2; - } - } - - for (i += extras; i > Point; i--) - TTYback(); -} - -static void -clear_line() -{ - Point = -strlen(Prompt); - TTYput('\r'); - ceol(); - Point = 0; - End = 0; - Line[0] = '\0'; -} - -static STATUS -insert_string(char *p) -{ - size_t len; - int i; - char *new; - char *q; - - len = strlen((char *)p); - if (End + len >= Length) { - if ((new = malloc(sizeof(char) * (Length + len + MEM_INC))) == NULL) - return CSstay; - if (Length) { - memcpy(new, Line, Length); - free(Line); - } - Line = new; - Length += len + MEM_INC; - } - - for (q = &Line[Point], i = End - Point; --i >= 0; ) - q[len + i] = q[i]; - memcpy(&Line[Point], p, len); - End += len; - Line[End] = '\0'; - TTYstring(&Line[Point]); - Point += len; - - return Point == End ? CSstay : CSmove; -} - -static STATUS -redisplay() -{ - TTYputs((const char *)NEWLINE); - TTYputs((const char *)Prompt); - TTYstring(Line); - return CSmove; -} - -static STATUS -redisplay_no_nl() -{ - TTYput('\r'); - TTYputs((const char *)Prompt); - TTYstring(Line); - return CSmove; -} - -static STATUS -toggle_meta_mode() -{ - rl_meta_chars = !rl_meta_chars; - return redisplay(); -} - - -static char * -next_hist() -{ - return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; -} - -static char * -prev_hist() -{ - return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; -} - -static STATUS -do_insert_hist(char *p) -{ - if (p == NULL) - return ring_bell(); - Point = 0; - reposition(); - ceol(); - End = 0; - return insert_string(p); -} - -static STATUS -do_hist(char *(*move)()) -{ - char *p; - int i; - - i = 0; - do { - if ((p = (*move)()) == NULL) - return ring_bell(); - } while (++i < Repeat); - return do_insert_hist(p); -} - -static STATUS -h_next() -{ - return do_hist(next_hist); -} - -static STATUS -h_prev() -{ - return do_hist(prev_hist); -} - -static STATUS -h_first() -{ - return do_insert_hist(H.Lines[H.Pos = 0]); -} - -static STATUS -h_last() -{ - return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); -} - -/* -** Return zero if pat appears as a substring in text. -*/ -static int -substrcmp(char *text, char *pat,int len) -{ - char c; - - if ((c = *pat) == '\0') - return *text == '\0'; - for ( ; *text; text++) - if (*text == c && strncmp(text, pat, len) == 0) - return 0; - return 1; -} - -static char * -search_hist(char *search,char *(*move)()) -{ - static char *old_search; - int len; - int pos; - int (*match)(); - char *pat; - - /* Save or get remembered search pattern. */ - if (search && *search) { - if (old_search) - free(old_search); - old_search = strdup(search); - } - else { - if (old_search == NULL || *old_search == '\0') - return NULL; - search = old_search; - } - - /* Set up pattern-finder. */ - if (*search == '^') { - match = strncmp; - pat = (char *)(search + 1); - } - else { - match = substrcmp; - pat = (char *)search; - } - len = strlen(pat); - - for (pos = H.Pos; (*move)() != NULL; ) - if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0) - return H.Lines[H.Pos]; - H.Pos = pos; - return NULL; -} - -static STATUS -h_search() -{ - static int Searching; - const char *old_prompt; - char *(*move)(); - char *p; - - if (Searching) - return ring_bell(); - Searching = 1; - - clear_line(); - old_prompt = Prompt; - Prompt = "Search: "; - TTYputs((const char *)Prompt); - move = Repeat == NO_ARG ? prev_hist : next_hist; - p = editinput(); - Searching = 0; - if (p == NULL && Signal > 0) { - Signal = 0; - clear_line(); - Prompt = old_prompt; - return redisplay_no_nl(); - } - p = search_hist(p, move); - clear_line(); - Prompt = old_prompt; - if (p == NULL) { - (void)ring_bell(); - return redisplay_no_nl(); - } - return do_insert_hist(p); -} - -static STATUS -fd_char() -{ - int i; - - i = 0; - do { - if (Point >= End) - break; - right(CSmove); - } while (++i < Repeat); - return CSstay; -} - -static void -save_yank(int begin, int i) -{ - if (Yanked) { - free(Yanked); - Yanked = NULL; - } - - if (i < 1) - return; - - if ((Yanked = malloc(sizeof(char) * (i + 1))) != NULL) { - memcpy(Yanked, &Line[begin], i); - Yanked[i] = '\0'; - } -} - -static STATUS -delete_string(int count) -{ - int i; - char *p; - - if (count <= 0 || End == Point) - return ring_bell(); - - if (count == 1 && Point == End - 1) { - /* Optimize common case of delete at end of line. */ - End--; - p = &Line[Point]; - i = 1; - TTYput(' '); - if (*p == TAB) { - /* XXX */ - } - else if (ISCTL(*p)) { - i = 2; - TTYput(' '); - } - else if (rl_meta_chars && ISMETA(*p)) { - i = 3; - TTYput(' '); - TTYput(' '); - } - TTYbackn(i); - *p = '\0'; - return CSmove; - } - if (Point + count > End && (count = End - Point) <= 0) - return CSstay; - - if (count > 1) - save_yank(Point, count); - - ceol(); - for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) - p[0] = p[count]; - End -= count; - TTYstring(&Line[Point]); - return CSmove; -} - -static STATUS -bk_char() -{ - int i; - - i = 0; - do { - if (Point == 0) - break; - left(CSmove); - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -bk_del_char() -{ - int i; - - i = 0; - do { - if (Point == 0) - break; - left(CSmove); - } while (++i < Repeat); - - return delete_string(i); -} - -static STATUS -kill_line() -{ - int i; - - if (Repeat != NO_ARG) { - if (Repeat < Point) { - i = Point; - Point = Repeat; - reposition(); - (void)delete_string(i - Point); - } - else if (Repeat > Point) { - right(CSmove); - (void)delete_string(Repeat - Point - 1); - } - return CSmove; - } - - save_yank(Point, End - Point); - ceol(); - Line[Point] = '\0'; - End = Point; - return CSstay; -} - -static STATUS -insert_char(int c) -{ - STATUS s; - char buff[2]; - char *p; - char *q; - int i; - - if (Repeat == NO_ARG || Repeat < 2) { - buff[0] = c; - buff[1] = '\0'; - return insert_string(buff); - } - - if ((p = malloc(sizeof(char) * (Repeat + 1))) == NULL) - return CSstay; - for (i = Repeat, q = p; --i >= 0; ) - *q++ = c; - *q = '\0'; - Repeat = 0; - s = insert_string(p); - free(p); - return s; -} - -static STATUS -meta() -{ - int c; - KEYMAP *kp; - - if ((c = TTYget()) == EOF) - return CSeof; -#if defined(ANSI_ARROWS) - /* Also include VT-100 arrows. */ - if (c == '[' || c == 'O') - switch ((int)(c = TTYget())) { - default: return ring_bell(); - case EOF: return CSeof; - case 'A': return h_prev(); - case 'B': return h_next(); - case 'C': return fd_char(); - case 'D': return bk_char(); - } -#endif /* defined(ANSI_ARROWS) */ - - if (isdigit(c)) { - for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) - Repeat = Repeat * 10 + c - '0'; - Pushed = 1; - PushBack = c; - return CSstay; - } - - if (isupper(c)) - return do_macro(c); - for (OldPoint = Point, kp = MetaMap; kp < &MetaMap[METAMAPSIZE]; kp++) - if (kp->Key == c && kp->Active) - return (*kp->Function)(); - - return ring_bell(); -} - -static STATUS -emacs(int c) -{ - STATUS s; - KEYMAP *kp; - -#if 0 - /* This test makes it impossible to enter eight-bit characters when - * meta-char mode is enabled. */ - if (rl_meta_chars && ISMETA(c)) { - Pushed = 1; - PushBack = UNMETA(c); - return meta(); - } -#endif /* 0 */ - for (kp = Map; kp < &Map[MAPSIZE]; kp++) - if (kp->Key == c && kp->Active) - break; - s = kp < &Map[MAPSIZE] ? (*kp->Function)() : insert_char((int)c); - if (!Pushed) - /* No pushback means no repeat count; hacky, but true. */ - Repeat = NO_ARG; - return s; -} - -static STATUS -TTYspecial(int c) -{ - if (rl_meta_chars && ISMETA(c)) - return CSdispatch; - - if (c == rl_erase || c == DEL) - return bk_del_char(); - if (c == rl_kill) { - if (Point != 0) { - Point = 0; - reposition(); - } - Repeat = NO_ARG; - return kill_line(); - } - if (c == rl_eof && Point == 0 && End == 0) - return CSeof; - if (c == rl_intr) { - Signal = SIGINT; - return CSsignal; - } - if (c == rl_quit) { - Signal = SIGQUIT; - return CSsignal; - } -#if defined(DO_SIGTSTP) - if (c == rl_susp) { - Signal = SIGTSTP; - return CSsignal; - } -#endif /* defined(DO_SIGTSTP) */ - - return CSdispatch; -} - -static char * -editinput() -{ - int c; - - Repeat = NO_ARG; - OldPoint = Point = Mark = End = 0; - Line[0] = '\0'; - - Signal = -1; - while ((c = TTYget()) != EOF) - switch (TTYspecial(c)) { - case CSdone: - return Line; - case CSeof: - return NULL; - case CSsignal: - return (char *)""; - case CSmove: - reposition(); - break; - case CSdispatch: - switch (emacs(c)) { - case CSdone: - return Line; - case CSeof: - return NULL; - case CSsignal: - return (char *)""; - case CSmove: - reposition(); - break; - case CSdispatch: - case CSstay: - break; - } - break; - case CSstay: - break; - } - return NULL; -} - -static void -hist_add(char *p) -{ - int i; - - if ((p = strdup(p)) == NULL) - return; - if (H.Size < HIST_SIZE) - H.Lines[H.Size++] = p; - else { - free(H.Lines[0]); - for (i = 0; i < HIST_SIZE - 1; i++) - H.Lines[i] = H.Lines[i + 1]; - H.Lines[i] = p; - } - H.Pos = H.Size - 1; -} - -static char * -read_redirected() -{ - int size; - char *p; - char *line; - char *end; - - for (size = MEM_INC, p = line = malloc(sizeof(char) * size), end = p + size; ; p++) { - if (p == end) { - size += MEM_INC; - p = line = realloc(line, size); - end = p + size; - } - if (read(0, p, 1) <= 0) { - /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ - free(line); - return NULL; - } - if (*p == '\n') - break; - } - *p = '\0'; - return line; -} - -/* -** For compatibility with FSF readline. -*/ -/* ARGSUSED0 */ -void -rl_reset_terminal(char *p) -{ - (void)p; /* Suppress warning */ -} - -void -rl_initialize() -{ -} - -int -rl_insert(int count, int c) -{ - if (count > 0) { - Repeat = count; - (void)insert_char(c); - (void)redisplay_no_nl(); - } - return 0; -} - -int (*rl_event_hook)(); - -int -rl_key_action(int c, char flag) -{ - KEYMAP *kp; - int size; - - (void)flag; /* Suppress warning */ - - if (ISMETA(c)) { - kp = MetaMap; - size = METAMAPSIZE; - } - else { - kp = Map; - size = MAPSIZE; - } - for ( ; --size >= 0; kp++) - if (kp->Key == c) { - kp->Active = c ? 1 : 0; - return 1; - } - return -1; -} - -char * -readline(const char *prompt) -{ - char *line; - int s; - - if (!isatty(0)) { - TTYflush(); - return read_redirected(); - } - - if (Line == NULL) { - Length = MEM_INC; - if ((Line = malloc(sizeof(char) * Length)) == NULL) - return NULL; - } - - TTYinfo(); - rl_ttyset(0); - hist_add(NIL); - ScreenSize = SCREEN_INC; - Screen = malloc(sizeof(char) * ScreenSize); - Prompt = prompt ? prompt : (char *)NIL; - TTYputs((const char *)Prompt); - if ((line = editinput()) != NULL) { - line = strdup(line); - TTYputs((const char *)NEWLINE); - TTYflush(); - } - rl_ttyset(1); - free(Screen); - free(H.Lines[--H.Size]); - if (Signal > 0) { - s = Signal; - Signal = 0; - (void)kill(getpid(), s); - } - return (char *)line; -} - -void -add_history(char *p) -{ - if (p == NULL || *p == '\0') - return; - -#if defined(UNIQUE_HISTORY) - if (H.Size && strcmp(p, H.Lines[H.Size - 1]) == 0) - return; -#endif /* defined(UNIQUE_HISTORY) */ - hist_add((char *)p); -} - - -static STATUS -beg_line() -{ - if (Point) { - Point = 0; - return CSmove; - } - return CSstay; -} - -static STATUS -del_char() -{ - return delete_string(Repeat == NO_ARG ? 1 : Repeat); -} - -static STATUS -end_line() -{ - if (Point != End) { - Point = End; - return CSmove; - } - return CSstay; -} - -/* -** Return allocated copy of word under cursor, moving cursor after the -** word. -*/ -static char * -find_word() -{ - static char SEPS[] = "\"#;&|^$=`'{}()<>\n\t "; - char *p; - char *new; - size_t len; - - /* Move forward to end of word. */ - p = &Line[Point]; - for ( ; Point < End && strchr(SEPS, (char)*p) == NULL; Point++, p++) - right(CSstay); - - /* Back up to beginning of word. */ - for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--) - continue; - len = Point - (p - Line) + 1; - if ((new = malloc(sizeof(char) * len)) == NULL) - return NULL; - memcpy(new, p, len); - new[len - 1] = '\0'; - return new; -} - -static STATUS -c_complete() -{ - char *p; - char *word; - int unique; - - word = find_word(); - p = (char *)rl_complete((char *)word, &unique); - if (word) - free(word); - if (p && *p) { - (void)insert_string(p); - if (!unique) - (void)ring_bell(); - free(p); - return redisplay_no_nl(); - } - return ring_bell(); -} - -static STATUS -c_possible() -{ - char **av; - char *word; - int ac; - - word = find_word(); - ac = rl_list_possib((char *)word, (char ***)&av); - if (word) - free(word); - if (ac) { - columns(ac, av); - while (--ac >= 0) - free(av[ac]); - free(av); - return redisplay_no_nl(); - } - return ring_bell(); -} - -static STATUS -accept_line() -{ - Line[End] = '\0'; - return CSdone; -} - -static STATUS -transpose() -{ - char c; - - if (Point) { - if (Point == End) - left(CSmove); - c = Line[Point - 1]; - left(CSstay); - Line[Point - 1] = Line[Point]; - TTYshow(Line[Point - 1]); - Line[Point++] = c; - TTYshow(c); - } - return CSstay; -} - -static STATUS -quote() -{ - int c; - - return (c = TTYget()) == EOF ? CSeof : insert_char((int)c); -} - -static STATUS -wipe() -{ - int i; - - if (Mark > End) - return ring_bell(); - - if (Point > Mark) { - i = Point; - Point = Mark; - Mark = i; - reposition(); - } - - return delete_string(Mark - Point); -} - -static STATUS -mk_set() -{ - Mark = Point; - return CSstay; -} - -static STATUS -exchange() -{ - int c; - - if ((c = TTYget()) != CTL('X')) - return c == EOF ? CSeof : ring_bell(); - - if ((c = Mark) <= End) { - Mark = Point; - Point = c; - return CSmove; - } - return CSstay; -} - -static STATUS -yank() -{ - if (Yanked && *Yanked) - return insert_string(Yanked); - return CSstay; -} - -static STATUS -copy_region() -{ - if (Mark > End) - return ring_bell(); - - if (Point > Mark) - save_yank(Mark, Point - Mark); - else - save_yank(Point, Mark - Point); - - return CSstay; -} - -static STATUS -move_to_char() -{ - int c; - int i; - char *p; - - if ((c = TTYget()) == EOF) - return CSeof; - for (i = Point + 1, p = &Line[i]; i < End; i++, p++) - if (*p == c) { - Point = i; - return CSmove; - } - return CSstay; -} - -static STATUS -fd_word() -{ - return do_forward(CSmove); -} - -static STATUS -fd_kill_word() -{ - int i; - - (void)do_forward(CSstay); - if (OldPoint != Point) { - i = Point - OldPoint; - Point = OldPoint; - return delete_string(i); - } - return CSstay; -} - -static STATUS -bk_word() -{ - int i; - char *p; - - i = 0; - do { - for (p = &Line[Point]; p > Line && !isalnum((int)p[-1]); p--) - left(CSmove); - - for (; p > Line && p[-1] != ' ' && isalnum((int)p[-1]); p--) - left(CSmove); - - if (Point == 0) - break; - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -bk_kill_word() -{ - (void)bk_word(); - if (OldPoint != Point) - return delete_string(OldPoint - Point); - return CSstay; -} - -static int -argify(char *line, char ***avp) -{ - char *c; - char **p; - char **new; - int ac; - int i; - - i = MEM_INC; - if ((*avp = p = malloc(sizeof(char*) * i))== NULL) - return 0; - - for (c = line; isspace((int)*c); c++) - continue; - if (*c == '\n' || *c == '\0') - return 0; - - for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { - if (isspace((int)*c)) { - *c++ = '\0'; - if (*c && *c != '\n') { - if (ac + 1 == i) { - new = malloc(sizeof(char*) * (i + MEM_INC)); - if (new == NULL) { - p[ac] = NULL; - return ac; - } - memcpy(new, p, i * sizeof (char **)); - i += MEM_INC; - free(p); - *avp = p = new; - } - p[ac++] = c; - } - } - else - c++; - } - *c = '\0'; - p[ac] = NULL; - return ac; -} - -static STATUS -last_argument() -{ - char **av; - char *p; - STATUS s; - int ac; - - if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) - return ring_bell(); - - if ((p = strdup(p)) == NULL) - return CSstay; - ac = argify(p, &av); - - if (Repeat != NO_ARG) - s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); - else - s = ac ? insert_string(av[ac - 1]) : CSstay; - - if (ac) - free(av); - free(p); - return s; -} - -static KEYMAP Map[MAPSIZE] = { - { CTL('@'), 1, ring_bell }, - { CTL('A'), 1, beg_line }, - { CTL('B'), 1, bk_char }, - { CTL('D'), 1, del_char }, - { CTL('E'), 1, end_line }, - { CTL('F'), 1, fd_char }, - { CTL('G'), 1, ring_bell }, - { CTL('H'), 1, bk_del_char }, - { CTL('I'), 1, c_complete }, - { CTL('J'), 1, accept_line }, - { CTL('K'), 1, kill_line }, - { CTL('L'), 1, redisplay }, - { CTL('M'), 1, accept_line }, - { CTL('N'), 1, h_next }, - { CTL('O'), 1, ring_bell }, - { CTL('P'), 1, h_prev }, - { CTL('Q'), 1, ring_bell }, - { CTL('R'), 1, h_search }, - { CTL('S'), 1, ring_bell }, - { CTL('T'), 1, transpose }, - { CTL('U'), 1, ring_bell }, - { CTL('V'), 1, quote }, - { CTL('W'), 1, wipe }, - { CTL('X'), 1, exchange }, - { CTL('Y'), 1, yank }, - { CTL('Z'), 1, ring_bell }, - { CTL('['), 1, meta }, - { CTL(']'), 1, move_to_char }, - { CTL('^'), 1, ring_bell }, - { CTL('_'), 1, ring_bell }, -}; - -static KEYMAP MetaMap[16]= { - { CTL('H'), 1, bk_kill_word }, - { CTL('['), 1, c_possible }, - { DEL, 1, bk_kill_word }, - { ' ', 1, mk_set }, - { '.', 1, last_argument }, - { '<', 1, h_first }, - { '>', 1, h_last }, - { '?', 1, c_possible }, - { 'b', 1, bk_word }, - { 'd', 1, fd_kill_word }, - { 'f', 1, fd_word }, - { 'l', 1, case_down_word }, - { 'm', 1, toggle_meta_mode}, - { 'u', 1, case_up_word }, - { 'y', 1, yank }, - { 'w', 1, copy_region }, -}; diff --git a/ndb/src/common/editline/editline_internal.h b/ndb/src/common/editline/editline_internal.h deleted file mode 100644 index d82fa91c44b..00000000000 --- a/ndb/src/common/editline/editline_internal.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $Revision: 1.2 $ -** -** Internal header file for editline library. -*/ - -#include <ndb_global.h> - -#if defined(SYS_UNIX) -#include "unix.h" -#endif /* defined(SYS_UNIX) */ - -#define MEM_INC 64 -#define SCREEN_INC 256 - -/* -** Variables and routines internal to this package. -*/ -extern int rl_eof; -extern int rl_erase; -extern int rl_intr; -extern int rl_kill; -extern int rl_quit; -#if defined(DO_SIGTSTP) -extern int rl_susp; -#endif /* defined(DO_SIGTSTP) */ -extern char *rl_complete(); -extern int rl_list_possib(); -extern void rl_ttyset(); -extern void rl_add_slash(); - diff --git a/ndb/src/common/editline/sysunix.c b/ndb/src/common/editline/sysunix.c deleted file mode 100644 index b0242fb99ce..00000000000 --- a/ndb/src/common/editline/sysunix.c +++ /dev/null @@ -1,132 +0,0 @@ -/* $Revision: 1.4 $ -** -** Unix system-dependant routines for editline library. -*/ -#include "editline_internal.h" - -#if defined(HAVE_TCGETATTR) -#include <termios.h> - -void -rl_ttyset(int Reset) -{ - static struct termios old; - struct termios new; - - if (Reset == 0) { - if (tcgetattr(0, &old) < 0) perror("tcgetattr"); - rl_erase = old.c_cc[VERASE]; - rl_kill = old.c_cc[VKILL]; - rl_eof = old.c_cc[VEOF]; - rl_intr = old.c_cc[VINTR]; - rl_quit = old.c_cc[VQUIT]; -#if defined(DO_SIGTSTP) - rl_susp = old.c_cc[VSUSP]; -#endif /* defined(DO_SIGTSTP) */ - - new = old; - new.c_lflag &= ~(ECHO | ICANON | ISIG); - new.c_iflag &= ~(ISTRIP | INPCK); - new.c_cc[VMIN] = 1; - new.c_cc[VTIME] = 0; - if (tcsetattr(0, TCSADRAIN, &new) < 0) perror("tcsetattr"); - } - else - (void)tcsetattr(0, TCSADRAIN, &old); -} - -#else -#if defined(HAVE_TERMIO) -#include <termio.h> - -void -rl_ttyset(int Reset) -{ - static struct termio old; - struct termio new; - - if (Reset == 0) { - (void)ioctl(0, TCGETA, &old); - rl_erase = old.c_cc[VERASE]; - rl_kill = old.c_cc[VKILL]; - rl_eof = old.c_cc[VEOF]; - rl_intr = old.c_cc[VINTR]; - rl_quit = old.c_cc[VQUIT]; -#if defined(DO_SIGTSTP) - rl_susp = old.c_cc[VSUSP]; -#endif /* defined(DO_SIGTSTP) */ - - new = old; - new.c_lflag &= ~(ECHO | ICANON | ISIG); - new.c_iflag &= ~(ISTRIP | INPCK); - new.c_cc[VMIN] = 1; - new.c_cc[VTIME] = 0; - (void)ioctl(0, TCSETAW, &new); - } - else - (void)ioctl(0, TCSETAW, &old); -} - -#else -#include <sgtty.h> - -void -rl_ttyset(int Reset) -{ - static struct sgttyb old_sgttyb; - static struct tchars old_tchars; - struct sgttyb new_sgttyb; - struct tchars new_tchars; -#if defined(DO_SIGTSTP) - struct ltchars old_ltchars; -#endif /* defined(DO_SIGTSTP) */ - - if (Reset == 0) { - (void)ioctl(0, TIOCGETP, &old_sgttyb); - rl_erase = old_sgttyb.sg_erase; - rl_kill = old_sgttyb.sg_kill; - - (void)ioctl(0, TIOCGETC, &old_tchars); - rl_eof = old_tchars.t_eofc; - rl_intr = old_tchars.t_intrc; - rl_quit = old_tchars.t_quitc; - -#if defined(DO_SIGTSTP) - (void)ioctl(0, TIOCGLTC, &old_ltchars); - rl_susp = old_ltchars.t_suspc; -#endif /* defined(DO_SIGTSTP) */ - - new_sgttyb = old_sgttyb; - new_sgttyb.sg_flags &= ~ECHO; - new_sgttyb.sg_flags |= RAW; -#if defined(PASS8) - new_sgttyb.sg_flags |= PASS8; -#endif /* defined(PASS8) */ - (void)ioctl(0, TIOCSETP, &new_sgttyb); - - new_tchars = old_tchars; - new_tchars.t_intrc = -1; - new_tchars.t_quitc = -1; - (void)ioctl(0, TIOCSETC, &new_tchars); - } - else { - (void)ioctl(0, TIOCSETP, &old_sgttyb); - (void)ioctl(0, TIOCSETC, &old_tchars); - } -} -#endif /* defined(HAVE_TERMIO) */ -#endif /* defined(HAVE_TCGETATTR) */ - -void -rl_add_slash(char *path, char *p, size_t p_len) -{ - struct stat Sb; - - if (stat(path, &Sb) >= 0) { - size_t len= strlen(p); - if (len+1 < p_len) { - p[len]= S_ISDIR(Sb.st_mode) ? '/' : ' '; - p[len+1]= 0; - } - } -} diff --git a/ndb/src/common/editline/test/Makefile b/ndb/src/common/editline/test/Makefile deleted file mode 100644 index 20229d0aa62..00000000000 --- a/ndb/src/common/editline/test/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include .defs.mk - -TYPE := util - -BIN_TARGET := editline_test -BIN_TARGET_ARCHIVES := editline - -SOURCES = testit.c - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/editline/unix.h b/ndb/src/common/editline/unix.h deleted file mode 100644 index c2fde7547b3..00000000000 --- a/ndb/src/common/editline/unix.h +++ /dev/null @@ -1,9 +0,0 @@ -/* $Revision: 1.3 $ -** -** Editline system header file for Unix. -*/ - -#define CRLF "\r\n" - -#include <ndb_global.h> -#include <dirent.h> diff --git a/ndb/src/common/logger/Makefile_old b/ndb/src/common/logger/Makefile_old deleted file mode 100644 index 994eb86ba35..00000000000 --- a/ndb/src/common/logger/Makefile_old +++ /dev/null @@ -1,27 +0,0 @@ -include .defs.mk - -TYPE := ndbapi - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := logger - -DIRS := loggertest - -SOURCES := Logger.cpp LogHandlerList.cpp LogHandler.cpp \ - ConsoleLogHandler.cpp FileLogHandler.cpp - -ifeq ($(NDB_OS), OSE) -NO_SYSLOG := Y -endif - -ifeq ($(NDB_OS), WIN32) -NO_SYSLOG := Y -endif - -ifneq ($(NO_SYSLOG), Y) -SOURCES += SysLogHandler.cpp -endif - -include $(NDB_TOP)/Epilogue.mk - - diff --git a/ndb/src/common/mgmcommon/LocalConfig.cpp b/ndb/src/common/mgmcommon/LocalConfig.cpp index 3cd4341c6b7..679de716be0 100644 --- a/ndb/src/common/mgmcommon/LocalConfig.cpp +++ b/ndb/src/common/mgmcommon/LocalConfig.cpp @@ -90,7 +90,7 @@ LocalConfig::init(const char *connectString, //7. Check { char buf[256]; - BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_BASE_PORT); + BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_PORT); if(readConnectString(buf, "default connect string")) return true; } @@ -124,12 +124,12 @@ void LocalConfig::printUsage() const { ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl << " the node. "<< endl << " Ex: Ndb.cfg" << endl - << " | host=localhost:"<<NDB_BASE_PORT<<endl; + << " | host=localhost:"<<NDB_PORT<<endl; ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl << " provide this information." <<endl << " Ex: " << endl - << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_BASE_PORT<<"\"" + << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_PORT<<"\"" <<endl<<endl; } diff --git a/ndb/src/common/mgmcommon/Makefile.am b/ndb/src/common/mgmcommon/Makefile.am index ed6a526eb47..b787da51ab9 100644 --- a/ndb/src/common/mgmcommon/Makefile.am +++ b/ndb/src/common/mgmcommon/Makefile.am @@ -7,7 +7,7 @@ libmgmsrvcommon_la_SOURCES = \ INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmapi -I$(top_srcdir)/ndb/src/mgmsrv -DEFS_LOC = -DNDB_BASE_PORT="\"@ndb_port_base@\"" +DEFS_LOC = -DNDB_PORT="\"@ndb_port@\"" include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapi.mk.am diff --git a/ndb/src/common/mgmcommon/Makefile_old b/ndb/src/common/mgmcommon/Makefile_old deleted file mode 100644 index c7bfda7e3bf..00000000000 --- a/ndb/src/common/mgmcommon/Makefile_old +++ /dev/null @@ -1,29 +0,0 @@ -include .defs.mk - -TYPE := ndbapi mgmapiclient - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := mgmsrvcommon - -# Removed temporary -DIRS := printConfig - -SOURCES = \ - LocalConfig.cpp \ - Config.cpp \ - ConfigInfo.cpp \ - ConfigRetriever.cpp \ - InitConfigFileParser.cpp \ - IPCConfig.cpp - -SOURCES.c = NdbConfig.c - -CFLAGS_IPCConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) - -include $(NDB_TOP)/Epilogue.mk - - - - - - diff --git a/ndb/src/common/mgmcommon/NdbConfig.c b/ndb/src/common/mgmcommon/NdbConfig.c index e92f8fa8392..8adc4c20dff 100644 --- a/ndb/src/common/mgmcommon/NdbConfig.c +++ b/ndb/src/common/mgmcommon/NdbConfig.c @@ -74,7 +74,7 @@ NdbConfig_NdbCfgName(int with_ndb_home){ static char *get_prefix_buf(int len, int node_id) { - char tmp_buf[sizeof("ndb_pid#########")+1]; + char tmp_buf[sizeof("ndb_pid#############")+1]; char *buf; if (node_id > 0) snprintf(tmp_buf, sizeof(tmp_buf), "ndb_%u", node_id); diff --git a/ndb/src/common/portlib/Makefile_old b/ndb/src/common/portlib/Makefile_old deleted file mode 100644 index 48f4929a839..00000000000 --- a/ndb/src/common/portlib/Makefile_old +++ /dev/null @@ -1,21 +0,0 @@ -include .defs.mk - -DIRS := - -ifeq ($(NDB_OS), SOFTOSE) -DIRS += ose -else -ifeq ($(NDB_OS), OSE) -DIRS += ose -else -ifeq ($(NDB_OS), WIN32) -DIRS += win32 -else -DIRS += unix -endif -endif -endif - - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/common/portlib/NdbDaemon.c b/ndb/src/common/portlib/NdbDaemon.c index c73b5927ff4..3f1c1998501 100644 --- a/ndb/src/common/portlib/NdbDaemon.c +++ b/ndb/src/common/portlib/NdbDaemon.c @@ -55,18 +55,21 @@ NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags) "%s: lseek failed: %s", lockfile, strerror(errno)); return -1; } +#ifdef F_TLOCK /* Test for lock before becoming daemon */ - if (lockf(lockfd, F_TEST, 0) == -1) { - if (errno == EACCES || errno == EAGAIN) { /* results may vary */ + if (lockf(lockfd, F_TLOCK, 0) == -1) + { + if (errno == EACCES || errno == EAGAIN) { /* results may vary */ snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize, - "%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid); + "%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid); return -1; } NdbDaemon_ErrorCode = errno; snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize, - "%s: lock test failed: %s", lockfile, strerror(errno)); + "%s: lock test failed: %s", lockfile, strerror(errno)); return -1; } +#endif /* Test open log file before becoming daemon */ if (logfile != NULL) { logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644); @@ -77,6 +80,15 @@ NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags) return -1; } } +#ifdef F_TLOCK + if (lockf(lockfd, F_ULOCK, 0) == -1) + { + snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize, + "%s: fail to unlock", lockfile); + return -1; + } +#endif + /* Fork */ n = fork(); if (n == -1) { diff --git a/ndb/src/common/portlib/old_dirs/unix/Makefile_old b/ndb/src/common/portlib/old_dirs/unix/Makefile_old deleted file mode 100644 index 452196d9f08..00000000000 --- a/ndb/src/common/portlib/old_dirs/unix/Makefile_old +++ /dev/null @@ -1,27 +0,0 @@ -include .defs.mk - -TYPE := util - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := portlib - -SOURCES.c = NdbCondition.c \ - NdbMutex.c \ - NdbSleep.c \ - NdbTick.c \ - NdbEnv.c \ - NdbThread.c \ - NdbHost.c \ - NdbTCP.c \ - NdbDaemon.c - -ifeq ($(NDB_OS), SOFTOSE) - SOURCES += NdbMem_SoftOse.cpp -else - SOURCES.c += NdbMem.c -endif - -include $(NDB_TOP)/Epilogue.mk - -testNdbDaemon: NdbDaemon.c - $(CC) -o $@ NdbDaemon.c $(CCFLAGS) -DNDB_DAEMON_TEST -L$(NDB_TOP)/lib diff --git a/ndb/src/common/transporter/Makefile_old b/ndb/src/common/transporter/Makefile_old deleted file mode 100644 index 372bf640566..00000000000 --- a/ndb/src/common/transporter/Makefile_old +++ /dev/null @@ -1,43 +0,0 @@ -include .defs.mk - -TYPE := util - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := transporter -DIRS := basictest perftest - -# Source files of non-templated classes (.cpp files) -SOURCES = \ - Transporter.cpp \ - SendBuffer.cpp \ - TCP_Transporter.cpp \ - TransporterRegistry.cpp \ - Packer.cpp - -DIRS := basictest perftest - -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/kernel) \ - -I$(call fixpath,$(NDB_TOP)/include/transporter) - - -ifeq ($(NDB_SHM), Y) -SOURCES += SHM_Transporter.cpp -ifeq ($(NDB_OS), WIN32) -SOURCES += SHM_Transporter.win32.cpp -else -SOURCES += SHM_Transporter.unix.cpp -endif -endif - -ifeq ($(NDB_SCI), Y) -SOURCES += SCI_Transporter.cpp -endif - -ifneq ($(findstring OSE, $(NDB_OS)),) - SOURCES += OSE_Transporter.cpp - SOURCES += OSE_Receiver.cpp -endif - - - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/Makefile_old b/ndb/src/common/util/Makefile_old deleted file mode 100644 index 65093396246..00000000000 --- a/ndb/src/common/util/Makefile_old +++ /dev/null @@ -1,28 +0,0 @@ -include .defs.mk - -TYPE := util - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := general - -SOURCES = File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ - SimpleProperties.cpp Parser.cpp InputStream.cpp SocketServer.cpp \ - OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ - NdbSqlUtil.cpp ConfigValues.cpp new.cpp - -SOURCES.c = uucode.c random.c getarg.c version.c - -ifeq ($(NDB_OS), OSE) - SOURCES += NdbErrHnd.cpp -endif -ifeq ($(NDB_OS), OSE) - SOURCES += NdbErrHnd.cpp -endif - SOURCES.c += strdup.c strlcat.c strlcpy.c - -DIRS := testSimpleProperties testProperties testConfigValues - -include $(NDB_TOP)/Epilogue.mk - -testNdbSqlUtil: NdbSqlUtil.cpp - $(CC) -o $@ NdbSqlUtil.cpp $(CCFLAGS) -DNDB_SQL_UTIL_TEST -L$(NDB_TOP)/lib -lportlib -lgeneral diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp index c3cffa1399b..8bee256684d 100644 --- a/ndb/src/common/util/SocketServer.cpp +++ b/ndb/src/common/util/SocketServer.cpp @@ -259,6 +259,15 @@ transfer(NDB_SOCKET_TYPE sock){ } void +SocketServer::foreachSession(void (*func)(SocketServer::Session*, void *), void *data) +{ + for(int i = m_sessions.size() - 1; i >= 0; i--){ + (*func)(m_sessions[i].m_session, data); + } + checkSessions(); +} + +void SocketServer::checkSessions(){ for(int i = m_sessions.size() - 1; i >= 0; i--){ if(m_sessions[i].m_session->m_stopped){ @@ -278,8 +287,10 @@ void SocketServer::stopSessions(bool wait){ int i; for(i = m_sessions.size() - 1; i>=0; i--) - m_sessions[i].m_session->m_stop = true; - + { + m_sessions[i].m_session->stopSession(); + m_sessions[i].m_session->m_stop = true; // to make sure + } for(i = m_services.size() - 1; i>=0; i--) m_services[i].m_service->stopSessions(); diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c index 7307279f345..8a58ca0fe5c 100644 --- a/ndb/src/common/util/basestring_vsnprintf.c +++ b/ndb/src/common/util/basestring_vsnprintf.c @@ -20,6 +20,10 @@ #include <basestring_vsnprintf.h> #include <my_config.h> + +/* + #define SNPRINTF_RETURN_TRUNC +*/ int basestring_snprintf(char *str, size_t size, const char *format, ...) { @@ -40,7 +44,6 @@ basestring_snprintf(char *str, size_t size, const char *format, ...) * Let's hope vsnprintf works anyways */ #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d) - extern int my_vsnprintf(char *str, size_t size, const char *format, va_list ap); #endif #ifdef SNPRINTF_RETURN_TRUNC static char basestring_vsnprintf_buf[16*1024]; @@ -48,13 +51,27 @@ static char basestring_vsnprintf_buf[16*1024]; int basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap) { - int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap); + if (size == 0) + { #ifdef SNPRINTF_RETURN_TRUNC - if (ret == size-1 || ret == -1) { - ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf, - sizeof(basestring_vsnprintf_buf), - format, ap); + return BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf, + sizeof(basestring_vsnprintf_buf), + format, ap); +#else + char buf[1]; + return BASESTRING_VSNPRINTF_FUNC(buf, 1, format, ap); +#endif } + { + int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap); +#ifdef SNPRINTF_RETURN_TRUNC + if (ret == size-1 || ret == -1) + { + ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf, + sizeof(basestring_vsnprintf_buf), + format, ap); + } #endif - return ret; + return ret; + } } diff --git a/ndb/src/cw/Makefile_old b/ndb/src/cw/Makefile_old deleted file mode 100644 index e710c1e244d..00000000000 --- a/ndb/src/cw/Makefile_old +++ /dev/null @@ -1,6 +0,0 @@ -include .defs.mk - -DIRS := cpcd - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/cw/cpcd/Makefile_old b/ndb/src/cw/cpcd/Makefile_old deleted file mode 100644 index f214fb087d2..00000000000 --- a/ndb/src/cw/cpcd/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := util -BIN_TARGET := ndb_cpcd - -# Source files of non-templated classes (.cpp files) -SOURCES = main.cpp CPCD.cpp Process.cpp APIService.cpp Monitor.cpp common.cpp - -BIN_TARGET_LIBS += logger - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/Makefile_old b/ndb/src/kernel/Makefile_old deleted file mode 100644 index d1f1741aca4..00000000000 --- a/ndb/src/kernel/Makefile_old +++ /dev/null @@ -1,5 +0,0 @@ -include .defs.mk - -DIRS := error vm ndb-main blocks - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/Makefile_old b/ndb/src/kernel/blocks/Makefile_old deleted file mode 100644 index ce554dfc3b8..00000000000 --- a/ndb/src/kernel/blocks/Makefile_old +++ /dev/null @@ -1,28 +0,0 @@ -#-------------------------------------------------------------------------- -# -# Name Makefile -# -# -# -# List subdirectories to be travered -include .defs.mk - -DIRS := \ - cmvmi \ - dbacc \ - dbdict \ - dbdih \ - dblqh \ - dbtc \ - dbtup \ - ndbfs \ - ndbcntr \ - qmgr \ - trix \ - backup \ - dbutil \ - suma \ - grep \ - dbtux - -include ${NDB_TOP}/Epilogue.mk diff --git a/ndb/src/kernel/blocks/backup/Makefile_old b/ndb/src/kernel/blocks/backup/Makefile_old deleted file mode 100644 index 989199cbe02..00000000000 --- a/ndb/src/kernel/blocks/backup/Makefile_old +++ /dev/null @@ -1,18 +0,0 @@ -include .defs.mk - -TYPE := kernel - -#ifneq ($(MYSQLCLUSTER_TOP),) -DIRS := restore -#endif - -ARCHIVE_TARGET := backup - -SOURCES = Backup.cpp BackupInit.cpp - -include $(NDB_TOP)/Epilogue.mk - -$(NDB_TOP)/bin/readBackupFile: read.o - $(C++) -o $@ read.o \ - $(NDB_TOP)/lib/libportlib.a $(NDB_TOP)/lib/libgeneral.a - diff --git a/ndb/src/kernel/blocks/cmvmi/Makefile_old b/ndb/src/kernel/blocks/cmvmi/Makefile_old deleted file mode 100644 index d75e5dbf08b..00000000000 --- a/ndb/src/kernel/blocks/cmvmi/Makefile_old +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := cmvmi - -SOURCES = Cmvmi.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbacc/Makefile_old b/ndb/src/kernel/blocks/dbacc/Makefile_old deleted file mode 100644 index 93a830cec95..00000000000 --- a/ndb/src/kernel/blocks/dbacc/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbacc - -SOURCES = \ - DbaccInit.cpp \ - DbaccMain.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbdict/Makefile_old b/ndb/src/kernel/blocks/dbdict/Makefile_old deleted file mode 100644 index 46d938114fb..00000000000 --- a/ndb/src/kernel/blocks/dbdict/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbdict - -SOURCES = \ - Dbdict.cpp - -DIRS := printSchemafile - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbdih/Makefile_old b/ndb/src/kernel/blocks/dbdih/Makefile_old deleted file mode 100644 index 83c1b95b5c4..00000000000 --- a/ndb/src/kernel/blocks/dbdih/Makefile_old +++ /dev/null @@ -1,13 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbdih - -DIRS := printSysfile - -SOURCES = \ - DbdihInit.cpp \ - DbdihMain.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dblqh/Makefile_old b/ndb/src/kernel/blocks/dblqh/Makefile_old deleted file mode 100644 index 520486d8058..00000000000 --- a/ndb/src/kernel/blocks/dblqh/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dblqh -DIRS := redoLogReader - -SOURCES = \ - DblqhInit.cpp \ - DblqhMain.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbtc/Makefile_old b/ndb/src/kernel/blocks/dbtc/Makefile_old deleted file mode 100644 index ae876ab1f84..00000000000 --- a/ndb/src/kernel/blocks/dbtc/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbtc -SOURCES = \ - DbtcInit.cpp \ - DbtcMain.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/kernel/blocks/dbtup/Makefile_old b/ndb/src/kernel/blocks/dbtup/Makefile_old deleted file mode 100644 index 87146f4b441..00000000000 --- a/ndb/src/kernel/blocks/dbtup/Makefile_old +++ /dev/null @@ -1,26 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbtup -SOURCES = \ - DbtupExecQuery.cpp \ - DbtupBuffer.cpp \ - DbtupRoutines.cpp \ - DbtupCommit.cpp \ - DbtupFixAlloc.cpp \ - DbtupTrigger.cpp \ - DbtupAbort.cpp \ - DbtupLCP.cpp \ - DbtupUndoLog.cpp \ - DbtupPageMap.cpp \ - DbtupPagMan.cpp \ - DbtupStoredProcDef.cpp \ - DbtupMeta.cpp \ - DbtupTabDesMan.cpp \ - DbtupGen.cpp \ - DbtupSystemRestart.cpp \ - DbtupIndex.cpp \ - DbtupDebug.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbtux/Makefile_old b/ndb/src/kernel/blocks/dbtux/Makefile_old deleted file mode 100644 index 30927c31848..00000000000 --- a/ndb/src/kernel/blocks/dbtux/Makefile_old +++ /dev/null @@ -1,17 +0,0 @@ -include .defs.mk - -TYPE = kernel - -ARCHIVE_TARGET = dbtux - -SOURCES = \ - DbtuxGen.cpp \ - DbtuxMeta.cpp \ - DbtuxMaint.cpp \ - DbtuxNode.cpp \ - DbtuxTree.cpp \ - DbtuxScan.cpp \ - DbtuxCmp.cpp \ - DbtuxDebug.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/dbutil/Makefile_old b/ndb/src/kernel/blocks/dbutil/Makefile_old deleted file mode 100644 index 54b7326e4e5..00000000000 --- a/ndb/src/kernel/blocks/dbutil/Makefile_old +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := dbutil -SOURCES = DbUtil.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/grep/Makefile_old b/ndb/src/kernel/blocks/grep/Makefile_old deleted file mode 100644 index 5ad5a0bce3b..00000000000 --- a/ndb/src/kernel/blocks/grep/Makefile_old +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := grep - -SOURCES = Grep.cpp GrepInit.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/ndbcntr/Makefile_old b/ndb/src/kernel/blocks/ndbcntr/Makefile_old deleted file mode 100644 index 8e9c4f01027..00000000000 --- a/ndb/src/kernel/blocks/ndbcntr/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := ndbcntr - -SOURCES = \ - NdbcntrInit.cpp \ - NdbcntrSysTable.cpp \ - NdbcntrMain.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/ndbfs/Makefile_old b/ndb/src/kernel/blocks/ndbfs/Makefile_old deleted file mode 100644 index 58e1458bf16..00000000000 --- a/ndb/src/kernel/blocks/ndbfs/Makefile_old +++ /dev/null @@ -1,14 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := ndbfs - -SOURCES = \ - AsyncFile.cpp \ - Ndbfs.cpp VoidFs.cpp \ - Filename.cpp \ - CircularIndex.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/kernel/blocks/qmgr/Makefile_old b/ndb/src/kernel/blocks/qmgr/Makefile_old deleted file mode 100644 index cd15643ea60..00000000000 --- a/ndb/src/kernel/blocks/qmgr/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := qmgr - -SOURCES = \ - QmgrInit.cpp \ - QmgrMain.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/suma/Makefile_old b/ndb/src/kernel/blocks/suma/Makefile_old deleted file mode 100644 index 20014c94670..00000000000 --- a/ndb/src/kernel/blocks/suma/Makefile_old +++ /dev/null @@ -1,10 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := suma - -SOURCES = Suma.cpp SumaInit.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/src/kernel/blocks/trix/Makefile_old b/ndb/src/kernel/blocks/trix/Makefile_old deleted file mode 100644 index 5ac0da11f33..00000000000 --- a/ndb/src/kernel/blocks/trix/Makefile_old +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := trix -SOURCES = Trix.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/error/Makefile_old b/ndb/src/kernel/error/Makefile_old deleted file mode 100644 index 0fe81f083ce..00000000000 --- a/ndb/src/kernel/error/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := error - -SOURCES = \ - TimeModule.cpp \ - ErrorReporter.cpp \ - ErrorMessages.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/vm/Makefile_old b/ndb/src/kernel/vm/Makefile_old deleted file mode 100644 index a162f3672ce..00000000000 --- a/ndb/src/kernel/vm/Makefile_old +++ /dev/null @@ -1,30 +0,0 @@ -include .defs.mk - -TYPE := kernel - -ARCHIVE_TARGET := kernel - -SOURCES = \ - SimulatedBlock.cpp \ - FastScheduler.cpp \ - TimeQueue.cpp \ - VMSignal.cpp \ - ThreadConfig.cpp \ - TransporterCallback.cpp \ - Emulator.cpp \ - Configuration.cpp \ - WatchDog.cpp \ - SimplePropertiesSection.cpp \ - SectionReader.cpp \ - MetaData.cpp \ - Mutex.cpp SafeCounter.cpp - -CFLAGS_Configuration.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) - -DIRS := testCopy testDataBuffer testSimplePropertiesSection - -ifneq ($(USE_EDITLINE), N) -DIRS += testLongSig -endif - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/mgmapi/Makefile_old b/ndb/src/mgmapi/Makefile_old deleted file mode 100644 index fa734f998e6..00000000000 --- a/ndb/src/mgmapi/Makefile_old +++ /dev/null @@ -1,27 +0,0 @@ -include .defs.mk - -TYPE := util - -PIC_ARCHIVE := Y -ARCHIVE_TARGET := mgmapi - -A_LIB := Y -SO_LIB := Y -PIC_LIB := Y - -#DIRS := test - -LIB_TARGET := MGM_API -LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) general portlib - -# Source files of non-templated classes (.C files) -SOURCES = mgmapi.cpp mgmapi_configuration.cpp - -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ - -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) - -CCFLAGS += -DNO_DEBUG_MESSAGES - -# -I$(NDB_TOP)/src/common/mgmcommon - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 4b62df968b3..66f0dbb1842 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -1834,4 +1834,46 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle, return res; } +extern "C" +int +ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){ + CHECK_HANDLE(handle, 0); + CHECK_CONNECTED(handle, 0); + + Properties args; + + const ParserRow<ParserDummy> reply[]= { + MGM_CMD("purge stale sessions reply", NULL, ""), + MGM_ARG("purged", String, Optional, ""), + MGM_ARG("result", String, Mandatory, "Error message"), + MGM_END() + }; + + const Properties *prop; + prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args); + + if(prop == NULL) { + SET_ERROR(handle, EIO, "Unable to purge stale sessions"); + return -1; + } + + int res= -1; + do { + const char * buf; + if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + ndbout_c("ERROR Message: %s\n", buf); + break; + } + if (purged) { + if (prop->get("purged", &buf)) + *purged= strdup(buf); + else + *purged= 0; + } + res= 0; + } while(0); + delete prop; + return res; +} + template class Vector<const ParserRow<ParserDummy>*>; diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index e0935c2104e..fde4e5a2e91 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -17,7 +17,195 @@ #include <ndb_global.h> #include <my_sys.h> -#include "CommandInterpreter.hpp" +//#define HAVE_GLOBAL_REPLICATION + +#include <Vector.hpp> +#ifdef HAVE_GLOBAL_REPLICATION +#include "../rep/repapi/repapi.h" +#endif + +#include <mgmapi.h> + +class MgmtSrvr; + +/** + * @class CommandInterpreter + * @brief Reads command line in management client + * + * This class has one public method which reads a command line + * from a stream. It then interpret that commmand line and calls a suitable + * method in the MgmtSrvr class which executes the command. + * + * For command syntax, see the HELP command. + */ +class CommandInterpreter { +public: + /** + * Constructor + * @param mgmtSrvr: Management server to use when executing commands + */ + CommandInterpreter(const char *); + ~CommandInterpreter(); + + /** + * Reads one line from the stream, parse the line to find + * a command and then calls a suitable method which executes + * the command. + * + * @return true until quit/bye/exit has been typed + */ + int execute(const char *_line, int _try_reconnect=-1); + +private: + void printError(); + + /** + * Analyse the command line, after the first token. + * + * @param processId: DB process id to send command to or -1 if + * command will be sent to all DB processes. + * @param allAfterFirstToken: What the client gave after the + * first token on the command line + */ + void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr); + + /** + * Parse the block specification part of the LOG* commands, + * things after LOG*: [BLOCK = {ALL|<blockName>+}] + * + * @param allAfterLog: What the client gave after the second token + * (LOG*) on the command line + * @param blocks, OUT: ALL or name of all the blocks + * @return: true if correct syntax, otherwise false + */ + bool parseBlockSpecification(const char* allAfterLog, + Vector<const char*>& blocks); + + /** + * A bunch of execute functions: Executes one of the commands + * + * @param processId: DB process id to send command to + * @param parameters: What the client gave after the command name + * on the command line. + * For example if complete input from user is: "1 LOGLEVEL 22" then the + * parameters argument is the string with everything after LOGLEVEL, in + * this case "22". Each function is responsible to check the parameters + * argument. + */ + void executeHelp(char* parameters); + void executeShow(char* parameters); + void executePurge(char* parameters); + void executeShutdown(char* parameters); + void executeRun(char* parameters); + void executeInfo(char* parameters); + void executeClusterLog(char* parameters); + +public: + void executeStop(int processId, const char* parameters, bool all); + void executeEnterSingleUser(char* parameters); + void executeExitSingleUser(char* parameters); + void executeStart(int processId, const char* parameters, bool all); + void executeRestart(int processId, const char* parameters, bool all); + void executeLogLevel(int processId, const char* parameters, bool all); + void executeError(int processId, const char* parameters, bool all); + void executeTrace(int processId, const char* parameters, bool all); + void executeLog(int processId, const char* parameters, bool all); + void executeLogIn(int processId, const char* parameters, bool all); + void executeLogOut(int processId, const char* parameters, bool all); + void executeLogOff(int processId, const char* parameters, bool all); + void executeTestOn(int processId, const char* parameters, bool all); + void executeTestOff(int processId, const char* parameters, bool all); + void executeSet(int processId, const char* parameters, bool all); + void executeGetStat(int processId, const char* parameters, bool all); + void executeStatus(int processId, const char* parameters, bool all); + void executeEventReporting(int processId, const char* parameters, bool all); + void executeDumpState(int processId, const char* parameters, bool all); + void executeStartBackup(char * parameters); + void executeAbortBackup(char * parameters); + + void executeRep(char* parameters); + + void executeCpc(char * parameters); + +public: + bool connect(); + bool disconnect(); + + /** + * A execute function definition + */ +public: + typedef void (CommandInterpreter::* ExecuteFunction)(int processId, + const char * param, + bool all); + + struct CommandFunctionPair { + const char * command; + ExecuteFunction executeFunction; + }; +private: + /** + * + */ + void executeForAll(const char * cmd, + ExecuteFunction fun, + const char * param); + + NdbMgmHandle m_mgmsrv; + bool connected; + const char *host; + int try_reconnect; +#ifdef HAVE_GLOBAL_REPLICATION + NdbRepHandle m_repserver; + const char *rep_host; + bool rep_connected; +#endif +}; + + +/* + * Facade object for CommandInterpreter + */ + +#include "ndb_mgmclient.hpp" +#include "ndb_mgmclient.h" + +Ndb_mgmclient::Ndb_mgmclient(const char *host) +{ + m_cmd= new CommandInterpreter(host); +} +Ndb_mgmclient::~Ndb_mgmclient() +{ + delete m_cmd; +} +int Ndb_mgmclient::execute(const char *_line, int _try_reconnect) +{ + return m_cmd->execute(_line,_try_reconnect); +} +int +Ndb_mgmclient::disconnect() +{ + return m_cmd->disconnect(); +} + +extern "C" { + Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string) + { + return (Ndb_mgmclient_handle) new Ndb_mgmclient(connect_string); + } + int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, const char** argv) + { + return ((Ndb_mgmclient*)h)->execute(argc, argv, 1); + } + int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle h) + { + delete (Ndb_mgmclient*)h; + return 0; + } +} +/* + * The CommandInterpreter + */ #include <mgmapi.h> #include <mgmapi_debug.h> @@ -33,8 +221,22 @@ #endif // HAVE_GLOBAL_REPLICATION #include "MgmtErrorReporter.hpp" -#include "CpcClient.hpp" +#include <Parser.hpp> +#include <SocketServer.hpp> +#include <util/InputStream.hpp> +#include <util/OutputStream.hpp> +int Ndb_mgmclient::execute(int argc, const char** argv, int _try_reconnect) +{ + if (argc <= 0) + return 0; + BaseString _line(argv[0]); + for (int i= 1; i < argc; i++) + { + _line.appfmt(" %s", argv[i]); + } + return m_cmd->execute(_line.c_str(),_try_reconnect); +} /***************************************************************************** * HELP @@ -73,6 +275,7 @@ static const char* helpText = #ifdef HAVE_GLOBAL_REPLICATION "REP CONNECT <host:port> Connect to REP server on host:port\n" #endif +"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n" "QUIT Quit management client\n" ; @@ -201,7 +404,7 @@ CommandInterpreter::~CommandInterpreter() host = NULL; } -bool +static bool emptyString(const char* s) { if (s == NULL) { @@ -264,18 +467,15 @@ CommandInterpreter::disconnect() //***************************************************************************** int -CommandInterpreter::readAndExecute(int _try_reconnect) +CommandInterpreter::execute(const char *_line, int _try_reconnect) { if (_try_reconnect >= 0) try_reconnect=_try_reconnect; - - char* _line = readline_gets(); char * line; if(_line == NULL) { // ndbout << endl; return false; } - line = my_strdup(_line,MYF(MY_WME)); My_auto_ptr<char> ptr(line); @@ -320,6 +520,10 @@ CommandInterpreter::readAndExecute(int _try_reconnect) executeAbortBackup(allAfterFirstToken); return true; } + else if (strcmp(firstToken, "PURGE") == 0) { + executePurge(allAfterFirstToken); + return true; + } #ifdef HAVE_GLOBAL_REPLICATION else if(strcmp(firstToken, "REPLICATION") == 0 || strcmp(firstToken, "REP") == 0) { @@ -349,10 +553,6 @@ CommandInterpreter::readAndExecute(int _try_reconnect) strcmp(firstToken, "BYE") == 0) && allAfterFirstToken == NULL){ return false; -#if 0 - } else if(strcmp(firstToken, "CPC") == 0) { - executeCpc(allAfterFirstToken); -#endif } else { /** * First token should be a digit, node ID @@ -766,6 +966,46 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, } void +CommandInterpreter::executePurge(char* parameters) +{ + int command_ok= 0; + do { + if (emptyString(parameters)) + break; + char* firstToken = strtok(parameters, " "); + char* nextToken = strtok(NULL, " \0"); + if (strcmp(firstToken,"STALE") == 0 && + nextToken && + strcmp(nextToken, "SESSIONS") == 0) { + command_ok= 1; + break; + } + } while(0); + + if (!command_ok) { + ndbout_c("Unexpected command, expected: PURGE STALE SESSIONS"); + return; + } + + int i; + char *str; + connect(); + + if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) { + ndbout_c("Command failed"); + return; + } + if (str) { + ndbout_c("Purged sessions with node id's: %s", str); + free(str); + } + else + { + ndbout_c("No sessions purged"); + } +} + +void CommandInterpreter::executeShow(char* parameters) { int i; @@ -1903,169 +2143,4 @@ CommandInterpreter::executeRep(char* parameters) } #endif // HAVE_GLOBAL_REPLICATION - -/***************************************************************************** - * CPC - *****************************************************************************/ - -#if 0 - -#if 0 -//#ifdef NDB_SOLARIS // XXX fix me -static char* strsep(char** x, const char* y) { return 0; } -#endif - -// Note this code has not been verified -#if 0 -static char * my_strsep(char **stringp, const char *delim) -{ - char *tmp= *stringp; - if (tmp == 0) - return 0; - *stringp = strtok(tmp, delim); - return tmp; -} -#endif - -void -CommandInterpreter::executeCpc(char *parameters) -{ - char *host_str = NULL, *port_str = NULL, *end; - long port = 1234; /* XXX */ - - while((host_str = my_strsep(¶meters, " \t:")) != NULL && - host_str[0] == '\0'); - - if(parameters && parameters[0] != '\0') { - while((port_str = my_strsep(¶meters, " \t:")) != NULL && - port_str[0] == '\0'); - - errno = 0; - port = strtol(port_str, &end, 0); - if(end[0] != '\0') - goto error; - if((port == LONG_MAX || port == LONG_MIN) && - errno == ERANGE) - goto error; - } - - { - SimpleCpcClient cpc(host_str, port); - bool done = false; - - if(cpc.connect() < 0) { - ndbout_c("Cannot connect to %s:%d.", cpc.getHost(), cpc.getPort()); - switch(errno) { - case ENOENT: - ndbout << ": " << "No such host" << endl; - break; - default: - ndbout << ": " << strerror(errno) << endl; - break; - } - return; - } - - while(!done) { - char *line = readline("CPC> "); - if(line != NULL) { - add_history(line); - - char *cmd = strtok(line, " "); - char *arg = strtok(NULL, ""); - - if(arg != NULL) { - while(arg[0] == ' ') - arg++; - if(strlen(arg) == 0) - arg = NULL; - } - - if(cmd != NULL) { - if(strcmp(cmd, "exit") == 0) - done = true; - else if(strcmp(cmd, "list") == 0) - cpc.cmd_list(arg); - else if(strcmp(cmd, "start") == 0) - cpc.cmd_start(arg); - else if(strcmp(cmd, "stop") == 0) - cpc.cmd_stop(arg); - else if(strcmp(cmd, "help") == 0) - cpc.cmd_help(arg); - } - } else { - done = true; - ndbout << endl; - } - } - } - return; - - error: - ndbout << "Error: expected a tcp port number, got '" << port_str << "'." - << endl; - return; -} -#endif - -#if 0 -static -void -CmdBackupCallback(const MgmtSrvr::BackupEvent & event){ - char str[255]; - - ndbout << endl; - - bool ok = false; - switch(event.Event){ - case MgmtSrvr::BackupEvent::BackupStarted: - ok = true; - BaseString::snprintf(str, sizeof(str), - "Backup %d started", event.Started.BackupId); - break; - case MgmtSrvr::BackupEvent::BackupFailedToStart: - ok = true; - BaseString::snprintf(str, sizeof(str), - "Backup failed to start (Error %d)", - event.FailedToStart.ErrorCode); - break; - case MgmtSrvr::BackupEvent::BackupCompleted: - ok = true; - BaseString::snprintf(str, sizeof(str), - "Backup %d completed", - event.Completed.BackupId); - ndbout << str << endl; - - BaseString::snprintf(str, sizeof(str), - " StartGCP: %d StopGCP: %d", - event.Completed.startGCP, event.Completed.stopGCP); - ndbout << str << endl; - - BaseString::snprintf(str, sizeof(str), - " #Records: %d #LogRecords: %d", - event.Completed.NoOfRecords, event.Completed.NoOfLogRecords); - ndbout << str << endl; - - BaseString::snprintf(str, sizeof(str), - " Data: %d bytes Log: %d bytes", - event.Completed.NoOfBytes, event.Completed.NoOfLogBytes); - break; - case MgmtSrvr::BackupEvent::BackupAborted: - ok = true; - BaseString::snprintf(str, sizeof(str), - "Backup %d has been aborted reason %d", - event.Aborted.BackupId, - event.Aborted.Reason); - break; - } - if(!ok){ - BaseString::snprintf(str, sizeof(str), - "Unknown backup event: %d", - event.Event); - - } - ndbout << str << endl; -} -#endif - template class Vector<char const*>; diff --git a/ndb/src/mgmclient/CommandInterpreter.hpp b/ndb/src/mgmclient/CommandInterpreter.hpp deleted file mode 100644 index eecc48a739e..00000000000 --- a/ndb/src/mgmclient/CommandInterpreter.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (C) 2003 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; either version 2 of the License, or - (at your option) any later version. - - 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 */ - -#ifndef CommandInterpreter_H -#define CommandInterpreter_H - -//#define HAVE_GLOBAL_REPLICATION -//***************************************************************************** -// Author: Peter Lind -//***************************************************************************** - -#include <ndb_global.h> -#include <Vector.hpp> -#include <editline/editline.h> - -#ifdef HAVE_GLOBAL_REPLICATION -#include "../rep/repapi/repapi.h" -#endif - -#include <mgmapi.h> - -class MgmtSrvr; - -/** - * @class CommandInterpreter - * @brief Reads command line in management client - * - * This class has one public method which reads a command line - * from a stream. It then interpret that commmand line and calls a suitable - * method in the MgmtSrvr class which executes the command. - * - * For command syntax, see the HELP command. - */ -class CommandInterpreter { -public: - /** - * Constructor - * @param mgmtSrvr: Management server to use when executing commands - */ - CommandInterpreter(const char *); - ~CommandInterpreter(); - - /** - * Reads one line from the stream, parse the line to find - * a command and then calls a suitable method which executes - * the command. - * - * @return true until quit/bye/exit has been typed - */ - int readAndExecute(int _try_reconnect=-1); - -private: - /** - * Read a string, and return a pointer to it. - * - * @return NULL on EOF. - */ - char *readline_gets () - { - static char *line_read = (char *)NULL; - - /* If the buffer has already been allocated, return the memory - to the free pool. */ - if (line_read) - { - free (line_read); - line_read = (char *)NULL; - } - - /* Get a line from the user. */ - line_read = readline ("NDB> "); - - /* If the line has any text in it, save it on the history. */ - if (line_read && *line_read) - add_history (line_read); - - return (line_read); - } - - void printError(); - - /** - * Analyse the command line, after the first token. - * - * @param processId: DB process id to send command to or -1 if - * command will be sent to all DB processes. - * @param allAfterFirstToken: What the client gave after the - * first token on the command line - */ - void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr); - - /** - * Parse the block specification part of the LOG* commands, - * things after LOG*: [BLOCK = {ALL|<blockName>+}] - * - * @param allAfterLog: What the client gave after the second token - * (LOG*) on the command line - * @param blocks, OUT: ALL or name of all the blocks - * @return: true if correct syntax, otherwise false - */ - bool parseBlockSpecification(const char* allAfterLog, - Vector<const char*>& blocks); - - /** - * A bunch of execute functions: Executes one of the commands - * - * @param processId: DB process id to send command to - * @param parameters: What the client gave after the command name - * on the command line. - * For example if complete input from user is: "1 LOGLEVEL 22" then the - * parameters argument is the string with everything after LOGLEVEL, in - * this case "22". Each function is responsible to check the parameters - * argument. - */ - void executeHelp(char* parameters); - void executeShow(char* parameters); - void executeShutdown(char* parameters); - void executeRun(char* parameters); - void executeInfo(char* parameters); - void executeClusterLog(char* parameters); - -public: - void executeStop(int processId, const char* parameters, bool all); - void executeEnterSingleUser(char* parameters); - void executeExitSingleUser(char* parameters); - void executeStart(int processId, const char* parameters, bool all); - void executeRestart(int processId, const char* parameters, bool all); - void executeLogLevel(int processId, const char* parameters, bool all); - void executeError(int processId, const char* parameters, bool all); - void executeTrace(int processId, const char* parameters, bool all); - void executeLog(int processId, const char* parameters, bool all); - void executeLogIn(int processId, const char* parameters, bool all); - void executeLogOut(int processId, const char* parameters, bool all); - void executeLogOff(int processId, const char* parameters, bool all); - void executeTestOn(int processId, const char* parameters, bool all); - void executeTestOff(int processId, const char* parameters, bool all); - void executeSet(int processId, const char* parameters, bool all); - void executeGetStat(int processId, const char* parameters, bool all); - void executeStatus(int processId, const char* parameters, bool all); - void executeEventReporting(int processId, const char* parameters, bool all); - void executeDumpState(int processId, const char* parameters, bool all); - void executeStartBackup(char * parameters); - void executeAbortBackup(char * parameters); - - void executeRep(char* parameters); - - void executeCpc(char * parameters); - -public: - bool connect(); - bool disconnect(); - - /** - * A execute function definition - */ -public: - typedef void (CommandInterpreter::* ExecuteFunction)(int processId, - const char * param, - bool all); - - struct CommandFunctionPair { - const char * command; - ExecuteFunction executeFunction; - }; -private: - /** - * - */ - void executeForAll(const char * cmd, - ExecuteFunction fun, - const char * param); - - NdbMgmHandle m_mgmsrv; - bool connected; - const char *host; - int try_reconnect; -#ifdef HAVE_GLOBAL_REPLICATION - NdbRepHandle m_repserver; - const char *rep_host; - bool rep_connected; -#endif -}; - -#endif // CommandInterpreter_H diff --git a/ndb/src/mgmclient/Makefile.am b/ndb/src/mgmclient/Makefile.am index e271c7bed53..cd6ddb0ad57 100644 --- a/ndb/src/mgmclient/Makefile.am +++ b/ndb/src/mgmclient/Makefile.am @@ -1,18 +1,19 @@ +noinst_LTLIBRARIES = libndbmgmclient.la ndbtools_PROGRAMS = ndb_mgm -ndb_mgm_SOURCES = \ - main.cpp \ - CommandInterpreter.cpp \ - CpcClient.cpp +libndbmgmclient_la_SOURCES = CommandInterpreter.cpp + +ndb_mgm_SOURCES = main.cpp include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapi.mk.am INCLUDES += -I$(top_srcdir)/ndb/include/mgmapi -I$(top_srcdir)/ndb/src/common/mgmcommon -LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \ - $(top_builddir)/ndb/src/common/editline/libeditline.a \ +LDADD_LOC = $(noinst_LTLIBRARIES) \ + @readline_link@ \ + $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ diff --git a/ndb/src/mgmclient/Makefile_old b/ndb/src/mgmclient/Makefile_old deleted file mode 100644 index d1b2d60a52a..00000000000 --- a/ndb/src/mgmclient/Makefile_old +++ /dev/null @@ -1,25 +0,0 @@ -include .defs.mk - -TYPE := ndbapi - -BIN_TARGET := mgmtclient -BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := trace logger mgmapi general mgmsrvcommon portlib repapi - -BIN_TARGET_ARCHIVES += editline - -DIRS = test_cpcd - -# Source files of non-templated classes (.cpp files) -SOURCES = \ - main.cpp \ - CommandInterpreter.cpp \ - CpcClient.cpp - -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ - -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) - -include $(NDB_TOP)/Epilogue.mk - -_bins_mkconfig : $(NDB_TOP)/bin/$(BIN_TARGET) - diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index a37214d366b..8f5d9e6656c 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -17,18 +17,29 @@ #include <ndb_global.h> #include <ndb_opts.h> +// copied from mysql.cc to get readline +extern "C" { +#if defined( __WIN__) || defined(OS2) +#include <conio.h> +#elif !defined(__NETWARE__) +#include <readline/readline.h> +extern "C" int add_history(const char *command); /* From readline directory */ +#define HAVE_READLINE +#endif +} + #include <NdbMain.h> #include <NdbHost.h> #include <mgmapi.h> #include <ndb_version.h> #include <LocalConfig.hpp> -#include "CommandInterpreter.hpp" +#include "ndb_mgmclient.hpp" const char *progname = "ndb_mgm"; -static CommandInterpreter* com; +static Ndb_mgmclient* com; extern "C" void @@ -90,6 +101,39 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), return 0; } +static int +read_and_execute(int _try_reconnect) +{ + static char *line_read = (char *)NULL; + + /* If the buffer has already been allocated, return the memory + to the free pool. */ + if (line_read) + { + free (line_read); + line_read = (char *)NULL; + } +#ifdef HAVE_READLINE + /* Get a line from the user. */ + line_read = readline ("ndb_mgm> "); + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) + add_history (line_read); +#else + static char linebuffer[254]; + fputs("ndb_mgm> ", stdout); + linebuffer[sizeof(linebuffer)-1]=0; + line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); + if (line_read == linebuffer) { + char *q=linebuffer; + while (*q > 31) q++; + *q=0; + line_read= strdup(linebuffer); + } +#endif + return com->execute(line_read,_try_reconnect); +} + int main(int argc, char** argv){ NDB_INIT(argv[0]); const char *_host = 0; @@ -127,8 +171,8 @@ int main(int argc, char** argv){ signal(SIGPIPE, handler); - com = new CommandInterpreter(buf); - while(com->readAndExecute(_try_reconnect)); + com = new Ndb_mgmclient(buf); + while(read_and_execute(_try_reconnect)); delete com; return 0; diff --git a/ndb/src/common/editline/test/testit.c b/ndb/src/mgmclient/ndb_mgmclient.h index 4058f8ae660..265e6bc67ec 100644 --- a/ndb/src/common/editline/test/testit.c +++ b/ndb/src/mgmclient/ndb_mgmclient.h @@ -14,42 +14,20 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* -*- c-basic-offset: 4; -*- -** $Revision: 1.5 $ -** -** A "micro-shell" to test editline library. -** If given any arguments, commands aren't executed. -*/ -#include <ndb_global.h> -#include <editline/editline.h> - -int -main(int argc, char **argv) -{ - char *prompt; - char *p; - int doit; - - (void)argv; /* Suppress warning */ - - doit = argc == 1; - if ((prompt = getenv("TESTPROMPT")) == NULL) - prompt = "testit> "; - - while ((p = readline(prompt)) != NULL) { - (void)printf("\t\t\t|%s|\n", p); - if (doit) { - if (strncmp(p, "cd ", 3) == 0) { - if (chdir(&p[3]) < 0) - perror(&p[3]); - } else { - if (system(p) != 0) - perror(p); - } - } - add_history(p); - free(p); - } - - return 0; +#ifndef Ndb_mgmclient_h +#define Ndb_mgmclient_h + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* Ndb_mgmclient_handle; +Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string); +int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, const char** argv); +int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle); + +#ifdef __cplusplus } +#endif + +#endif /* Ndb_mgmclient_h */ diff --git a/ndb/src/common/editline/editline_win32.c b/ndb/src/mgmclient/ndb_mgmclient.hpp index 5083edb7fae..933d1bab5ce 100644 --- a/ndb/src/common/editline/editline_win32.c +++ b/ndb/src/mgmclient/ndb_mgmclient.hpp @@ -14,19 +14,20 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef Ndb_mgmclient_hpp +#define Ndb_mgmclient_hpp -#include <ndb_global.h> - - -char* readline(const char* prompt) +class CommandInterpreter; +class Ndb_mgmclient { - char* szBuf; - printf(prompt); - szBuf = (char*)malloc(256); - return gets(szBuf); -} - -void add_history(char* pch) -{ -} - +public: + Ndb_mgmclient(const char*); + ~Ndb_mgmclient(); + int execute(const char *_line, int _try_reconnect=-1); + int execute(int argc, const char** argv, int _try_reconnect=-1); + int disconnect(); +private: + CommandInterpreter *m_cmd; +}; + +#endif // Ndb_mgmclient_hpp diff --git a/ndb/src/mgmsrv/CommandInterpreter.hpp b/ndb/src/mgmsrv/CommandInterpreter.hpp index 3466ee76226..db23f76a5bd 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.hpp +++ b/ndb/src/mgmsrv/CommandInterpreter.hpp @@ -23,7 +23,6 @@ #include <ndb_global.h> #include <Vector.hpp> -#include <editline/editline.h> #include <BaseString.hpp> class MgmtSrvr; @@ -63,26 +62,27 @@ private: */ char *readline_gets () { + static char linebuffer[254]; static char *line_read = (char *)NULL; - // Disable the default file-name completion action of TAB - // rl_bind_key ('\t', rl_insert); - /* If the buffer has already been allocated, return the memory to the free pool. */ if (line_read) - { - free (line_read); - line_read = (char *)NULL; - } + { + free (line_read); + line_read = (char *)NULL; + } /* Get a line from the user. */ - line_read = readline ("NDB> "); - - /* If the line has any text in it, save it on the history. */ - if (line_read && *line_read) - add_history (line_read); - + fputs("ndb_mgmd> ", stdout); + linebuffer[sizeof(linebuffer)-1]=0; + line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); + if (line_read == linebuffer) { + char *q=linebuffer; + while (*q > 31) q++; + *q=0; + line_read= strdup(linebuffer); + } return (line_read); } diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index ad346b30ead..4af1556a0c0 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1478,7 +1478,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::USED, false, ConfigInfo::INT, - NDB_BASE_PORT, + NDB_PORT, "0", STR_VALUE(MAX_INT_RNIL) }, @@ -1490,7 +1490,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::USED, false, ConfigInfo::INT, - "2199", + UNDEFINED, "0", STR_VALUE(MAX_INT_RNIL) }, @@ -3010,7 +3010,7 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ if(!(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) && !ctx.m_systemDefaults->get("PortNumber", &base)) { - base= strtoll(NDB_BASE_PORT,0,0)+2; + base= strtoll(NDB_BASE_PORT,0,0); // ctx.reportError("Cannot retrieve base port number"); // return false; } @@ -3442,7 +3442,7 @@ static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>§ions, #if 0 Properties * props= ctx.m_config; Properties computers(true); - Uint32 port_base = NDB_BASE_PORT+2; + Uint32 port_base = NDB_BASE_PORT; Uint32 nNodes; ctx.m_userProperties.get("NoOfNodes", &nNodes); diff --git a/ndb/src/mgmsrv/Makefile.am b/ndb/src/mgmsrv/Makefile.am index 3b57b027827..ee5220ef9f8 100644 --- a/ndb/src/mgmsrv/Makefile.am +++ b/ndb/src/mgmsrv/Makefile.am @@ -24,7 +24,6 @@ INCLUDES_LOC = -I$(top_srcdir)/ndb/src/ndbapi \ -I$(top_srcdir)/ndb/src/common/mgmcommon LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \ - $(top_builddir)/ndb/src/common/editline/libeditline.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ @@ -34,6 +33,7 @@ DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\"" \ + -DNDB_PORT="\"@ndb_port@\"" \ -DNDB_BASE_PORT="\"@ndb_port_base@\"" include $(top_srcdir)/ndb/config/common.mk.am diff --git a/ndb/src/mgmsrv/Makefile_old b/ndb/src/mgmsrv/Makefile_old deleted file mode 100644 index c99875ae8b6..00000000000 --- a/ndb/src/mgmsrv/Makefile_old +++ /dev/null @@ -1,41 +0,0 @@ -include .defs.mk - -TYPE := ndbapi mgmapiclient - -BIN_TARGET := mgmtsrvr -BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := NDB_API mgmsrvcommon mgmapi general - -ifneq ($(USE_EDITLINE), N) -BIN_TARGET_ARCHIVES += editline -DIRS := mkconfig -endif -BIN_TARGET_ARCHIVES += general - -BIN_FLAGS += $(TERMCAP_LIB) - -# Source files of non-templated classes (.cpp files) -SOURCES = \ - MgmtSrvr.cpp \ - MgmtSrvrGeneralSignalHandling.cpp \ - main.cpp \ - Services.cpp \ - convertStrToInt.cpp \ - NodeLogLevel.cpp \ - NodeLogLevelList.cpp \ - SignalQueue.cpp \ - MgmtSrvrConfig.cpp - -ifeq ($(findstring OSE, $(NDB_OS)),) -SOURCES += CommandInterpreter.cpp -endif - -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/src/ndbapi) \ - -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ - -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ - -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) - -include $(NDB_TOP)/Epilogue.mk - -_bins_mkconfig : $(NDB_TOP)/bin/$(BIN_TARGET) - diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 2e30d73290b..a49b29af275 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -400,11 +400,13 @@ MgmtSrvr::getPort() const { /* Constructor */ MgmtSrvr::MgmtSrvr(NodeId nodeId, + SocketServer *socket_server, const BaseString &configFilename, LocalConfig &local_config, Config * config): _blockNumber(1), // Hard coded block number since it makes it easy to send // signals to other management servers. + m_socket_server(socket_server), _ownReference(0), m_local_config(local_config), theSignalIdleList(NULL), @@ -2094,6 +2096,25 @@ MgmtSrvr::getNodeType(NodeId nodeId) const return nodeTypes[nodeId]; } +void +MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const +{ + if (theFacade && theFacade->theClusterMgr) + { + for(Uint32 i = 0; i < MAX_NODES; i++) + { + if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) + { + const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); + if (node.connected) + { + connected_nodes.bitOR(node.m_state.m_connected_nodes); + } + } + } + } +} + bool MgmtSrvr::alloc_node_id(NodeId * nodeId, enum ndb_mgm_node_type type, @@ -2106,7 +2127,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, *nodeId, type, client_addr)); if (g_no_nodeid_checks) { if (*nodeId == 0) { - error_string.appfmt("no-nodeid-ckecks set in manegment server.\n" + error_string.appfmt("no-nodeid-checks set in management server.\n" "node id must be set explicitly in connectstring"); DBUG_RETURN(false); } @@ -2115,16 +2136,11 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, Guard g(m_node_id_mutex); int no_mgm= 0; NodeBitmask connected_nodes(m_reserved_nodes); - for(Uint32 i = 0; i < MAX_NODES; i++) + get_connected_nodes(connected_nodes); { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB && - theFacade && theFacade->theClusterMgr) { - const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); - if (node.connected) { - connected_nodes.bitOR(node.m_state.m_connected_nodes); - } - } else if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) - no_mgm++; + for(Uint32 i = 0; i < MAX_NODES; i++) + if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) + no_mgm++; } bool found_matching_id= false; bool found_matching_type= false; @@ -2227,6 +2243,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, m_connect_address[id_found].s_addr= 0; } m_reserved_nodes.set(id_found); + char tmp_str[128]; + m_reserved_nodes.getText(tmp_str); + g_EventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.", + id_found, get_connect_address(id_found), tmp_str); DBUG_RETURN(true); } @@ -2283,6 +2303,36 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, error_string.appfmt("No node defined with id=%d in config file.", *nodeId); } + + g_EventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. " + "Returned error string \"%s\"", + *nodeId, + client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>", + error_string.c_str()); + + NodeBitmask connected_nodes2; + get_connected_nodes(connected_nodes2); + { + BaseString tmp_connected, tmp_not_connected; + for(Uint32 i = 0; i < MAX_NODES; i++) + { + if (connected_nodes2.get(i)) + { + if (!m_reserved_nodes.get(i)) + tmp_connected.appfmt(" %d", i); + } + else if (m_reserved_nodes.get(i)) + { + tmp_not_connected.appfmt(" %d", i); + } + } + if (tmp_connected.length() > 0) + g_EventLogger.info("Mgmt server state: node id's %s connected but not reserved", + tmp_connected.c_str()); + if (tmp_not_connected.length() > 0) + g_EventLogger.info("Mgmt server state: node id's %s not connected but reserved", + tmp_not_connected.c_str()); + } DBUG_RETURN(false); } @@ -2531,10 +2581,15 @@ MgmtSrvr::Allocated_resources::~Allocated_resources() { Guard g(m_mgmsrv.m_node_id_mutex); if (!m_reserved_nodes.isclear()) { + m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); // node has been reserved, force update signal to ndb nodes global_flag_send_heartbeat_now= 1; + + char tmp_str[128]; + m_mgmsrv.m_reserved_nodes.getText(tmp_str); + g_EventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", + get_nodeid(), tmp_str); } - m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); } void @@ -2543,6 +2598,17 @@ MgmtSrvr::Allocated_resources::reserve_node(NodeId id) m_reserved_nodes.set(id); } +NodeId +MgmtSrvr::Allocated_resources::get_nodeid() const +{ + for(Uint32 i = 0; i < MAX_NODES; i++) + { + if (m_reserved_nodes.get(i)) + return i; + } + return 0; +} + int MgmtSrvr::setDbParameter(int node, int param, const char * value, BaseString& msg){ diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index c796e1e9219..b3257491123 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -96,7 +96,10 @@ public: // methods to reserve/allocate resources which // will be freed when running destructor void reserve_node(NodeId id); - bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId);} + bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId); } + bool is_reserved(NodeBitmask mask) { return !mask.bitAND(m_reserved_nodes).isclear(); } + bool isclear() { return m_reserved_nodes.isclear(); } + NodeId get_nodeid() const; private: MgmtSrvr &m_mgmsrv; NodeBitmask m_reserved_nodes; @@ -173,6 +176,7 @@ public: /* Constructor */ MgmtSrvr(NodeId nodeId, /* Local nodeid */ + SocketServer *socket_server, const BaseString &config_filename, /* Where to save config */ LocalConfig &local_config, /* Ndb.cfg filename */ Config * config); @@ -499,6 +503,9 @@ public: int setDbParameter(int node, int parameter, const char * value, BaseString&); const char *get_connect_address(Uint32 node_id) { return inet_ntoa(m_connect_address[node_id]); } + void get_connected_nodes(NodeBitmask &connected_nodes) const; + SocketServer *get_socket_server() { return m_socket_server; } + //************************************************************************** private: //************************************************************************** @@ -525,6 +532,8 @@ private: int _blockNumber; NodeId _ownNodeId; + SocketServer *m_socket_server; + BlockReference _ownReference; NdbMutex *m_configMutex; const Config * _config; diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 2672d8c9d4b..0394c4e80bb 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -242,6 +242,8 @@ ParserRow<MgmApiSession> commands[] = { MGM_ARG("node", Int, Optional, "Node"), MGM_ARG("filter", String, Mandatory, "Event category"), + MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""), + MGM_END() }; @@ -1412,6 +1414,46 @@ done: m_output->println(""); } +struct PurgeStruct +{ + NodeBitmask free_nodes;/* free nodes as reported + * by ndbd in apiRegReqConf + */ + BaseString *str; +}; + +void +MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *data) +{ + MgmApiSession *s= (MgmApiSession *)_s; + struct PurgeStruct &ps= *(struct PurgeStruct *)data; + if (s->m_allocated_resources->is_reserved(ps.free_nodes)) + { + ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid()); + s->stopSession(); + } +} + +void +MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx, + const class Properties &args) +{ + struct PurgeStruct ps; + BaseString str; + ps.str = &str; + + m_mgmsrv.get_connected_nodes(ps.free_nodes); + ps.free_nodes.bitXORC(NodeBitmask()); // invert connected_nodes to get free nodes + + m_mgmsrv.get_socket_server()->foreachSession(stop_session_if_not_connected,&ps); + + m_output->println("purge stale sessions reply"); + if (str.length() > 0) + m_output->println("purged:%s",str.c_str()); + m_output->println("result: Ok"); + m_output->println(""); +} + template class MutexVector<int>; template class Vector<ParserRow<MgmApiSession> const*>; template class Vector<unsigned short>; diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index e47820826b6..bfc915f18f1 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -28,7 +28,9 @@ /** Undefine this to remove backwards compatibility for "GET CONFIG". */ #define MGM_GET_CONFIG_BACKWARDS_COMPAT -class MgmApiSession : public SocketServer::Session { +class MgmApiSession : public SocketServer::Session +{ + static void stop_session_if_not_connected(SocketServer::Session *_s, void *data); private: typedef Parser<MgmApiSession> Parser_t; @@ -84,6 +86,8 @@ public: void setParameter(Parser_t::Context &ctx, const class Properties &args); void listen_event(Parser_t::Context &ctx, const class Properties &args); + + void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args); void repCommand(Parser_t::Context &ctx, const class Properties &args); }; diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 6e3a0b280d1..f85456c8ea6 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -83,7 +83,6 @@ struct MgmGlobals { int g_no_nodeid_checks= 0; static MgmGlobals glob; - /****************************************************************************** * Function prototypes ******************************************************************************/ @@ -203,7 +202,7 @@ int main(int argc, char** argv) if (!readGlobalConfig()) goto error_end; - glob.mgmObject = new MgmtSrvr(glob.localNodeId, + glob.mgmObject = new MgmtSrvr(glob.localNodeId, glob.socketServer, BaseString(glob.config_filename), local_config, glob.cluster_config); diff --git a/ndb/src/ndbapi/Makefile_old b/ndb/src/ndbapi/Makefile_old deleted file mode 100644 index 54de9ba96f4..00000000000 --- a/ndb/src/ndbapi/Makefile_old +++ /dev/null @@ -1,60 +0,0 @@ -include .defs.mk - -TYPE := ndbapi - -PIC_ARCHIVE := Y -NONPIC_ARCHIVE := Y -ARCHIVE_TARGET := ndbapi - -A_LIB := Y -SO_LIB := Y -PIC_LIB := Y -LIB_TARGET := NDB_API - -LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) \ - transporter \ - general \ - signaldataprint \ - mgmapi mgmsrvcommon \ - portlib \ - logger \ - trace - -DIRS := signal-sender - -CFLAGS_TransporterFacade.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) -CFLAGS_ClusterMgr.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) - -# Source files of non-templated classes (.cpp files) -SOURCES = \ - TransporterFacade.cpp \ - ClusterMgr.cpp \ - Ndb.cpp \ - NdbPoolImpl.cpp NdbPool.cpp \ - Ndblist.cpp \ - Ndbif.cpp \ - Ndbinit.cpp \ - ndberror.c Ndberr.cpp NdbErrorOut.cpp \ - NdbConnection.cpp \ - NdbConnectionScan.cpp \ - NdbOperation.cpp \ - NdbOperationSearch.cpp \ - NdbOperationInt.cpp \ - NdbOperationDefine.cpp \ - NdbOperationExec.cpp \ - NdbResultSet.cpp \ - NdbScanOperation.cpp NdbScanFilter.cpp \ - NdbIndexOperation.cpp \ - NdbEventOperation.cpp \ - NdbEventOperationImpl.cpp \ - NdbApiSignal.cpp \ - NdbRecAttr.cpp \ - NdbUtil.cpp \ - NdbReceiver.cpp \ - NdbDictionary.cpp NdbDictionaryImpl.cpp DictCache.cpp - NdbBlob.cpp - -include $(NDB_TOP)/Epilogue.mk - -### -# Backward compatible diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index c8414ec16a3..09d15c7f962 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -343,6 +343,18 @@ NdbDictionary::Table::getColumn(const int attrId) const { return m_impl.getColumn(attrId); } +NdbDictionary::Column* +NdbDictionary::Table::getColumn(const char * name) +{ + return m_impl.getColumn(name); +} + +NdbDictionary::Column* +NdbDictionary::Table::getColumn(const int attrId) +{ + return m_impl.getColumn(attrId); +} + void NdbDictionary::Table::setLogging(bool val){ m_impl.m_logging = val; @@ -956,6 +968,10 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) out << " NOT NULL"; else out << " NULL"; + + if (col.getDistributionKey()) + out << " DISTRIBUTION KEY"; + return out; } diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 12f0946ab67..62d2a951f28 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -637,11 +637,9 @@ NdbDictionaryImpl::get_local_table_info(const char * internalTableName, return 0; } } - if (do_add_blob_tables && - info->m_table_impl->m_noOfBlobs && - addBlobTables(*(info->m_table_impl))) { - return 0; - } + if (do_add_blob_tables && info->m_table_impl->m_noOfBlobs) + addBlobTables(*(info->m_table_impl)); + return info; // autoincrement already initialized } diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index 13664794dcd..cccc3b6409f 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -192,7 +192,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) OperationType tOperationType = theOperationType; Uint32 tTupKeyLen = theTupKeyLen; Uint8 abortOption = - m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption; + m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption; tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator); tcKeyReq->setOperationType(tReqInfo, tOperationType); @@ -543,7 +543,7 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) }//if AbortOption ao = (AbortOption) - (m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption); + (m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption); theReceiver.m_received_result_length = ~0; theStatus = Finished; diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 86bac7deb16..373fec1a2b0 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -850,6 +850,14 @@ NdbScanOperation::doSendScan(int aProcessorId) tSignal = tSignal->next(); } theStatus = WaitResponse; + + m_sent_receivers_count = theParallelism; + if(m_ordered) + { + m_current_api_receiver = theParallelism; + m_api_receivers_count = theParallelism; + } + return tSignalCount; }//NdbOperation::doSendScan() @@ -1507,13 +1515,8 @@ NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){ m_api_receivers_count = 0; m_current_api_receiver = 0; - m_sent_receivers_count = parallell; + m_sent_receivers_count = 0; m_conf_receivers_count = 0; - - if(ordered){ - m_current_api_receiver = parallell; - m_api_receivers_count = parallell; - } } int diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 17a80082023..1a0d8132d71 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -124,7 +124,8 @@ ErrorBundle ErrorCodes[] = { { 217, TR, "217" }, { 218, TR, "218" }, { 219, TR, "219" }, - { 233, TR, "Out of operation records in transaction coordinator" }, + { 233, TR, + "Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)" }, { 275, TR, "275" }, { 279, TR, "Out of transaction markers in transaction coordinator" }, { 414, TR, "414" }, @@ -137,7 +138,7 @@ ErrorBundle ErrorCodes[] = { { 830, TR, "Out of add fragment operation records" }, { 873, TR, "Out of attrinfo records for scan in tuple manager" }, { 1217, TR, "1217" }, - { 1219, TR, "Out of operation records in local data manager" }, + { 1219, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, { 1220, TR, "1220" }, { 1222, TR, "Out of transaction markers in LQH" }, { 4021, TR, "Out of Send Buffer space in NDB API" }, @@ -149,9 +150,10 @@ ErrorBundle ErrorCodes[] = { */ { 623, IS, "623" }, { 624, IS, "624" }, - { 625, IS, "Out of memory in Ndb Kernel, index part" }, - { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes)" }, - { 827, IS, "Out of memory in Ndb Kernel, data part" }, + { 625, IS, "Out of memory in Ndb Kernel, index part (increase IndexMemory)" }, + { 800, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" }, + { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes or MaxNoOfTables)" }, + { 827, IS, "Out of memory in Ndb Kernel, data part (increase DataMemory)" }, { 832, IS, "832" }, /** @@ -168,10 +170,10 @@ ErrorBundle ErrorCodes[] = { * OverloadError */ { 410, OL, "Out of log file space temporarily" }, - { 677, OL, "Index UNDO buffers overloaded" }, - { 891, OL, "Data UNDO buffers overloaded" }, - { 1221, OL, "REDO log buffers overloaded" }, - { 4006, OL, "Connect failure - out of connection objects" }, + { 677, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" }, + { 891, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" }, + { 1221, OL, "REDO log buffers overloaded (increase RedoBuffer)" }, + { 4006, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" }, @@ -241,9 +243,9 @@ ErrorBundle ErrorCodes[] = { { 884, AE, "Stack overflow in interpreter" }, { 885, AE, "Stack underflow in interpreter" }, { 886, AE, "More than 65535 instructions executed in interpreter" }, - { 4256, AE, "Must call Ndb::init() before this function" }, + { 4256, AE, "Must call Ndb::init() before this function" }, { 880, AE, "Tried to read too much - too many getValue calls" }, - { 4257, AE, "Tried to read too much - too many getValue calls" }, + { 4257, AE, "Tried to read too much - too many getValue calls" }, /** * Scan application errors @@ -288,7 +290,7 @@ ErrorBundle ErrorCodes[] = { { 283, SE, "Table is being dropped" }, { 284, SE, "Table not defined in transaction coordinator" }, { 285, SE, "Unknown table error in transaction coordinator" }, - { 881, SE, "Unable to create table, out of data pages" }, + { 881, SE, "Unable to create table, out of data pages (increase DataMemory) " }, { 1225, SE, "Table not defined in local query handler" }, { 1226, SE, "Table is being dropped" }, { 1228, SE, "Cannot use drop table for drop index" }, @@ -344,17 +346,11 @@ ErrorBundle ErrorCodes[] = { { 4327, AE, "Distribution Group with 1 byte attribute is not allowed" }, { 4328, AE, "Disk memory attributes not yet supported" }, { 4329, AE, "Variable stored attributes not yet supported" }, - { 4330, AE, "Table names limited to 127 bytes" }, - { 4331, AE, "Attribute names limited to 31 bytes" }, - { 4332, AE, "Maximum 2000 attributes in a table" }, - { 4333, AE, "Maximum 4092 bytes long keys allowed" }, - { 4334, AE, "Attribute properties length limited to 127 bytes" }, { 4400, AE, "Status Error in NdbSchemaCon" }, { 4401, AE, "Only one schema operation per schema transaction" }, { 4402, AE, "No schema operation defined before calling execute" }, - { 4500, AE, "Cannot handle more than 2048 tables in NdbApi" }, { 4501, AE, "Insert in hash table failed when getting table information from Ndb" }, { 4502, AE, "GetValue not allowed in Update operation" }, { 4503, AE, "GetValue not allowed in Insert operation" }, diff --git a/ndb/src/mgmclient/CpcClient.hpp b/ndb/test/include/CpcClient.hpp index 1655bc57b56..1655bc57b56 100644 --- a/ndb/src/mgmclient/CpcClient.hpp +++ b/ndb/test/include/CpcClient.hpp diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp index b0b5fe15960..8b69faebde8 100644 --- a/ndb/test/include/NDBT_Test.hpp +++ b/ndb/test/include/NDBT_Test.hpp @@ -392,10 +392,10 @@ C##suitname():NDBT_TestSuite(#suitname){ \ // Add a number of equal steps to the testcase #define STEPS(stepfunc, num) \ - for (int i = 0; i < num; i++){ \ + { int i; for (i = 0; i < num; i++){ \ pts = new NDBT_ParallelStep(pt, #stepfunc, stepfunc); \ pt->addStep(pts);\ - } + } } #define VERIFIER(stepfunc) \ ptv = new NDBT_Verifier(pt, #stepfunc, stepfunc); \ diff --git a/ndb/test/ndbapi/Makefile_old b/ndb/test/ndbapi/Makefile_old deleted file mode 100644 index c3198096ec0..00000000000 --- a/ndb/test/ndbapi/Makefile_old +++ /dev/null @@ -1,49 +0,0 @@ -include .defs.mk - - -ifeq ($(NDB_OS), OSE) -DIRS = basic flexBench flexAsynch -else -DIRS = lmc-bench ronja -BIN_DIRS = \ - flexAsynch \ - flexBench \ - flexHammer \ - flexTT \ - create_tab \ - create_all_tabs \ - drop_all_tabs \ - bulk_copy \ - restarter2 restarter \ - restarts testScan testNdbApi \ - testScanInterpreter testIndex \ - testInterpreter \ - testOIBasic \ - testBackup \ - testBasic \ - basicAsynch \ - testNodeRestart \ - testOperations testTransactions \ - testSystemRestart \ - testTimeout \ - testMgm \ - testRestartGci \ - testDataBuffers \ - testDict \ - acid \ - telco \ - indexTest \ - test_event \ - indexTest2 \ - testGrep \ - testBlobs - -ifeq ($(NDB_OS), SOLARIS) -ifeq ($(NDB_COMPILER), FORTE6) - DIRS += flexTimedAsynch -endif -endif -endif - -include ${NDB_TOP}/Epilogue.mk - diff --git a/ndb/test/ndbapi/ScanFunctions.hpp b/ndb/test/ndbapi/ScanFunctions.hpp index 2ff4b751c33..6964f8c73a8 100644 --- a/ndb/test/ndbapi/ScanFunctions.hpp +++ b/ndb/test/ndbapi/ScanFunctions.hpp @@ -286,36 +286,36 @@ void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ attr = new Attrib; attr->numAttribs = 0; attriblist.push_back(attr); - - for(int i = 1; i < pTab->getNoOfColumns(); i++){ + int i; + for(i = 1; i < pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = i; for(int a = 0; a<i; a++) attr->attribs[a] = a; attriblist.push_back(attr); } - for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ + for(i = pTab->getNoOfColumns()-1; i > 0; i--){ attr = new Attrib; attr->numAttribs = i; for(int a = 0; a<i; a++) attr->attribs[a] = a; attriblist.push_back(attr); } - for(int i = pTab->getNoOfColumns(); i > 0; i--){ + for(i = pTab->getNoOfColumns(); i > 0; i--){ attr = new Attrib; attr->numAttribs = pTab->getNoOfColumns() - i; for(int a = 0; a<pTab->getNoOfColumns() - i; a++) attr->attribs[a] = pTab->getNoOfColumns()-a-1; attriblist.push_back(attr); } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ + for(i = 1; i < pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = pTab->getNoOfColumns() - i; for(int a = 0; a<pTab->getNoOfColumns() - i; a++) attr->attribs[a] = pTab->getNoOfColumns()-a-1; attriblist.push_back(attr); } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ + for(i = 1; i < pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = 2; for(int a = 0; a<2; a++){ @@ -345,11 +345,11 @@ void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ attriblist.push_back(attr); #if 1 - for(size_t i = 0; i < attriblist.size(); i++){ + for(size_t j = 0; j < attriblist.size(); j++){ - g_info << attriblist[i]->numAttribs << ": " ; - for(int a = 0; a < attriblist[i]->numAttribs; a++) - g_info << attriblist[i]->attribs[a] << ", "; + g_info << attriblist[j]->numAttribs << ": " ; + for(int a = 0; a < attriblist[j]->numAttribs; a++) + g_info << attriblist[j]->attribs[a] << ", "; g_info << endl; } #endif diff --git a/ndb/test/ndbapi/bank/Makefile_old b/ndb/test/ndbapi/bank/Makefile_old deleted file mode 100644 index f710f9e6612..00000000000 --- a/ndb/test/ndbapi/bank/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -DIRS = src bankCreator \ - bankSumAccounts \ - bankTransactionMaker \ - bankValidateAllGLs \ - bankMakeGL \ - bankTimer \ - testBank - - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old b/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old deleted file mode 100644 index bfff5cd161a..00000000000 --- a/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexBench - -# Source files of non-templated classes (.C files) -SOURCES = flexBench.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 04602f51d5f..03d52252334 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -123,15 +123,15 @@ chkerror(char const* fmt, ...) // alignment of addresses and data sizes -static bool isAligned(unsigned x) +static bool isAligned(UintPtr x) { return ((x & 3) == 0); } static bool isAligned(char* p) { - return isAligned(unsigned(p)); + return isAligned(UintPtr(p)); } -static unsigned toAligned(unsigned x) +static unsigned toAligned(UintPtr x) { while (! isAligned(x)) x++; @@ -223,10 +223,10 @@ testcase(int flag) noRandom = ! (flag & 8); ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl; - int smax = 0, stot = 0; + int smax = 0, stot = 0, i; if (xverbose) ndbout << "- define table " << tab << endl; - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; memset(&c, 0, sizeof(c)); sprintf(c.aAttrName, "C%d", i); @@ -266,7 +266,7 @@ testcase(int flag) return ndberror("getNdbSchemaOp"); if (top->createTable(tab) < 0) return ndberror("createTable"); - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (top->createAttribute( c.aAttrName, @@ -299,7 +299,7 @@ testcase(int flag) return ndberror("getNdbOperation key=%d", key); if (op->deleteTuple() < 0) return ndberror("deleteTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) @@ -329,7 +329,7 @@ testcase(int flag) return ndberror("getNdbOperation key=%d", key); if (op->insertTuple() < 0) return ndberror("insertTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) @@ -362,7 +362,7 @@ testcase(int flag) return ndberror("getNdbOperation key=%d", key); if (op->readTuple() < 0) return ndberror("readTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) @@ -371,7 +371,7 @@ testcase(int flag) if (xverbose) { char tmp[20]; if (useBuf) - sprintf(tmp, "0x%x", int(c.buf + off)); + sprintf(tmp, "0x%p", c.buf + off); else strcpy(tmp, "ndbapi"); ndbout << "--- column " << i << " addr=" << tmp << endl; @@ -388,23 +388,24 @@ testcase(int flag) } if (con->execute(Commit) != 0) return ndberror("execute key=%d", key); - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { } else if (useBuf) { - for (int j = 0; j < off; j++) { + int j; + for (j = 0; j < off; j++) { if (c.buf[j] != 'B') { return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'B', c.buf[j]); } } - for (int j = 0; j < c.aArraySize; j++) { + for (j = 0; j < c.aArraySize; j++) { if (c.buf[j + off] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), c.buf[j]); } } - for (int j = c.aArraySize + off; j < c.bufsiz; j++) { + for (j = c.aArraySize + off; j < c.bufsiz; j++) { if (c.buf[j] != 'B') { return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'B', c.buf[j]); @@ -431,7 +432,8 @@ testcase(int flag) if (xverbose) ndbout << "- scan" << endl; char found[MaxOper]; - for (int k = 0; k < opercnt; k++) + int k; + for (k = 0; k < opercnt; k++) found[k] = 0; for (key = 0; key < opercnt; key++) { int off = makeOff(key); @@ -459,7 +461,7 @@ testcase(int flag) if (op->interpret_exit_ok() < 0) return ndberror("interpret_exit_ok"); } - for (int i = 0; i < attrcnt; i++) { + for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->getValue(c.aAttrName, (char*)&newkey) < 0) @@ -468,7 +470,7 @@ testcase(int flag) if (xverbose) { char tmp[20]; if (useBuf) - sprintf(tmp, "0x%x", int(c.buf + off)); + sprintf(tmp, "0x%p", c.buf + off); else strcpy(tmp, "ndbapi"); ndbout << "--- column " << i << " addr=" << tmp << endl; @@ -489,22 +491,23 @@ testcase(int flag) while ((ret = rs->nextResult()) == 0) { if (key != newkey) return ndberror("unexpected key=%d newkey=%d", key, newkey); - for (int i = 1; i < attrcnt; i++) { + for (i = 1; i < attrcnt; i++) { col& c = ccol[i]; if (useBuf) { - for (int j = 0; j < off; j++) { + int j; + for (j = 0; j < off; j++) { if (c.buf[j] != 'C') { return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'C', c.buf[j]); } } - for (int j = 0; j < c.aArraySize; j++) { + for (j = 0; j < c.aArraySize; j++) { if (c.buf[j + off] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), c.buf[j]); } } - for (int j = c.aArraySize + off; j < c.bufsiz; j++) { + for (j = c.aArraySize + off; j < c.bufsiz; j++) { if (c.buf[j] != 'C') { return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'C', c.buf[j]); @@ -533,7 +536,7 @@ testcase(int flag) } con = 0; op = 0; - for (int k = 0; k < opercnt; k++) + for (k = 0; k < opercnt; k++) if (! found[k]) return ndberror("key %d not found", k); ndbout << "scanned " << key << endl; @@ -545,6 +548,7 @@ testcase(int flag) NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535) { + int i; ndb_init(); while (++argv, --argc > 0) { char const* p = argv[0]; @@ -602,7 +606,7 @@ NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuff } } unsigned ok = true; - for (int i = 1; 0 == loopcnt || i <= loopcnt; i++) { + for (i = 1; 0 == loopcnt || i <= loopcnt; i++) { ndbout << "=== loop " << i << " ===" << endl; for (int flag = 0; flag < (1<<testbits); flag++) { if (testcase(flag) < 0) { diff --git a/ndb/test/ndbapi/testDeadlock.cpp b/ndb/test/ndbapi/testDeadlock.cpp index 66fa48173cc..eb985e815ac 100644 --- a/ndb/test/ndbapi/testDeadlock.cpp +++ b/ndb/test/ndbapi/testDeadlock.cpp @@ -459,7 +459,8 @@ wl1822_main(char scantx) static const unsigned thrcount = 2; // create threads for tx1 and tx2 Thr* thrlist[2]; - for (int n = 0; n < thrcount; n++) { + int n; + for (n = 0; n < thrcount; n++) { Thr& thr = *(thrlist[n] = new Thr(1 + n)); CHK(thr.m_ret == 0); } @@ -472,7 +473,7 @@ wl1822_main(char scantx) if (runstep != 0) thr.start(runstep); } - for (int n = 0; n < thrcount; n++) { + for (n = 0; n < thrcount; n++) { Thr& thr = *thrlist[n]; Runstep runstep = wl1822_step[i][n]; if (runstep != 0) @@ -480,7 +481,7 @@ wl1822_main(char scantx) } } // delete threads - for (int n = 0; n < thrcount; n++) { + for (n = 0; n < thrcount; n++) { Thr& thr = *thrlist[n]; thr.exit(); thr.join(); diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 89232de2535..9552e321f00 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1431,11 +1431,12 @@ int runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ Vector<char*> cols; Vector<const NdbDictionary::Table*> tabs; + int i; Ndb* pNdb = GETNDB(step); const Uint32 count = NDBT_Tables::getNumTables(); - for (int i=0; i < count; i++){ + for (i=0; i < count; i++){ const NdbDictionary::Table * tab = NDBT_Tables::getTable(i); pNdb->getDictionary()->createTable(* tab); @@ -1458,7 +1459,7 @@ runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ Uint32 size = cols.size() / 2; char ** columns = &cols[0]; Uint64 start = NdbTick_CurrentMillisecond(); - for(int i = 0; i<times; i++){ + for(i = 0; i<times; i++){ int j = 2 * (rand() % size); const NdbDictionary::Table* tab = (const NdbDictionary::Table*)tcols[j]; const char * col = tcols[j+1]; diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index ed9e114fd92..6623ad35a7f 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -58,7 +58,9 @@ void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ // Build attrib definitions that describes which attributes to build index // Try to build strange combinations, not just "all" or all PK's - for(int i = 1; i <= pTab->getNoOfColumns(); i++){ + int i; + + for(i = 1; i <= pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = i; for(int a = 0; a<i; a++) @@ -66,7 +68,7 @@ void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ attriblist.push_back(attr); } int b = 0; - for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ + for(i = pTab->getNoOfColumns()-1; i > 0; i--){ attr = new Attrib; attr->numAttribs = i; b++; @@ -74,21 +76,21 @@ void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ attr->attribs[a] = a+b; attriblist.push_back(attr); } - for(int i = pTab->getNoOfColumns(); i > 0; i--){ + for(i = pTab->getNoOfColumns(); i > 0; i--){ attr = new Attrib; attr->numAttribs = pTab->getNoOfColumns() - i; for(int a = 0; a<pTab->getNoOfColumns() - i; a++) attr->attribs[a] = pTab->getNoOfColumns()-a-1; attriblist.push_back(attr); } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ + for(i = 1; i < pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = pTab->getNoOfColumns() - i; for(int a = 0; a<pTab->getNoOfColumns() - i; a++) attr->attribs[a] = pTab->getNoOfColumns()-a-1; attriblist.push_back(attr); } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ + for(i = 1; i < pTab->getNoOfColumns(); i++){ attr = new Attrib; attr->numAttribs = 2; for(int a = 0; a<2; a++){ @@ -226,8 +228,8 @@ int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){ while (l < loops && result == NDBT_OK){ - - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + unsigned int i; + for (i = 0; i < attrList.attriblist.size(); i++){ // Try to create index if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) @@ -235,7 +237,7 @@ int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){ } // Now drop all indexes that where created - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + for (i = 0; i < attrList.attriblist.size(); i++){ // Try to drop index if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK) @@ -1083,8 +1085,8 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ else pIdx.setType(NdbDictionary::Index::UniqueHashIndex); pIdx.setStoredIndex(logged); - - for (int c = 0; c< pTab->getNoOfColumns(); c++){ + int c; + for (c = 0; c< pTab->getNoOfColumns(); c++){ const NdbDictionary::Column * col = pTab->getColumn(c); if(col->getPrimaryKey()){ pIdx.addIndexColumn(col->getName()); @@ -1093,7 +1095,7 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ } int colId = -1; - for (int c = 0; c< pTab->getNoOfColumns(); c++){ + for (c = 0; c< pTab->getNoOfColumns(); c++){ const NdbDictionary::Column * col = pTab->getColumn(c); if(col->getNullable()){ pIdx.addIndexColumn(col->getName()); diff --git a/ndb/test/ndbapi/testLcp.cpp b/ndb/test/ndbapi/testLcp.cpp index c92be091a97..d11692db761 100644 --- a/ndb/test/ndbapi/testLcp.cpp +++ b/ndb/test/ndbapi/testLcp.cpp @@ -85,7 +85,8 @@ main(int argc, char ** argv){ g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished before SAVE_PAGES" << endl; require(!pause_lcp()); - for(size_t j = 0; j<g_rows; j++){ + size_t j; + for(j = 0; j<g_rows; j++){ require(!do_op(j)); } require(!continue_lcp(5900)); @@ -98,7 +99,7 @@ main(int argc, char ** argv){ << endl; require(!load_table()); require(!pause_lcp()); - for(size_t j = 0; j<g_rows; j++){ + for(j = 0; j<g_rows; j++){ require(!do_op(j)); } require(!continue_lcp(5901)); @@ -109,7 +110,7 @@ main(int argc, char ** argv){ g_info << "Testing pre LCP operations, undo-ed at commit" << endl; require(!load_table()); require(!pause_lcp()); - for(size_t j = 0; j<g_rows; j++){ + for(j = 0; j<g_rows; j++){ require(!do_op(j)); } require(!continue_lcp(5902)); diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 74cb1f8bcd0..a1ebac609b6 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -88,10 +88,10 @@ int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){ oldi = i; - for(size_t i = 0; i < ndbVector.size(); i++){ - delete ndbVector[i]; - if(((i+1) % 250) == 0){ - ndbout << "Deleted " << (Uint64) i << " ndb objects " << endl; + for(size_t j = 0; j < ndbVector.size(); j++){ + delete ndbVector[j]; + if(((j+1) % 250) == 0){ + ndbout << "Deleted " << (Uint64) j << " ndb objects " << endl; } } ndbVector.clear(); @@ -178,8 +178,8 @@ int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){ oldi = i; - for(size_t i = 0; i < conVector.size(); i++){ - pNdb->closeTransaction(conVector[i]); + for(size_t j = 0; j < conVector.size(); j++){ + pNdb->closeTransaction(conVector[j]); } conVector.clear(); l++; @@ -537,8 +537,8 @@ int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){ } // Delete the ndb objects - for(size_t i = 0; i < ndbVector.size(); i++) - delete ndbVector[i]; + for(size_t j = 0; j < ndbVector.size(); j++) + delete ndbVector[j]; ndbVector.clear(); l++; } diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 21862e02328..41f0686e63b 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -407,10 +407,11 @@ Col::verify(const void* addr) const const unsigned char* p = (const unsigned char*)addr; unsigned n = (p[0] << 8) | p[1]; assert(n <= m_length); - for (unsigned i = 0; i < n; i++) { + unsigned i; + for (i = 0; i < n; i++) { assert(p[2 + i] != 0); } - for (unsigned i = n; i < m_length; i++) { + for (i = n; i < m_length; i++) { assert(p[2 + i] == 0); } } @@ -3021,7 +3022,8 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode) { LL2(fname); const int threads = (mode & ST ? 1 : par.m_threads); - for (int n = 0; n < threads; n++) { + int n; + for (n = 0; n < threads; n++) { LL4("start " << n); Thr& thr = *g_thrlist[n]; thr.m_par.m_tab = par.m_tab; @@ -3033,7 +3035,7 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode) thr.start(); } unsigned errs = 0; - for (int n = threads - 1; n >= 0; n--) { + for (n = threads - 1; n >= 0; n--) { LL4("stop " << n); Thr& thr = *g_thrlist[n]; thr.stopped(); @@ -3301,10 +3303,11 @@ runtest(Par par) CHK(con.connect() == 0); par.m_con = &con; g_thrlist = new Thr* [par.m_threads]; - for (unsigned n = 0; n < par.m_threads; n++) { + unsigned n; + for (n = 0; n < par.m_threads; n++) { g_thrlist[n] = 0; } - for (unsigned n = 0; n < par.m_threads; n++) { + for (n = 0; n < par.m_threads; n++) { g_thrlist[n] = new Thr(par, n); Thr& thr = *g_thrlist[n]; assert(thr.m_thread != 0); @@ -3330,11 +3333,11 @@ runtest(Par par) } } } - for (unsigned n = 0; n < par.m_threads; n++) { + for (n = 0; n < par.m_threads; n++) { Thr& thr = *g_thrlist[n]; thr.exit(); } - for (unsigned n = 0; n < par.m_threads; n++) { + for (n = 0; n < par.m_threads; n++) { Thr& thr = *g_thrlist[n]; thr.join(); delete &thr; diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp index 8d0d78cbe8c..380a809ad00 100644 --- a/ndb/test/ndbapi/testReadPerf.cpp +++ b/ndb/test/ndbapi/testReadPerf.cpp @@ -99,7 +99,8 @@ main(int argc, const char** argv){ { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" } }; const int num_args = 1 + P_MAX; - for(int i = 0; i<P_MAX; i++){ + int i; + for(i = 0; i<P_MAX; i++){ args[i+1].long_name = g_paramters[i].name; args[i+1].short_name = * g_paramters[i].name; args[i+1].type = arg_integer; @@ -127,7 +128,7 @@ main(int argc, const char** argv){ g_err << "Wait until ready failed" << endl; goto error; } - for(int i = optind; i<argc; i++){ + for(i = optind; i<argc; i++){ const char * T = argv[i]; g_info << "Testing " << T << endl; BaseString::snprintf(g_table, sizeof(g_table), T); diff --git a/ndb/test/ndbapi/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci.cpp index e817245af55..4e541d1f38f 100644 --- a/ndb/test/ndbapi/testRestartGci.cpp +++ b/ndb/test/ndbapi/testRestartGci.cpp @@ -132,7 +132,8 @@ int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ // RULE1: The vector with saved records should have exactly as many // records with lower or same gci as there are in DB int recordsWithLowerOrSameGci = 0; - for (unsigned i = 0; i < savedRecords.size(); i++){ + unsigned i; + for (i = 0; i < savedRecords.size(); i++){ if (savedRecords[i].m_gci <= restartGCI) recordsWithLowerOrSameGci++; } @@ -144,7 +145,7 @@ int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ // RULE2: The records found in db should have same or lower // gci as in the vector - for (unsigned i = 0; i < savedRecords.size(); i++){ + for (i = 0; i < savedRecords.size(); i++){ CHECK(hugoOps.startTransaction(pNdb) == 0); CHECK(hugoOps.pkReadRecord(pNdb, i) == 0); if (hugoOps.execute_Commit(pNdb) != 0){ diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp index c1334125978..003fc67179f 100644 --- a/ndb/test/ndbapi/testScanPerf.cpp +++ b/ndb/test/ndbapi/testScanPerf.cpp @@ -80,7 +80,8 @@ main(int argc, const char** argv){ { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" } }; const int num_args = 1 + P_MAX; - for(int i = 0; i<P_MAX; i++){ + int i; + for(i = 0; i<P_MAX; i++){ args[i+1].long_name = g_paramters[i].name; args[i+1].short_name = * g_paramters[i].name; args[i+1].type = arg_integer; @@ -107,7 +108,7 @@ main(int argc, const char** argv){ g_err << "Wait until ready failed" << endl; goto error; } - for(int i = optind; i<argc; i++){ + for(i = optind; i<argc; i++){ const char * T = argv[i]; g_info << "Testing " << T << endl; BaseString::snprintf(g_tablename, sizeof(g_tablename), T); diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp index f8f2b84acc4..35016896495 100644 --- a/ndb/test/ndbapi/testSystemRestart.cpp +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -452,7 +452,7 @@ int runSystemRestart3(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); Uint32 currentRestartNodeIndex = 0; @@ -561,7 +561,7 @@ int runSystemRestart4(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); Uint32 currentRestartNodeIndex = 0; @@ -691,7 +691,7 @@ int runSystemRestart5(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); Uint32 currentRestartNodeIndex = 0; @@ -821,7 +821,7 @@ int runSystemRestart6(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); Uint32 currentRestartNodeIndex = 0; @@ -877,7 +877,7 @@ int runSystemRestart7(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); int a_nodeIds[64]; @@ -952,7 +952,7 @@ int runSystemRestart8(NDBT_Context* ctx, NDBT_Step* step){ } Vector<int> nodeIds; - for(Uint32 i = 0; i<nodeCount; i++) + for(i = 0; i<nodeCount; i++) nodeIds.push_back(restarter.getDbNodeId(i)); int a_nodeIds[64]; diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am index 1eac96e7ac7..c890536dcc6 100644 --- a/ndb/test/run-test/Makefile.am +++ b/ndb/test/run-test/Makefile.am @@ -11,9 +11,8 @@ test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \ atrt-clear-result.sh make-config.sh make-index.sh make-html-reports.sh atrt_SOURCES = main.cpp -INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include -I$(top_srcdir)/ndb/src/mgmclient -LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CpcClient.o \ - $(top_builddir)/ndb/test/src/libNDBT.a \ +INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include +LDADD_LOC = $(top_builddir)/ndb/test/src/libNDBT.a \ $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ diff --git a/ndb/test/run-test/Makefile_old b/ndb/test/run-test/Makefile_old deleted file mode 100644 index 6b4689b2dbb..00000000000 --- a/ndb/test/run-test/Makefile_old +++ /dev/null @@ -1,22 +0,0 @@ -include .defs.mk - -TYPE := util - -BIN_TARGET := atrt -BIN_TARGET_LIBS := mgmapi - -SOURCES = main.cpp -SCRIPTS = atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \ - atrt-clear-result.sh make-config.sh - -OBJECTS_LOC = $(call fixpath,$(NDB_TOP)/src/mgmclient/CpcClient.o) - -CFLAGS_main.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmclient) -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) - -include $(NDB_TOP)/Epilogue.mk - -_bins:: - -rm -f $(SCRIPTS:%=$(NDB_TOP)/bin/%) - cp $(SCRIPTS) $(NDB_TOP)/bin - diff --git a/ndb/src/mgmclient/CpcClient.cpp b/ndb/test/src/CpcClient.cpp index d407ba65312..d407ba65312 100644 --- a/ndb/src/mgmclient/CpcClient.cpp +++ b/ndb/test/src/CpcClient.cpp diff --git a/ndb/test/src/Makefile.am b/ndb/test/src/Makefile.am index a8f34a0ea22..56f3d6a1ec6 100644 --- a/ndb/test/src/Makefile.am +++ b/ndb/test/src/Makefile.am @@ -9,7 +9,8 @@ libNDBT_a_SOURCES = \ HugoAsynchTransactions.cpp UtilTransactions.cpp \ NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp \ NdbBackup.cpp NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp \ - NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c + NdbSchemaCon.cpp NdbSchemaOp.cpp getarg.c \ + CpcClient.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/src/common/mgmcommon -I$(top_srcdir)/ndb/include/mgmcommon -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/src/mgmapi diff --git a/ndb/test/src/Makefile_old b/ndb/test/src/Makefile_old deleted file mode 100644 index 2738ce1aba2..00000000000 --- a/ndb/test/src/Makefile_old +++ /dev/null @@ -1,33 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -ARCHIVE_TARGET := NDBT - -SOURCES = NDBT_ReturnCodes.cpp \ - NDBT_Error.cpp NDBT_Tables.cpp NDBT_ResultRow.cpp \ - NDBT_Test.cpp HugoCalculator.cpp \ - HugoOperations.cpp HugoTransactions.cpp \ - HugoAsynchTransactions.cpp UtilTransactions.cpp \ - NdbRestarter.cpp NdbRestarts.cpp NDBT_Output.cpp \ - NdbBackup.cpp NdbConfig.cpp NdbGrep.cpp NDBT_Table.cpp - -SOURCES.c = - -CFLAGS_NdbRestarter.cpp := -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) -CFLAGS_NdbConfig.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ - -I$(call fixpath,$(NDB_TOP)/src/mgmapi) -CFLAGS_NdbRestarts.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) -CFLAGS_NdbBackup.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ - -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ - -I$(call fixpath,$(NDB_TOP)/include/kernel) -CFLAGS_NdbGrep.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) - -include $(NDB_TOP)/Epilogue.mk - - - - - - - diff --git a/ndb/test/tools/Makefile.am b/ndb/test/tools/Makefile.am index 8d94c21b721..3255267b636 100644 --- a/ndb/test/tools/Makefile.am +++ b/ndb/test/tools/Makefile.am @@ -20,12 +20,10 @@ copy_tab_SOURCES = copy_tab.cpp create_index_SOURCES = create_index.cpp ndb_cpcc_SOURCES = cpcc.cpp -INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmclient - include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am -ndb_cpcc_LDADD = $(LDADD) $(top_builddir)/ndb/src/mgmclient/CpcClient.o +ndb_cpcc_LDADD = $(LDADD) # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/test/tools/Makefile_old b/ndb/test/tools/Makefile_old deleted file mode 100644 index b8e90ae207f..00000000000 --- a/ndb/test/tools/Makefile_old +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -DIRS := hugoCalculator hugoFill hugoLoad hugoLockRecords \ - hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate \ - hugoScanRead hugoScanUpdate restart waiter - -include $(NDB_TOP)/Epilogue.mk - -_bins_ndbapi : _libs_src diff --git a/ndb/test/tools/old_dirs/waiter/Makefile_old b/ndb/test/tools/old_dirs/waiter/Makefile_old deleted file mode 100644 index da2c9daff00..00000000000 --- a/ndb/test/tools/old_dirs/waiter/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := waiter - -# Source files of non-templated classes (.C files) -SOURCES = waiter.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index 64625f69ea2..fad9bf9ff84 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -1,5 +1,6 @@ ndbtools_PROGRAMS = \ + ndb_test_platform \ ndb_waiter \ ndb_drop_table \ ndb_delete_all \ @@ -11,6 +12,7 @@ ndbtools_PROGRAMS = \ tools_common_sources = ../test/src/NDBT_ReturnCodes.cpp ../test/src/NDBT_Table.cpp ../test/src/NDBT_Output.cpp +ndb_test_platform_SOURCES = ndb_test_platform.cpp ndb_waiter_SOURCES = waiter.cpp $(tools_common_sources) ndb_delete_all_SOURCES = delete_all.cpp $(tools_common_sources) ndb_desc_SOURCES = desc.cpp $(tools_common_sources) @@ -23,6 +25,7 @@ ndb_select_count_SOURCES = select_count.cpp $(tools_common_sources) include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapitools.mk.am +ndb_test_platform_LDFLAGS = @ndb_bin_am_ldflags@ ndb_waiter_LDFLAGS = @ndb_bin_am_ldflags@ ndb_drop_table_LDFLAGS = @ndb_bin_am_ldflags@ ndb_delete_all_LDFLAGS = @ndb_bin_am_ldflags@ diff --git a/ndb/tools/Makefile_old b/ndb/tools/Makefile_old deleted file mode 100644 index b9dc6883e18..00000000000 --- a/ndb/tools/Makefile_old +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -BIN_DIRS = select_all select_count desc list_tables \ - drop_tab delete_all copy_tab \ - create_index drop_index verify_index cpcc - -ifneq ($(NDB_ODBC),N) -BIN_DIRS += ndbsql -endif - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/tools/ndb_test_platform.cpp b/ndb/tools/ndb_test_platform.cpp new file mode 100644 index 00000000000..72dd146dacd --- /dev/null +++ b/ndb/tools/ndb_test_platform.cpp @@ -0,0 +1,95 @@ +/* Copyright (C) 2003 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + + +#include <ndb_global.h> +#include <my_sys.h> +#include <BaseString.hpp> + +/* + * Test BaseString::snprintf + */ + +static +int test_snprintf(const char * fmt, int buf_sz, int result) +{ + int ret; + char buf[100]; + ret = BaseString::snprintf(buf, buf_sz, fmt); + + if(ret < 0) + { + printf("BaseString::snprint returns %d with size=%d and strlen(fmt)=%d\n", + ret, buf_sz, strlen(fmt)); + return -1; + } + + if(ret+1 == buf_sz) + { + printf("BaseString::snprint truncates returns %d with size=%d and strlen(fmt)=%d\n", + ret, buf_sz, strlen(fmt)); + return -1; + } + + if(ret != result) + { + printf("BaseString::snprint returns incorrect value: returned=%d != expected=%d\n", + ret, result); + return -1; + } + + for(ret = 0; ret+1 < buf_sz && ret < result; ret++) + { + if(buf[ret] != fmt[ret]) + { + printf("BaseString::snprint Incorrect value in output buffer: " + "size=%d returned=expected=%d at pos=%d result=%d != expected=%d\n", + buf_sz, result, ret, buf[ret], fmt[ret]); + return -1; + } + } + return 0; +} + +int +main(void) +{ + /* + * Test BaseString::snprintf + */ + + if(test_snprintf("test", 1, 4)) + return -1; + + if(test_snprintf("test", 0, 4)) + return -1; + + if(test_snprintf("test", 100, 4)) + return -1; + + /* + * Test UintPtr + */ + + if (sizeof(UintPtr) != sizeof(Uint32*)) + { + printf("sizeof(UintPtr)=%d != sizeof(Uint32*)=%d\n", + sizeof(UintPtr), sizeof(Uint32*)); + return -1; + } + + return 0; +} diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index c9e76bb8ed3..be572d7c275 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -86,7 +86,7 @@ int main(int argc, char** argv){ if (_hostName == NULL){ LocalConfig lcfg; - if(!lcfg.init()) + if(!lcfg.init(opt_connect_str, 0)) { lcfg.printError(); lcfg.printUsage(); diff --git a/scripts/fill_help_tables.sh b/scripts/fill_help_tables.sh index cb5437f7178..78dfe7b6088 100644 --- a/scripts/fill_help_tables.sh +++ b/scripts/fill_help_tables.sh @@ -197,6 +197,10 @@ sub prepare_name $a =~ s/(\@node(.*?)\n)/ /g; $a =~ s/(\@tab)/\t/g; $a =~ s/\@item/ /g; + $a =~ s/\@minus\{\}/-/g; + $a =~ s/\@dots\{\}/.../g; + $a =~ s/\@var\{((.|\n)+?)\}/$1/go; + $a =~ s/\@command\{((.|\n)+?)\}/$1/go; $a =~ s/\@code\{((.|\n)+?)\}/$1/go; $a =~ s/\@strong\{(.+?)\}/$1/go; $a =~ s/\@samp\{(.+?)\}/$1/go; @@ -244,6 +248,10 @@ sub prepare_description $a =~ s/(\@item)/ /g; $a =~ s/(\@tindex\s(.*?)\n)//g; $a =~ s/(\@c\s(.*?)\n)//g; + $a =~ s/\@minus\{\}/-/g; + $a =~ s/\@dots\{\}/.../g; + $a =~ s/\@var\{((.|\n)+?)\}/$1/go; + $a =~ s/\@command\{((.|\n)+?)\}/$1/go; $a =~ s/\@code\{((.|\n)+?)\}/$1/go; $a =~ s/\@strong\{(.+?)\}/$1/go; $a =~ s/\@samp\{(.+?)\}/$1/go; @@ -273,6 +281,8 @@ sub prepare_example $a =~ s/(^\@c for_help_topic(.*?)\n)//g; + $a =~ s/\@var\{((.|\n)+?)\}/$1/go; + $a =~ s/\@dots\{\}/.../g; $a =~ s/\\/\\\\/g; $a =~ s/(\@{)/{/g; $a =~ s/(\@})/}/g; diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index b9e7ce21f79..da7e06f6c05 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -315,7 +315,7 @@ do break fi - if test @IS_LINUX@ -a $KILL_MYSQLD -eq 1 + if @IS_LINUX@ && test $KILL_MYSQLD -eq 1 then # Test if one process was hanging. # This is only a fix for Linux (running as base 3 mysqld processes) diff --git a/sql-common/my_time.c b/sql-common/my_time.c index dc997921f74..5afa6ea2857 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -723,6 +723,10 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) I couldn't come up with a better way to get a repeatable result :( We can't use mktime() as it's buggy on many platforms and not thread safe. + + Note: this code assumes that our time_t estimation is not too far away + from real value (we assume that localtime_r(tmp) will return something + within 24 hrs from t) which is probably true for all current time zones. */ tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) - (long) days_at_timestart)*86400L + (long) t->hour*3600L + @@ -735,7 +739,8 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) for (loop=0; loop < 2 && (t->hour != (uint) l_time->tm_hour || - t->minute != (uint) l_time->tm_min); + t->minute != (uint) l_time->tm_min || + t->second != (uint) l_time->tm_sec); loop++) { /* One check should be enough ? */ /* Get difference in days */ @@ -745,15 +750,22 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) + - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); current_timezone+= diff+3600; /* Compensate for -3600 above */ tmp+= (time_t) diff; localtime_r(&tmp,&tm_tmp); l_time=&tm_tmp; } /* - Fix that if we are in the not existing daylight saving time hour - we move the start of the next real hour + Fix that if we are in the non existing daylight saving time hour + we move the start of the next real hour. + + This code doesn't handle such exotical thing as time-gaps whose length + is more than one hour or non-integer (latter can theoretically happen + if one of seconds will be removed due leap correction, or because of + general time correction like it happened for Africa/Monrovia time zone + in year 1972). */ if (loop == 2 && t->hour != (uint) l_time->tm_hour) { @@ -763,7 +775,8 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+ - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); if (diff == 3600) tmp+=3600 - t->minute*60 - t->second; /* Move to next hour */ else if (diff == -3600) diff --git a/sql/field.cc b/sql/field.cc index 1275e1bbb8e..5332607c6d5 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4418,6 +4418,8 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), int Field_string::cmp(const char *a_ptr, const char *b_ptr) { + uint a_len, b_len; + if (field_charset->strxfrm_multiply > 1) { /* @@ -4429,10 +4431,19 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) (const uchar*) b_ptr, field_length); } - return my_strnncoll(field_charset,(const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, field_length); + if (field_charset->mbmaxlen != 1) + { + uint char_len= field_length/field_charset->mbmaxlen; + a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); + b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); + } + else + a_len= b_len= field_length; + return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len, + (const uchar*) b_ptr, b_len); } + void Field_string::sort_string(char *to,uint length) { uint tmp=my_strnxfrm(field_charset, @@ -5958,8 +5969,15 @@ Field *make_field(char *ptr, uint32 field_length, if (f_is_alpha(pack_flag)) { if (!f_is_packed(pack_flag)) - return new Field_string(ptr,field_length,null_pos,null_bit, - unireg_check, field_name, table, field_charset); + { + if (field_type == FIELD_TYPE_STRING || + field_type == FIELD_TYPE_DECIMAL || // 3.23 or 4.0 string + field_type == FIELD_TYPE_VAR_STRING) + return new Field_string(ptr,field_length,null_pos,null_bit, + unireg_check, field_name, table, + field_charset); + return 0; // Error + } uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 890687fc925..336408c5aa9 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -126,8 +126,7 @@ set_field_to_null(Field *field) return 0; } if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } @@ -185,8 +184,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) return 0; } if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } @@ -473,7 +471,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) { if (to->flags & BLOB_FLAG) { - if (!(from->flags & BLOB_FLAG)) + if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) return do_conv_blob; if (from_length != to_length || to->table->db_low_byte_first != from->table->db_low_byte_first) diff --git a/sql/filesort.cc b/sql/filesort.cc index 4ca8a2f418c..569ae3da357 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -284,7 +284,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, } } if (error) - my_error(ER_FILSORT_ABORT,MYF(ME_ERROR+ME_WAITTANG)); + my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT), + MYF(ME_ERROR+ME_WAITTANG)); else statistic_add(thd->status_var.filesort_rows, (ulong) records, &LOCK_status); @@ -707,7 +708,7 @@ static void make_sortkey(register SORTPARAM *param, } case REAL_RESULT: { - double value=item->val(); + double value= item->val_real(); if ((maybe_null=item->null_value)) { bzero((char*) to,sort_field->length+1); diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 3bb8383e488..1c8967c1a34 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -86,7 +86,7 @@ void ha_heap::set_keys_for_scanning(void) int ha_heap::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -96,7 +96,7 @@ int ha_heap::write_row(byte * buf) int ha_heap::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return heap_update(file,old_data,new_data); @@ -104,7 +104,7 @@ int ha_heap::update_row(const byte * old_data, byte * new_data) int ha_heap::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return heap_delete(file,buf); } @@ -112,7 +112,8 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error = heap_rkey(file,buf,active_index, key, key_len, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -121,7 +122,8 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len, int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error= heap_rkey(file, buf, active_index, key, key_len, HA_READ_PREFIX_LAST); table->status= error ? STATUS_NOT_FOUND : 0; @@ -131,7 +133,8 @@ int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len) int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error = heap_rkey(file, buf, index, key, key_len, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -140,7 +143,8 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, int ha_heap::index_next(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=heap_rnext(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -149,7 +153,8 @@ int ha_heap::index_next(byte * buf) int ha_heap::index_prev(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=heap_rprev(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -158,7 +163,7 @@ int ha_heap::index_prev(byte * buf) int ha_heap::index_first(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -168,7 +173,8 @@ int ha_heap::index_first(byte * buf) int ha_heap::index_last(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -181,7 +187,7 @@ int ha_heap::rnd_init(bool scan) int ha_heap::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=heap_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; @@ -192,7 +198,8 @@ int ha_heap::rnd_pos(byte * buf, byte *pos) { int error; HEAP_PTR position; - statistic_increment(current_thd->status_var.ha_read_rnd_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR)); error=heap_rrnd(file, buf, position); table->status=error ? STATUS_NOT_FOUND: 0; @@ -456,7 +463,7 @@ int ha_heap::create(const char *name, TABLE *table_arg, } } mem_per_row+= MY_ALIGN(table_arg->reclength + 1, sizeof(char*)); - max_rows = (ha_rows) (current_thd->variables.max_heap_table_size / + max_rows = (ha_rows) (table->in_use->variables.max_heap_table_size / mem_per_row); HP_CREATE_INFO hp_create_info; hp_create_info.auto_key= auto_key; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 370458c6e01..650cb86e253 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -495,9 +495,10 @@ innobase_mysql_tmpfile(void) if (fd2 < 0) { DBUG_PRINT("error",("Got error %d on dup",fd2)); my_errno=errno; - my_error(EE_OUT_OF_FILERESOURCES, - MYF(ME_BELL+ME_WAITTANG), filename, my_errno); - } + my_error(EE_OUT_OF_FILERESOURCES, + MYF(ME_BELL+ME_WAITTANG), + filename, my_errno); + } my_close(fd, MYF(MY_WME)); } return(fd2); @@ -4674,6 +4675,104 @@ ha_innobase::get_foreign_key_create_info(void) return(str); } + +int +ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) +{ + dict_foreign_t* foreign; + + DBUG_ENTER("get_foreign_key_list"); + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + ut_a(prebuilt != NULL); + update_thd(current_thd); + prebuilt->trx->op_info = (char*)"getting list of foreign keys"; + trx_search_latch_release_if_reserved(prebuilt->trx); + mutex_enter(&(dict_sys->mutex)); + foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); + + while (foreign != NULL) + { + uint i; + FOREIGN_KEY_INFO f_key_info; + LEX_STRING *name= 0; + const char *tmp_buff; + + tmp_buff= foreign->id; + i= 0; + while (tmp_buff[i] != '/') + i++; + tmp_buff+= i + 1; + f_key_info.forein_id= make_lex_string(thd, f_key_info.forein_id, + tmp_buff, strlen(tmp_buff), 1); + tmp_buff= foreign->referenced_table_name; + i= 0; + while (tmp_buff[i] != '/') + i++; + f_key_info.referenced_db= make_lex_string(thd, f_key_info.referenced_db, + tmp_buff, i, 1); + tmp_buff+= i + 1; + f_key_info.referenced_table= make_lex_string(thd, + f_key_info.referenced_table, + tmp_buff, strlen(tmp_buff), 1); + + for (i= 0;;) + { + tmp_buff= foreign->foreign_col_names[i]; + name= make_lex_string(thd, name, tmp_buff, strlen(tmp_buff), 1); + f_key_info.foreign_fields.push_back(name); + tmp_buff= foreign->referenced_col_names[i]; + name= make_lex_string(thd, name, tmp_buff, strlen(tmp_buff), 1); + f_key_info.referenced_fields.push_back(name); + if (++i >= foreign->n_fields) + break; + } + + ulong length= 0; + if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) + { + length=17; + tmp_buff= "ON DELETE CASCADE"; + } + else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) + { + length=18; + tmp_buff= "ON DELETE SET NULL"; + } + else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) + { + length=19; + tmp_buff= "ON DELETE NO ACTION"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) + { + length=17; + tmp_buff= "ON UPDATE CASCADE"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) + { + length=18; + tmp_buff= "ON UPDATE SET NULL"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) + { + length=19; + tmp_buff= "ON UPDATE NO ACTION"; + } + f_key_info.constraint_method= make_lex_string(thd, + f_key_info.constraint_method, + tmp_buff, length, 1); + + FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) + thd->memdup((gptr) &f_key_info, + sizeof(FOREIGN_KEY_INFO))); + f_key_list->push_back(pf_key_info); + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + } + mutex_exit(&(dict_sys->mutex)); + prebuilt->trx->op_info = (char*)""; + DBUG_RETURN(0); +} + /*********************************************************************** Checks if a table is referenced by a foreign key. The MySQL manual states that a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a @@ -5028,7 +5127,7 @@ ha_innobase::external_lock( Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB Monitor to the client. */ -int +bool innodb_show_status( /*===============*/ THD* thd) /* in: the MySQL query thread of the caller */ @@ -5042,7 +5141,7 @@ innodb_show_status( my_message(ER_NOT_SUPPORTED_YET, "Cannot call SHOW INNODB STATUS because skip-innodb is defined", MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } trx = check_trx_exists(thd); @@ -5071,7 +5170,7 @@ innodb_show_status( if (!(str = my_malloc(flen + 1, MYF(0)))) { mutex_exit_noninline(&srv_monitor_file_mutex); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } rewind(srv_monitor_file); @@ -5088,7 +5187,7 @@ innodb_show_status( my_free(str, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } protocol->prepare_for_resend(); @@ -5096,10 +5195,10 @@ innodb_show_status( my_free(str, MYF(0)); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /**************************************************************************** diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 7e337afed0e..5ec5c207456 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -162,6 +162,7 @@ class ha_innobase: public handler int check(THD* thd, HA_CHECK_OPT* check_opt); char* update_table_comment(const char* comment); char* get_foreign_key_create_info(); + int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list); uint referenced_by_foreign_key(); void free_foreign_key_create_info(char* str); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, @@ -233,7 +234,7 @@ int innobase_savepoint( my_off_t binlog_cache_pos); int innobase_close_connection(THD *thd); int innobase_drop_database(char *path); -int innodb_show_status(THD* thd); +bool innodb_show_status(THD* thd); my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, uint full_name_len); diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 903f9c46002..e1fd17f4399 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -69,7 +69,7 @@ uint ha_isam::min_record_length(uint options) const int ha_isam::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -79,7 +79,7 @@ int ha_isam::write_row(byte * buf) int ha_isam::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return !nisam_update(file,old_data,new_data) ? 0 : my_errno ? my_errno : -1; @@ -87,14 +87,15 @@ int ha_isam::update_row(const byte * old_data, byte * new_data) int ha_isam::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count, &LOCK_status); return !nisam_delete(file,buf) ? 0 : my_errno ? my_errno : -1; } int ha_isam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; @@ -103,7 +104,8 @@ int ha_isam::index_read(byte * buf, const byte * key, int ha_isam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; @@ -111,7 +113,8 @@ int ha_isam::index_read_idx(byte * buf, uint index, const byte * key, int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; @@ -120,7 +123,7 @@ int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len) int ha_isam::index_next(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_next_count, + statistic_increment(table->in_use->status_var.ha_read_next_count, &LOCK_status); int error=nisam_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -129,7 +132,7 @@ int ha_isam::index_next(byte * buf) int ha_isam::index_prev(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_prev_count, + statistic_increment(table->in_use->status_var.ha_read_prev_count, &LOCK_status); int error=nisam_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -138,7 +141,7 @@ int ha_isam::index_prev(byte * buf) int ha_isam::index_first(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=nisam_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -147,7 +150,7 @@ int ha_isam::index_first(byte * buf) int ha_isam::index_last(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_last_count, + statistic_increment(table->in_use->status_var.ha_read_last_count, &LOCK_status); int error=nisam_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -161,7 +164,7 @@ int ha_isam::rnd_init(bool scan) int ha_isam::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=nisam_rrnd(file, buf, NI_POS_ERROR); table->status=error ? STATUS_NOT_FOUND: 0; @@ -170,7 +173,7 @@ int ha_isam::rnd_next(byte *buf) int ha_isam::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_count, &LOCK_status); int error=nisam_rrnd(file, buf, (ulong) my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc index 3d28b7aa4e2..c63548ec5cf 100644 --- a/sql/ha_isammrg.cc +++ b/sql/ha_isammrg.cc @@ -77,7 +77,7 @@ int ha_isammrg::write_row(byte * buf) int ha_isammrg::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return !mrg_update(file,old_data,new_data) ? 0 : my_errno ? my_errno : -1; @@ -85,7 +85,7 @@ int ha_isammrg::update_row(const byte * old_data, byte * new_data) int ha_isammrg::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count, &LOCK_status); return !mrg_delete(file,buf) ? 0 : my_errno ? my_errno : -1; } @@ -128,7 +128,7 @@ int ha_isammrg::rnd_init(bool scan) int ha_isammrg::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=mrg_rrnd(file, buf, ~(mrg_off_t) 0); table->status=error ? STATUS_NOT_FOUND: 0; @@ -137,7 +137,8 @@ int ha_isammrg::rnd_next(byte *buf) int ha_isammrg::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=mrg_rrnd(file, buf, (ulong) my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 8ff67fe95ab..8b8824448ba 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -249,7 +249,7 @@ int ha_myisam::close(void) int ha_myisam::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) @@ -602,7 +602,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) local_testflag|= T_STATISTICS; param.testflag|= T_STATISTICS; // We get this for free statistics_done=1; - if (current_thd->variables.myisam_repair_threads>1) + if (thd->variables.myisam_repair_threads>1) { char buf[40]; /* TODO: respect myisam_repair_threads variable */ @@ -1084,7 +1084,7 @@ bool ha_myisam::is_crashed() const int ha_myisam::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return mi_update(file,old_data,new_data); @@ -1092,7 +1092,7 @@ int ha_myisam::update_row(const byte * old_data, byte * new_data) int ha_myisam::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return mi_delete(file,buf); } @@ -1100,7 +1100,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1109,7 +1110,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1118,7 +1120,8 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1127,7 +1130,8 @@ int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) int ha_myisam::index_next(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1136,7 +1140,8 @@ int ha_myisam::index_next(byte * buf) int ha_myisam::index_prev(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=mi_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1145,7 +1150,7 @@ int ha_myisam::index_prev(byte * buf) int ha_myisam::index_first(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=mi_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -1155,7 +1160,8 @@ int ha_myisam::index_first(byte * buf) int ha_myisam::index_last(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=mi_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1166,7 +1172,8 @@ int ha_myisam::index_next_same(byte * buf, uint length __attribute__((unused))) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext_same(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1182,7 +1189,7 @@ int ha_myisam::rnd_init(bool scan) int ha_myisam::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=mi_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; @@ -1196,7 +1203,8 @@ int ha_myisam::restart_rnd_next(byte *buf, byte *pos) int ha_myisam::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1606,7 +1614,7 @@ int ha_myisam::ft_read(byte * buf) if (!ft_handler) return -1; - thread_safe_increment(current_thd->status_var.ha_read_next_count, + thread_safe_increment(table->in_use->status_var.ha_read_next_count, &LOCK_status); // why ? error=ft_handler->please->read_next(ft_handler,(char*) buf); diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 3eadd94bb93..2574892b1fe 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -81,7 +81,7 @@ int ha_myisammrg::close(void) int ha_myisammrg::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -91,7 +91,7 @@ int ha_myisammrg::write_row(byte * buf) int ha_myisammrg::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return myrg_update(file,old_data,new_data); @@ -99,14 +99,15 @@ int ha_myisammrg::update_row(const byte * old_data, byte * new_data) int ha_myisammrg::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return myrg_delete(file,buf); } int ha_myisammrg::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -115,7 +116,8 @@ int ha_myisammrg::index_read(byte * buf, const byte * key, int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -123,7 +125,8 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; @@ -132,7 +135,8 @@ int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len) int ha_myisammrg::index_next(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=myrg_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -140,7 +144,8 @@ int ha_myisammrg::index_next(byte * buf) int ha_myisammrg::index_prev(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=myrg_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -148,7 +153,7 @@ int ha_myisammrg::index_prev(byte * buf) int ha_myisammrg::index_first(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=myrg_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -157,7 +162,8 @@ int ha_myisammrg::index_first(byte * buf) int ha_myisammrg::index_last(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=myrg_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -167,7 +173,8 @@ int ha_myisammrg::index_next_same(byte * buf, const byte *key __attribute__((unused)), uint length __attribute__((unused))) { - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=myrg_rnext_same(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -180,7 +187,7 @@ int ha_myisammrg::rnd_init(bool scan) int ha_myisammrg::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=myrg_rrnd(file, buf, HA_OFFSET_ERROR); table->status=error ? STATUS_NOT_FOUND: 0; @@ -189,7 +196,8 @@ int ha_myisammrg::rnd_next(byte *buf) int ha_myisammrg::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=myrg_rrnd(file, buf, my_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return error; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b2e115e9779..17aaaf20fa2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1290,7 +1290,6 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, Field *field= key_part->field; uint part_len= key_part->length; uint part_store_len= key_part->store_length; - bool part_nullable= (bool) key_part->null_bit; // Info about each key part struct part_st { bool part_last; @@ -1312,9 +1311,9 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, p.part_last= (tot_len + part_store_len >= key_tot_len[j]); p.key= keys[j]; p.part_ptr= &p.key->key[tot_len]; - p.part_null= (field->maybe_null() && *p.part_ptr); + p.part_null= key_part->null_bit && *p.part_ptr; p.bound_ptr= (const char *) - p.part_null ? 0 : part_nullable ? p.part_ptr + 1 : p.part_ptr; + p.part_null ? 0 : key_part->null_bit ? p.part_ptr + 1 : p.part_ptr; if (j == 0) { @@ -2325,7 +2324,7 @@ int ha_ndbcluster::index_last(byte *buf) DBUG_RETURN(0); } } - DBUG_RETURN(1); + DBUG_RETURN(res); } @@ -2788,7 +2787,7 @@ int ha_ndbcluster::reset() const char **ha_ndbcluster::bas_ext() const -{ static const char *ext[]= { ".ndb", NullS }; return ext; } +{ static const char *ext[]= { ha_ndb_ext, NullS }; return ext; } /* @@ -3322,7 +3321,7 @@ int ha_ndbcluster::create(const char *name, { NDBTAB tab; NDBCOL col; - uint pack_length, length, i; + uint pack_length, length, i, pk_length= 0; const void *data, *pack_data; const char **key_names= form->keynames.type_names; char name2[FN_HEADLEN]; @@ -3369,6 +3368,8 @@ int ha_ndbcluster::create(const char *name, if ((my_errno= create_ndb_column(col, field, info))) DBUG_RETURN(my_errno); tab.addColumn(col); + if(col.getPrimaryKey()) + pk_length += (field->pack_length() + 3) / 4; } // No primary key, create shadow key as 64 bit, auto increment @@ -3382,6 +3383,39 @@ int ha_ndbcluster::create(const char *name, col.setPrimaryKey(TRUE); col.setAutoIncrement(TRUE); tab.addColumn(col); + pk_length += 2; + } + + // Make sure that blob tables don't have to big part size + for (i= 0; i < form->fields; i++) + { + /** + * The extra +7 concists + * 2 - words from pk in blob table + * 5 - from extra words added by tup/dict?? + */ + switch (form->field[i]->real_type()) { + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + { + NdbDictionary::Column * col = tab.getColumn(i); + int size = pk_length + (col->getPartSize()+3)/4 + 7; + if(size > NDB_MAX_TUPLE_SIZE_IN_WORDS && + (pk_length+7) < NDB_MAX_TUPLE_SIZE_IN_WORDS) + { + size = NDB_MAX_TUPLE_SIZE_IN_WORDS - pk_length - 7; + col->setPartSize(4*size); + } + /** + * If size > NDB_MAX and pk_length+7 >= NDB_MAX + * then the table can't be created anyway, so skip + * changing part size, and have error later + */ + } + default: + break; + } } if ((my_errno= check_ndb_connection())) diff --git a/sql/handler.cc b/sql/handler.cc index bb5e980f7bf..12820a66cb9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -105,6 +105,9 @@ const char *tx_isolation_names[] = TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names, NULL}; +static TYPELIB known_extensions= {0,"known_exts", NULL, NULL}; +uint known_extensions_id= 0; + enum db_type ha_resolve_by_name(const char *name, uint namelen) { THD *thd= current_thd; @@ -514,7 +517,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if ((error=ndbcluster_commit(thd,trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_COMMIT, MYF(0)); + my_message(ER_ERROR_DURING_COMMIT, ER(ER_ERROR_DURING_COMMIT), + MYF(0)); error=1; } if (trans == &thd->transaction.all) @@ -577,13 +581,20 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) if (opt_using_transactions) { bool operation_done=0; + /* + As rollback can be 30 times slower than insert in InnoDB, and user may + not know there's rollback (if it's because of a dupl row), better warn. + */ + const char *save_proc_info= thd->proc_info; + thd->proc_info= "Rolling back"; #ifdef HAVE_NDBCLUSTER_DB if (trans->ndb_tid) { if ((error=ndbcluster_rollback(thd, trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_ROLLBACK, MYF(0)); + my_message(ER_ERROR_DURING_ROLLBACK, ER(ER_ERROR_DURING_ROLLBACK), + MYF(0)); error=1; } trans->ndb_tid = 0; @@ -648,6 +659,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); + thd->proc_info= save_proc_info; } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); @@ -760,6 +772,25 @@ int ha_savepoint(THD *thd, char *savepoint_name) DBUG_RETURN(error); } + +int ha_start_consistent_snapshot(THD *thd) +{ +#ifdef HAVE_INNOBASE_DB + if ((have_innodb == SHOW_OPTION_YES) && + !innobase_start_trx_and_assign_read_view(thd)) + return 0; +#endif + /* + Same idea as when one wants to CREATE TABLE in one engine which does not + exist: + */ + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, + "This MySQL server does not support any " + "consistent-read capable storage engine"); + return 0; +} + + bool ha_flush_logs() { bool result=0; @@ -1169,7 +1200,7 @@ void handler::print_error(int error, myf errflag) str.length(max_length-4); str.append("..."); } - my_error(ER_DUP_ENTRY,MYF(0),str.c_ptr(),key_nr+1); + my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1); DBUG_VOID_RETURN; } textno=ER_DUP_KEY; @@ -1191,7 +1222,7 @@ void handler::print_error(int error, myf errflag) textno=ER_CRASHED_ON_REPAIR; break; case HA_ERR_OUT_OF_MEM: - my_error(ER_OUT_OF_RESOURCES,errflag); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), errflag); DBUG_VOID_RETURN; case HA_ERR_WRONG_COMMAND: textno=ER_ILLEGAL_HA; @@ -1238,7 +1269,7 @@ void handler::print_error(int error, myf errflag) uint length=dirname_part(buff,table->path); buff[length-1]=0; db=buff+dirname_length(buff); - my_error(ER_NO_SUCH_TABLE,MYF(0),db,table->table_name); + my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->table_name); break; } default: @@ -1252,16 +1283,16 @@ void handler::print_error(int error, myf errflag) { const char* engine= table_type(); if (temporary) - my_error(ER_GET_TEMPORARY_ERRMSG,MYF(0),error,str.ptr(),engine); + my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine); else - my_error(ER_GET_ERRMSG,MYF(0),error,str.ptr(),engine); + my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine); } else my_error(ER_GET_ERRNO,errflag,error); DBUG_VOID_RETURN; } } - my_error(textno,errflag,table->table_name,error); + my_error(textno, errflag, table->table_name, error); DBUG_VOID_RETURN; } @@ -1383,7 +1414,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); + my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name,error); DBUG_RETURN(error != 0); } @@ -1755,3 +1786,65 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, error= ha_index_end(); return error; } + + +/* + Returns a list of all known extensions. + + SYNOPSIS + ha_known_exts() + + NOTES + No mutexes, worst case race is a minor surplus memory allocation + We have to recreate the extension map if mysqld is restarted (for example + within libmysqld) + + RETURN VALUE + pointer pointer to TYPELIB structure +*/ + +TYPELIB *ha_known_exts(void) +{ + if (!known_extensions.type_names || mysys_usage_id != known_extensions_id) + { + show_table_type_st *types; + List<char> found_exts; + List_iterator_fast<char> it(found_exts); + const char **ext, *old_ext; + + known_extensions_id= mysys_usage_id; + found_exts.push_back((char*) ".db"); + for (types= sys_table_types; types->type; types++) + { + if (*types->value == SHOW_OPTION_YES) + { + handler *file= get_new_handler(0,(enum db_type) types->db_type); + for (ext= file->bas_ext(); *ext; ext++) + { + while ((old_ext= it++)) + { + if (!strcmp(old_ext, *ext)) + break; + } + if (!old_ext) + found_exts.push_back((char *) *ext); + + it.rewind(); + } + delete file; + } + } + ext= (const char **) my_once_alloc(sizeof(char *)* + (found_exts.elements+1), + MYF(MY_WME | MY_FAE)); + + DBUG_ASSERT(ext); + known_extensions.count= found_exts.elements; + known_extensions.type_names= ext; + + while ((old_ext= it++)) + *ext++= old_ext; + *ext= 0; + } + return &known_extensions; +} diff --git a/sql/handler.h b/sql/handler.h index c408425ed60..31c6e2f902b 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -138,6 +138,8 @@ #define HA_CACHE_TBL_ASKTRANSACT 2 #define HA_CACHE_TBL_TRANSACT 4 +/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */ +#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1 enum db_type { @@ -221,6 +223,8 @@ typedef struct st_ha_create_information struct st_table; typedef struct st_table TABLE; +struct st_foreign_key_info; +typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef struct st_ha_check_opt { @@ -463,6 +467,8 @@ public: virtual char* get_foreign_key_create_info() { return(NULL);} /* gets foreign key create string from InnoDB */ /* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */ + virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) + { return 0; } virtual uint referenced_by_foreign_key() { return 0;} virtual void init_table_handle_for_HANDLER() { return; } /* prepare InnoDB for HANDLER */ @@ -590,5 +596,5 @@ int ha_discover(THD* thd, const char* dbname, const char* name, 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); - - +TYPELIB *ha_known_exts(void); +int ha_start_consistent_snapshot(THD *thd); diff --git a/sql/item.cc b/sql/item.cc index 9e28793493d..ea721eea831 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -26,6 +26,7 @@ #include "sql_acl.h" #include "sp_head.h" #include "sql_trigger.h" +#include "sql_select.h" static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, @@ -489,13 +490,13 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && derivation < dt.derivation && - dt.derivation == DERIVATION_COERCIBLE) + dt.derivation >= DERIVATION_COERCIBLE) { // Do nothing; } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && dt.derivation < derivation && - derivation == DERIVATION_COERCIBLE) + derivation >= DERIVATION_COERCIBLE) { set(dt); strong= nagg; @@ -710,7 +711,7 @@ String *Item_field::val_str(String *str) return field->val_str(str,&str_value); } -double Item_field::val() +double Item_field::val_real() { DBUG_ASSERT(fixed == 1); if ((null_value=field->is_null())) @@ -903,7 +904,7 @@ void Item_string::print(String *str) bool Item_null::eq(const Item *item, bool binary_cmp) const { return item->type() == type(); } -double Item_null::val() +double Item_null::val_real() { // following assert is redundant, because fixed=1 assigned in constructor DBUG_ASSERT(fixed == 1); @@ -1220,7 +1221,7 @@ bool Item_param::get_date(TIME *res, uint fuzzydate) } -double Item_param::val() +double Item_param::val_real() { switch (state) { case REAL_VALUE: @@ -1465,10 +1466,10 @@ bool Item::fix_fields(THD *thd, // We do not check fields which are fixed during construction DBUG_ASSERT(fixed == 0 || basic_const_item()); fixed= 1; - return 0; + return FALSE; } -double Item_ref_null_helper::val() +double Item_ref_null_helper::val_real() { DBUG_ASSERT(fixed == 1); double tmp= (*ref)->val_result(); @@ -1532,170 +1533,415 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, } -bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) + + +/* + Search a GROUP BY clause for a field with a certain name. + + SYNOPSIS + find_field_in_group_list() + find_item the item being searched for + group_list GROUP BY clause + + DESCRIPTION + Search the GROUP BY list for a column named as find_item. When searching + preference is given to columns that are qualified with the same table (and + database) name as the one being searched for. + + RETURN + - the found item on success + - NULL if find_item is not in group_list +*/ + +static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) +{ + const char *db_name; + const char *table_name; + const char *field_name; + ORDER *found_group= NULL; + int found_match_degree= 0; + Item_field *cur_field; + int cur_match_degree= 0; + + if (find_item->type() == Item::FIELD_ITEM || + find_item->type() == Item::REF_ITEM) + { + db_name= ((Item_ident*) find_item)->db_name; + table_name= ((Item_ident*) find_item)->table_name; + field_name= ((Item_ident*) find_item)->field_name; + } + else + return NULL; + + DBUG_ASSERT(field_name); + + for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next) + { + if ((*(cur_group->item))->type() == Item::FIELD_ITEM) + { + cur_field= (Item_field*) *cur_group->item; + cur_match_degree= 0; + + DBUG_ASSERT(cur_field->field_name); + + if (!my_strcasecmp(system_charset_info, + cur_field->field_name, field_name)) + ++cur_match_degree; + else + continue; + + if (cur_field->table_name && table_name) + { + /* If field_name is qualified by a table name. */ + if (strcmp(cur_field->table_name, table_name)) + /* Same field names, different tables. */ + return NULL; + + ++cur_match_degree; + if (cur_field->db_name && db_name) + { + /* If field_name is also qualified by a database name. */ + if (strcmp(cur_field->db_name, db_name)) + /* Same field names, different databases. */ + return NULL; + ++cur_match_degree; + } + } + + if (cur_match_degree > found_match_degree) + { + found_match_degree= cur_match_degree; + found_group= cur_group; + } + else if (found_group && (cur_match_degree == found_match_degree) && + ! (*(found_group->item))->eq(cur_field, 0)) + { + /* + If the current resolve candidate matches equally well as the current + best match, they must reference the same column, otherwise the field + is ambiguous. + */ + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find_item->full_name(), current_thd->where); + return NULL; + } + } + } + + if (found_group) + return found_group->item; + else + return NULL; +} + + +/* + Resolve a column reference in a sub-select. + + SYNOPSIS + resolve_ref_in_select_and_group() + thd current thread + ref column reference being resolved + select the sub-select that ref is resolved against + + DESCRIPTION + Resolve a column reference (usually inside a HAVING clause) against the + SELECT and GROUP BY clauses of the query described by 'select'. The name + resolution algorithm searches both the SELECT and GROUP BY clauses, and in + case of a name conflict prefers GROUP BY column names over SELECT names. If + both clauses contain different fields with the same names, a warning is + issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no + GROUP BY column is found, then a HAVING name is resolved as a possibly + derived SELECT column. + + NOTES + The resolution procedure is: + - Search for a column or derived column named col_ref_i [in table T_j] + in the SELECT clause of Q. + - Search for a column named col_ref_i [in table T_j] + in the GROUP BY clause of Q. + - If found different columns with the same name in GROUP BY and SELECT + - issue a warning and return the GROUP BY column, + - otherwise return the found SELECT column. + + + RETURN + NULL - there was an error, and the error was already reported + not_found_item - the item was not resolved, no error was reported + resolved item - if the item was resolved +*/ + +static Item** +resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) +{ + Item **group_by_ref= NULL; + Item **select_ref= NULL; + ORDER *group_list= (ORDER*) select->group_list.first; + bool ambiguous_fields= FALSE; + uint counter; + bool not_used; + + /* + Search for a column or derived column named as 'ref' in the SELECT + clause of the current select. + */ + if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()), &counter, + REPORT_EXCEPT_NOT_FOUND, ¬_used))) + return NULL; /* Some error occurred. */ + + /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ + if (select->having_fix_field && !ref->with_sum_func && group_list) + { + group_by_ref= find_field_in_group_list(ref, group_list); + + /* Check if the fields found in SELECT and GROUP BY are the same field. */ + if (group_by_ref && (select_ref != not_found_item) && + !((*group_by_ref)->eq(*select_ref, 0))) + { + ambiguous_fields= TRUE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR, + ER(ER_NON_UNIQ_ERROR), ref->full_name(), + current_thd->where); + + } + } + + if (select_ref != not_found_item || group_by_ref) + { + if (select_ref != not_found_item && !ambiguous_fields) + { + DBUG_ASSERT(*select_ref); + if (! (*select_ref)->fixed) + { + my_error(ER_ILLEGAL_REFERENCE, MYF(0), + ref->name, "forward reference in item list"); + return NULL; + } + return (select->ref_pointer_array + counter); + } + else if (group_by_ref) + return group_by_ref; + else + DBUG_ASSERT(FALSE); + } + else + return (Item**) not_found_item; +} + + +/* + Resolve the name of a column reference. + + SYNOPSIS + Item_field::fix_fields() + thd [in] current thread + tables [in] the tables in a FROM clause + reference [in/out] view column if this item was resolved to a view column + + DESCRIPTION + The method resolves the column reference represented by 'this' as a column + present in one of: FROM clause, SELECT clause, GROUP BY clause of a query + Q, or in outer queries that contain Q. + + NOTES + The name resolution algorithm used is (where [T_j] is an optional table + name that qualifies the column name): + + resolve_column_reference([T_j].col_ref_i) + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q; + + if such a column is NOT found AND // Lookup in outer queries. + there are outer queries + { + for each outer query Q_k beginning from the inner-most one + { + if - Q_k is not a group query AND + - Q_k is not inside an aggregate function + OR + - Q_(k-1) is not in a HAVING or SELECT clause of Q_k + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q_k; + } + + if such a column is not found + Search for a column or derived column named col_ref_i + [in table T_j] in the SELECT and GROUP clauses of Q_k. + } + } + } + + Notice that compared to Item_ref::fix_fields, here we first search the FROM + clause, and then we search the SELECT and GROUP BY clauses. + + RETURN + TRUE if error + FALSE on success +*/ + +bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); if (!field) // If field is not checked { - bool upward_lookup= 0; - Field *tmp= (Field *)not_found_field; - if ((tmp= find_field_in_tables(thd, this, tables, ref, 0, + bool upward_lookup= FALSE; + Field *from_field= (Field *)not_found_field; + if ((from_field= find_field_in_tables(thd, this, tables, reference, + IGNORE_EXCEPT_NON_UNIQUE, !any_privileges)) == not_found_field) { - /* - We can't find table field in table list of current select, - consequently we have to find it in outer subselect(s). - We can't join lists of outer & current select, because of scope - of view rules. For example if both tables (outer & current) have - field 'field' it is not mistake to refer to this field without - mention of table name, but if we join tables in one list it will - cause error ER_NON_UNIQ_ERROR in find_field_in_tables. - */ SELECT_LEX *last= 0; -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; -#endif TABLE_LIST *table_list; - Item **refer= (Item **)not_found_item; - uint counter; - bool not_used; - // Prevent using outer fields in subselects, that is not supported now - SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select; - if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) + Item **ref= (Item **) not_found_item; + SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select; + /* + If there is an outer select, and it is not a derived table (which do + not support the use of outer fields for now), try to resolve this + reference in the outer select(s). + + We treat each subselect as a separate namespace, so that different + subselects may contain columns with the same names. The subselects are + searched starting from the innermost. + */ + if (current_sel->master_unit()->first_select()->linkage != + DERIVED_TABLE_TYPE) { - SELECT_LEX_UNIT *prev_unit= cursel->master_unit(); - for (SELECT_LEX *sl= prev_unit->outer_select(); - sl; - sl= (prev_unit= sl->master_unit())->outer_select()) + SELECT_LEX_UNIT *prev_unit= current_sel->master_unit(); + SELECT_LEX *outer_sel= prev_unit->outer_select(); + for ( ; outer_sel ; + outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) { - upward_lookup= 1; - table_list= (last= sl)->get_table_list(); - if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) - { + last= outer_sel; + Item_subselect *prev_subselect_item= prev_unit->item; + upward_lookup= TRUE; + + /* Search in the tables of the FROM clause of the outer select. */ + table_list= outer_sel->get_table_list(); + if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) /* - it is primary INSERT st_select_lex => skip first table - resolving + It is a primary INSERT st_select_lex => do not resolve against the + first table. */ table_list= table_list->next_local; - } - Item_subselect *prev_subselect_item= prev_unit->item; enum_parsing_place place= prev_subselect_item->parsing_place; /* - check table fields only if subquery used somewhere out of HAVING - or outer SELECT do not use groupping (i.e. tables are accessable) + Check table fields only if the subquery is used somewhere out of + HAVING, or the outer SELECT does not use grouping (i.e. tables are + accessible). */ if ((place != IN_HAVING || - (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && - (tmp= find_field_in_tables(thd, this, - table_list, ref, - 0, 1)) != not_found_field) + (outer_sel->with_sum_func == 0 && + outer_sel->group_list.elements == 0)) && + (from_field= find_field_in_tables(thd, this, table_list, + reference, + IGNORE_EXCEPT_NON_UNIQUE, + TRUE)) != + not_found_field) { - if (tmp) + if (from_field) { - if (tmp != view_ref_found) + if (from_field != view_ref_found) { - prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; } else { prev_subselect_item->used_tables_cache|= - (*ref)->used_tables(); + (*reference)->used_tables(); prev_subselect_item->const_item_cache&= - (*ref)->const_item(); + (*reference)->const_item(); } } break; } - if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && - (refer= find_item_in_list(this, sl->item_list, &counter, - REPORT_EXCEPT_NOT_FOUND, - ¬_used)) != - (Item **) not_found_item) + + /* Search in the SELECT and GROUP lists of the outer select. */ + if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE) { - if (*refer && (*refer)->fixed) // Avoid crash in case of error - { - prev_subselect_item->used_tables_cache|= (*refer)->used_tables(); - prev_subselect_item->const_item_cache&= (*refer)->const_item(); - } - break; + if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ + if (ref != not_found_item) + { + DBUG_ASSERT(*ref && (*ref)->fixed); + prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); + prev_subselect_item->const_item_cache&= (*ref)->const_item(); + break; + } } // Reference is not found => depend from outer (or just error) prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; - if (sl->master_unit()->first_select()->linkage == + if (outer_sel->master_unit()->first_select()->linkage == DERIVED_TABLE_TYPE) break; // do not look over derived table } } - if (!tmp) - return -1; - if (!refer) - return 1; - if (tmp == not_found_field && refer == (Item **)not_found_item) + + DBUG_ASSERT(ref); + if (!from_field) + return TRUE; + if (ref == not_found_item && from_field == not_found_field) { if (upward_lookup) { - // We can't say exactly what absend table or field - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - full_name(), thd->where); + // We can't say exactly what absent table or field + my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where); } else { // Call to report error - find_field_in_tables(thd, this, tables, ref, 1, 1); + find_field_in_tables(thd, this, tables, reference, REPORT_ALL_ERRORS, + TRUE); } - return -1; + return TRUE; } - else if (refer != (Item **)not_found_item) + else if (ref != not_found_item) { - if (!(*refer)->fixed) - { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return -1; - } + /* Should have been checked in resolve_ref_in_select_and_group(). */ + DBUG_ASSERT(*ref && (*ref)->fixed); - Item_ref *rf= new Item_ref(last->ref_pointer_array + counter, - (char *)table_name, (char *)field_name); + Item_ref *rf= new Item_ref(ref, (char *)table_name, (char *)field_name); if (!rf) - return 1; - thd->change_item_tree(ref, rf); + return TRUE; + thd->change_item_tree(reference, rf); /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() */ - if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) - return 1; + if (rf->fix_fields(thd, tables, reference) || rf->check_cols(1)) + return TRUE; - mark_as_dependent(thd, last, cursel, rf); - return 0; + mark_as_dependent(thd, last, current_sel, rf); + return FALSE; } else { - mark_as_dependent(thd, last, cursel, this); + mark_as_dependent(thd, last, current_sel, this); if (last->having_fix_field) { Item_ref *rf; rf= new Item_ref((cached_table->db[0] ? cached_table->db : 0), (char*) cached_table->alias, (char*) field_name); if (!rf) - return 1; - thd->change_item_tree(ref, rf); + return TRUE; + thd->change_item_tree(reference, rf); /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() */ - return rf->fix_fields(thd, tables, ref) || rf->check_cols(1); + return rf->fix_fields(thd, tables, reference) || rf->check_cols(1); } } } - else if (!tmp) - return -1; + else if (!from_field) + return TRUE; /* if it is not expression from merged VIEW we will set this field. @@ -1709,8 +1955,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Also we suppose that view can't be changed during PS/SP life. */ - if (tmp != view_ref_found) - set_field(tmp); + if (from_field != view_ref_found) + set_field(from_field); } else if (thd->set_query_id && field->query_id != thd->query_id) { @@ -1738,22 +1984,18 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) db, tab, field_name) & VIEW_ANY_ACL))) { - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - field_name, - tab); - return 1; + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "ANY", thd->priv_user, thd->host_or_ip, + field_name, tab); + return TRUE; } } #endif fixed= 1; - return 0; + return FALSE; } + Item *Item_field::safe_charset_converter(CHARSET_INFO *tocs) { no_const_subst= 1; @@ -2134,7 +2376,7 @@ int Item::save_in_field(Field *field, bool no_conversions) } else if (result_type() == REAL_RESULT) { - double nr=val(); + double nr= val_real(); if (null_value) return set_field_to_null(field); field->set_notnull(); @@ -2204,8 +2446,7 @@ Item_real::Item_real(const char *str_arg, uint length) when we are in the parser */ DBUG_ASSERT(str_arg[length] == 0); - my_printf_error(ER_ILLEGAL_VALUE_FOR_TYPE, ER(ER_ILLEGAL_VALUE_FOR_TYPE), - MYF(0), "double", (char*) str_arg); + my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg); } presentation= name=(char*) str_arg; decimals=(uint8) nr_of_decimals(str_arg); @@ -2216,7 +2457,7 @@ Item_real::Item_real(const char *str_arg, uint length) int Item_real::save_in_field(Field *field, bool no_conversions) { - double nr=val(); + double nr= val_real(); if (null_value) return set_field_to_null(field); field->set_notnull(); @@ -2378,15 +2619,14 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_FLOAT: { float nr; - nr= (float) val(); + nr= (float) val_real(); if (!null_value) result= protocol->store(nr, decimals, buffer); break; } case MYSQL_TYPE_DOUBLE: { - double nr; - nr= val(); + double nr= val_real(); if (!null_value) result= protocol->store(nr, decimals, buffer); break; @@ -2428,207 +2668,240 @@ bool Item_field::send(Protocol *protocol, String *buffer) /* - This is used for HAVING clause - Find field in select list having the same name + Resolve the name of a reference to a column reference. + + SYNOPSIS + Item_ref::fix_fields() + thd [in] current thread + tables [in] the tables in a FROM clause + reference [in/out] view column if this item was resolved to a view column + + DESCRIPTION + The method resolves the column reference represented by 'this' as a column + present in one of: GROUP BY clause, SELECT clause, outer queries. It is + used typically for columns in the HAVING clause which are not under + aggregate functions. + + NOTES + The name resolution algorithm used is (where [T_j] is an optional table + name that qualifies the column name): + + resolve_extended([T_j].col_ref_i) + { + Search for a column or derived column named col_ref_i [in table T_j] + in the SELECT and GROUP clauses of Q. + + if such a column is NOT found AND // Lookup in outer queries. + there are outer queries + { + for each outer query Q_k beginning from the inner-most one + { + Search for a column or derived column named col_ref_i + [in table T_j] in the SELECT and GROUP clauses of Q_k. + + if such a column is not found AND + - Q_k is not a group query AND + - Q_k is not inside an aggregate function + OR + - Q_(k-1) is not in a HAVING or SELECT clause of Q_k + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q_k; + } + } + } + } + + This procedure treats GROUP BY and SELECT clauses as one namespace for + column references in HAVING. Notice that compared to + Item_field::fix_fields, here we first search the SELECT and GROUP BY + clauses, and then we search the FROM clause. + + RETURN + TRUE if error + FALSE on success */ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); - uint counter; - bool not_used; + SELECT_LEX *current_sel= thd->lex->current_select; + if (!ref) { - TABLE_LIST *table_list; - bool upward_lookup= 0; - SELECT_LEX_UNIT *prev_unit= thd->lex->current_select->master_unit(); - SELECT_LEX *sl= prev_unit->outer_select(); - /* - Finding only in current select will be performed for selects that have - not outer one and for derived tables (which not support using outer - fields for now) - */ - if ((ref= find_item_in_list(this, - *(thd->lex->current_select->get_item_list()), - &counter, - ((sl && - thd->lex->current_select->master_unit()-> - first_select()->linkage != - DERIVED_TABLE_TYPE) ? - REPORT_EXCEPT_NOT_FOUND : - REPORT_ALL_ERRORS), ¬_used)) == - (Item **)not_found_item) + SELECT_LEX_UNIT *prev_unit= current_sel->master_unit(); + SELECT_LEX *outer_sel= prev_unit->outer_select(); + ORDER *group_list= (ORDER*) current_sel->group_list.first; + bool ambiguous_fields= FALSE; + Item **group_by_ref= NULL; + + if (!(ref= resolve_ref_in_select_and_group(thd, this, current_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ + + if (ref == not_found_item) /* This reference was not resolved. */ { - Field *tmp= (Field*) not_found_field; - SELECT_LEX *last= 0; - upward_lookup= 1; /* - We can't find table field in select list of current select, - consequently we have to find it in outer subselect(s). - We can't join lists of outer & current select, because of scope - of view rules. For example if both tables (outer & current) have - field 'field' it is not mistake to refer to this field without - mention of table name, but if we join tables in one list it will - cause error ER_NON_UNIQ_ERROR in find_item_in_list. + If there is an outer select, and it is not a derived table (which do + not support the use of outer fields for now), try to resolve this + reference in the outer select(s). + + We treat each subselect as a separate namespace, so that different + subselects may contain columns with the same names. The subselects are + searched starting from the innermost. */ - for ( ; sl ; sl= (prev_unit= sl->master_unit())->outer_select()) + if (outer_sel && (current_sel->master_unit()->first_select()->linkage != + DERIVED_TABLE_TYPE)) { - last= sl; - Item_subselect *prev_subselect_item= prev_unit->item; - if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && - (ref= find_item_in_list(this, sl->item_list, - &counter, REPORT_EXCEPT_NOT_FOUND, - ¬_used)) != - (Item **)not_found_item) - { - if (*ref && (*ref)->fixed) // Avoid crash in case of error - { - prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); - prev_subselect_item->const_item_cache&= (*ref)->const_item(); - } - break; - } - table_list= sl->get_table_list(); - if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) - { - // it is primary INSERT st_select_lex => skip first table resolving - table_list= table_list->next_local; - } - enum_parsing_place place= prev_subselect_item->parsing_place; - /* - Check table fields only if subquery used somewhere out of HAVING - or SELECT list or outer SELECT do not use groupping (i.e. tables - are accessable) - */ - if ((place != IN_HAVING || - (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && - (tmp= find_field_in_tables(thd, this, - table_list, reference, - 0, 1)) != not_found_field) - { - if (tmp) + TABLE_LIST *table_list; + Field *from_field= (Field*) not_found_field; + SELECT_LEX *last= 0; + + for ( ; outer_sel ; + outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) + { + last= outer_sel; + Item_subselect *prev_subselect_item= prev_unit->item; + + /* Search in the SELECT and GROUP lists of the outer select. */ + if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE) { - if (tmp != view_ref_found) + if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ + if (ref != not_found_item) { - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; + DBUG_ASSERT(*ref && (*ref)->fixed); + prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); + prev_subselect_item->const_item_cache&= (*ref)->const_item(); + break; } - else + } + + /* Search in the tables of the FROM clause of the outer select. */ + table_list= outer_sel->get_table_list(); + if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) + /* + It is a primary INSERT st_select_lex => do not resolve against the + first table. + */ + table_list= table_list->next_local; + + enum_parsing_place place= prev_subselect_item->parsing_place; + /* + Check table fields only if the subquery is used somewhere out of + HAVING or the outer SELECT does not use grouping (i.e. tables are + accessible). + TODO: + Here we could first find the field anyway, and then test this + condition, so that we can give a better error message - + ER_WRONG_FIELD_WITH_GROUP, instead of the less informative + ER_BAD_FIELD_ERROR which we produce now. + */ + if ((place != IN_HAVING || + (!outer_sel->with_sum_func && + outer_sel->group_list.elements == 0))) + { + if ((from_field= find_field_in_tables(thd, this, table_list, + reference, + IGNORE_EXCEPT_NON_UNIQUE, + TRUE)) != + not_found_field) { - prev_subselect_item->used_tables_cache|= - (*reference)->used_tables(); - prev_subselect_item->const_item_cache&= - (*reference)->const_item(); + if (from_field != view_ref_found) + { + prev_subselect_item->used_tables_cache|= from_field->table->map; + prev_subselect_item->const_item_cache= 0; + } + else + { + prev_subselect_item->used_tables_cache|= + (*reference)->used_tables(); + prev_subselect_item->const_item_cache&= + (*reference)->const_item(); + } + break; } } - break; - } - // Reference is not found => depend from outer (or just error) - prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; - prev_subselect_item->const_item_cache= 0; + /* Reference is not found => depend on outer (or just error). */ + prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; + prev_subselect_item->const_item_cache= 0; - if (sl->master_unit()->first_select()->linkage == - DERIVED_TABLE_TYPE) - break; // do not look over derived table - } + if (outer_sel->master_unit()->first_select()->linkage == + DERIVED_TABLE_TYPE) + break; /* Do not consider derived tables. */ + } - if (!ref) - return 1; - if (!tmp) - return -1; - if (ref == (Item **)not_found_item && tmp == not_found_field) - { - if (upward_lookup) - { - // We can't say exactly what absend (table or field) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - full_name(), thd->where); - } - else - { - // Call to report error - find_item_in_list(this, - *(thd->lex->current_select->get_item_list()), - &counter, REPORT_ALL_ERRORS, ¬_used); - } - ref= 0; // Safety - return 1; - } - if (tmp != not_found_field) - { - /* - Set ref to 0 as we are replacing this item with the found item - and this will ensure we get an error if this item would be - used elsewhere - */ - ref= 0; // Safety - if (tmp != view_ref_found) - { - Item_field* fld; - if (!(fld= new Item_field(tmp))) - return 1; - thd->change_item_tree(reference, fld); - mark_as_dependent(thd, last, thd->lex->current_select, fld); - return 0; - } - /* - We can leave expression substituted from view for next PS/SP - rexecution (i.e. do not register this substitution for reverting - on cleupup() (register_item_tree_changing())), because this - subtree will be fix_field'ed during - setup_tables()->setup_ancestor() (i.e. before all other - expressions of query, and references on tables which do not - present in query will not make problems. - - Also we suppose that view can't be changed during PS/SP life. - */ - } - else - { - if (!(*ref)->fixed) + DBUG_ASSERT(ref); + if (!from_field) + return TRUE; + if (ref == not_found_item && from_field == not_found_field) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), + this->full_name(), current_thd->where); + ref= 0; // Safety + return TRUE; + } + if (from_field != not_found_field) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return -1; + /* + Set ref to 0 as we are replacing this item with the found item and + this will ensure we get an error if this item would be used + elsewhere + */ + ref= 0; // Safety + if (from_field != view_ref_found) + { + Item_field* fld; + if (!(fld= new Item_field(from_field))) + return TRUE; + thd->change_item_tree(reference, fld); + mark_as_dependent(thd, last, thd->lex->current_select, fld); + return FALSE; + } + /* + We can leave expression substituted from view for next PS/SP + re-execution (i.e. do not register this substitution for reverting + on cleanup() (register_item_tree_changing())), because this subtree + will be fix_field'ed during setup_tables()->setup_ancestor() + (i.e. before all other expressions of query, and references on + tables which do not present in query will not make problems. + + Also we suppose that view can't be changed during PS/SP life. + */ + } + else + { + /* Should be checked in resolve_ref_in_select_and_group(). */ + DBUG_ASSERT(*ref && (*ref)->fixed); + mark_as_dependent(thd, last, current_sel, this); } - mark_as_dependent(thd, last, thd->lex->current_select, - this); - ref= last->ref_pointer_array + counter; } - } - else if (!ref) - return 1; - else - { - if (!(*ref)->fixed) + else { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return -1; + /* The current reference cannot be resolved in this query. */ + my_error(ER_BAD_FIELD_ERROR,MYF(0), + this->full_name(), current_thd->where); + return TRUE; } - ref= thd->lex->current_select->ref_pointer_array + counter; } } /* - The following conditional is changed as to correctly identify - incorrect references in group functions or forward references - with sub-select's / derived tables, while it prevents this - check when Item_ref is created in an expression involving - summing function, which is to be placed in the user variable. + Check if this is an incorrect reference in a group function or forward + reference. Do not issue an error if this is an unnamed reference inside an + aggregate function. */ if (((*ref)->with_sum_func && name && (depended_from || - !(thd->lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && - thd->lex->current_select->having_fix_field))) || + !(current_sel->linkage != GLOBAL_OPTIONS_TYPE && + current_sel->having_fix_field))) || !(*ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - ((*ref)->with_sum_func? - "reference on group function": - "forward reference in item list")); - return 1; + my_error(ER_ILLEGAL_REFERENCE, MYF(0), + name, ((*ref)->with_sum_func? + "reference to group function": + "forward reference in item list")); + return TRUE; } max_length= (*ref)->max_length; maybe_null= (*ref)->maybe_null; @@ -2638,8 +2911,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) fixed= 1; if (ref && (*ref)->check_cols(1)) - return 1; - return 0; + return TRUE; + return FALSE; } @@ -2677,7 +2950,7 @@ double Item_ref::val_result() return 0.0; return result_field->val_real(); } - return val(); + return val_real(); } @@ -2743,34 +3016,33 @@ bool Item_default_value::fix_fields(THD *thd, if (!arg) { fixed= 1; - return 0; + return FALSE; } if (arg->fix_fields(thd, table_list, &arg)) - return 1; + return TRUE; if (arg->type() == REF_ITEM) { Item_ref *ref= (Item_ref *)arg; if (ref->ref[0]->type() != FIELD_ITEM) { - return 1; + return TRUE; } arg= ref->ref[0]; } field_arg= (Item_field *)arg; if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG) { - my_printf_error(ER_NO_DEFAULT_FOR_FIELD, ER(ER_NO_DEFAULT_FOR_FIELD), - MYF(0), field_arg->field->field_name); - return 1; + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name); + return TRUE; } if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of()))) - return 1; + return TRUE; memcpy(def_field, field_arg->field, field_arg->field->size_of()); def_field->move_field(def_field->table->default_values - def_field->table->record[0]); set_field(def_field); - return 0; + return FALSE; } void Item_default_value::print(String *str) @@ -2798,14 +3070,14 @@ bool Item_insert_value::fix_fields(THD *thd, { DBUG_ASSERT(fixed == 0); if (arg->fix_fields(thd, table_list, &arg)) - return 1; + return TRUE; if (arg->type() == REF_ITEM) { Item_ref *ref= (Item_ref *)arg; if (ref->ref[0]->type() != FIELD_ITEM) { - return 1; + return TRUE; } arg= ref->ref[0]; } @@ -2814,7 +3086,7 @@ bool Item_insert_value::fix_fields(THD *thd, { Field *def_field= (Field*) sql_alloc(field_arg->field->size_of()); if (!def_field) - return 1; + return TRUE; memcpy(def_field, field_arg->field, field_arg->field->size_of()); def_field->move_field(def_field->table->insert_values - def_field->table->record[0]); @@ -2827,7 +3099,7 @@ bool Item_insert_value::fix_fields(THD *thd, set_field(new Field_null(0, 0, Field::NONE, tmp_field->field_name, tmp_field->table, &my_charset_bin)); } - return 0; + return FALSE; } void Item_insert_value::print(String *str) @@ -2979,7 +3251,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) } else { // It must REAL_RESULT - double result=item->val(); + double result= item->val_real(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; new_item= (null_value ? (Item*) new Item_null(name) : (Item*) @@ -3014,7 +3286,7 @@ bool field_is_equal_to_item(Field *field,Item *item) } if (res_type == INT_RESULT) return 1; // Both where of type int - double result=item->val(); + double result= item->val_real(); if (item->null_value) return 1; return result == field->val_real(); @@ -3087,7 +3359,7 @@ void Item_cache_str::store(Item *item) } -double Item_cache_str::val() +double Item_cache_str::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -3318,10 +3590,10 @@ bool Item_type_holder::join_types(THD *thd, Item *item) if (item_type == STRING_RESULT && collation.aggregate(item->collation)) { my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), - old_cs, old_derivation, - item->collation.collation->name, - item->collation.derivation_name(), - "UNION"); + old_cs, old_derivation, + item->collation.collation->name, + item->collation.derivation_name(), + "UNION"); return 1; } @@ -3355,7 +3627,7 @@ uint32 Item_type_holder::real_length(Item *item) } } -double Item_type_holder::val() +double Item_type_holder::val_real() { DBUG_ASSERT(0); // should never be called return 0.0; diff --git a/sql/item.h b/sql/item.h index 93c396b95b0..9c036c28408 100644 --- a/sql/item.h +++ b/sql/item.h @@ -32,6 +32,7 @@ class Item_field; enum Derivation { + DERIVATION_IGNORABLE= 4, DERIVATION_COERCIBLE= 3, DERIVATION_IMPLICIT= 2, DERIVATION_NONE= 1, @@ -99,6 +100,7 @@ public: { switch(derivation) { + case DERIVATION_IGNORABLE: return "IGNORABLE"; case DERIVATION_COERCIBLE: return "COERCIBLE"; case DERIVATION_IMPLICIT: return "IMPLICIT"; case DERIVATION_EXPLICIT: return "EXPLICIT"; @@ -186,7 +188,7 @@ public: virtual enum_field_types field_type() const; virtual enum Type type() const =0; /* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */ - virtual double val()=0; + virtual double val_real()=0; virtual longlong val_int()=0; /* Return string representation of this item object. @@ -217,7 +219,7 @@ public: virtual Field *get_tmp_table_field() { return 0; } virtual Field *tmp_table_field(TABLE *t_arg) { return 0; } virtual const char *full_name() const { return name ? name : "???"; } - virtual double val_result() { return val(); } + virtual double val_result() { return val_real(); } virtual longlong val_int_result() { return val_int(); } virtual String *str_result(String* tmp) { return val_str(tmp); } /* bit map of tables used by item */ @@ -362,10 +364,10 @@ public: // the item in the frame enum Type type() const; - inline double val() + inline double val_real() { Item *it= this_item(); - double ret= it->val(); + double ret= it->val_real(); Item::null_value= it->null_value; return ret; } @@ -526,7 +528,7 @@ public: Item_field(Field *field); enum Type type() const { return FIELD_ITEM; } bool eq(const Item *item, bool binary_cmp) const; - double val(); + double val_real(); longlong val_int(); String *val_str(String*); double val_result(); @@ -577,10 +579,11 @@ public: max_length= 0; name= name_par ? name_par : (char*) "NULL"; fixed= 1; + collation.set(&my_charset_bin, DERIVATION_IGNORABLE); } enum Type type() const { return NULL_ITEM; } bool eq(const Item *item, bool binary_cmp) const; - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); int save_in_field(Field *field, bool no_conversions); @@ -669,7 +672,7 @@ public: enum Type type() const { return item_type; } enum_field_types field_type() const { return param_type; } - double val(); + double val_real(); longlong val_int(); String *val_str(String*); bool get_time(TIME *tm); @@ -726,7 +729,7 @@ public: enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } String *val_str(String*); int save_in_field(Field *field, bool no_conversions); bool basic_const_item() const { return 1; } @@ -755,7 +758,7 @@ public: Item_uint(const char *str_arg, uint length); Item_uint(uint32 i) :Item_int((longlong) i, 10) { unsigned_flag= 1; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); } String *val_str(String*); Item *new_item() { return new Item_uint(name,max_length); } @@ -784,7 +787,7 @@ public: int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - double val() { DBUG_ASSERT(fixed == 1); return value; } + double val_real() { DBUG_ASSERT(fixed == 1); return value; } longlong val_int() { DBUG_ASSERT(fixed == 1); @@ -855,7 +858,7 @@ public: fixed= 1; } enum Type type() const { return STRING_ITEM; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -945,7 +948,7 @@ class Item_varbinary :public Item public: Item_varbinary(const char *str,uint str_length); enum Type type() const { return VARBIN_ITEM; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); } longlong val_int(); bool basic_const_item() const { return 1; } @@ -997,7 +1000,7 @@ public: enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const { return ref && (*ref)->eq(item, binary_cmp); } - double val() + double val_real() { double tmp=(*ref)->val_result(); null_value=(*ref)->null_value; @@ -1062,7 +1065,7 @@ public: Item_ref_null_helper(Item_in_subselect* master, Item **item, const char *table_name_par, const char *field_name_par): Item_ref(item, table_name_par, field_name_par), owner(master) {} - double val(); + double val_real(); longlong val_int(); String* val_str(String* s); bool get_date(TIME *ltime, uint fuzzydate); @@ -1130,7 +1133,7 @@ public: enum Type type() const { return COPY_STR_ITEM; } enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return cached_field_type; } - double val() + double val_real() { int err; return (null_value ? 0.0 : @@ -1358,7 +1361,7 @@ public: Item_cache_int(): Item_cache() {} void store(Item *item); - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String* val_str(String *str) { @@ -1376,7 +1379,7 @@ public: Item_cache_real(): Item_cache() {} void store(Item *item); - double val() { DBUG_ASSERT(fixed == 1); return value; } + double val_real() { DBUG_ASSERT(fixed == 1); return value; } longlong val_int() { DBUG_ASSERT(fixed == 1); @@ -1398,7 +1401,7 @@ public: Item_cache_str(): Item_cache() { } void store(Item *item); - double val(); + double val_real(); longlong val_int(); String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; } enum Item_result result_type() const { return STRING_RESULT; } @@ -1430,7 +1433,7 @@ public: { illegal_method_call((const char*)"make_field"); }; - double val() + double val_real() { illegal_method_call((const char*)"val"); return 0; @@ -1481,7 +1484,7 @@ public: Item_result result_type () const { return item_type; } enum Type type() const { return TYPE_HOLDER; } - double val(); + double val_real(); longlong val_int(); String *val_str(String*); bool join_types(THD *thd, Item *); diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 1559cfe958e..66de26dba9a 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -70,7 +70,7 @@ Item_str_buff::~Item_str_buff() bool Item_real_buff::cmp(void) { - double nr=item->val(); + double nr= item->val_real(); if (null_value != item->null_value || nr != value) { null_value= item->null_value; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 905250ed96f..4a4485ba2da 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -53,10 +53,10 @@ static void agg_cmp_type(Item_result *type, Item **items, uint nitems) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); } @@ -104,7 +104,7 @@ Item_bool_func2* Le_creator::create(Item *a, Item *b) const longlong Item_func_not::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return !null_value && value == 0 ? 1 : 0; } @@ -116,7 +116,7 @@ longlong Item_func_not::val_int() longlong Item_func_not_all::val_int() { DBUG_ASSERT(fixed == 1); - double value= args[0]->val(); + double value= args[0]->val_real(); if (abort_on_null) { null_value= 0; @@ -384,10 +384,10 @@ int Arg_comparator::compare_e_binary_string() int Arg_comparator::compare_real() { - double val1= (*a)->val(); + double val1= (*a)->val_real(); if (!(*a)->null_value) { - double val2= (*b)->val(); + double val2= (*b)->val_real(); if (!(*b)->null_value) { owner->null_value= 0; @@ -402,8 +402,8 @@ int Arg_comparator::compare_real() int Arg_comparator::compare_e_real() { - double val1= (*a)->val(); - double val2= (*b)->val(); + double val1= (*a)->val_real(); + double val2= (*b)->val_real(); if ((*a)->null_value || (*b)->null_value) return test((*a)->null_value && (*b)->null_value); return test(val1 == val2); @@ -600,17 +600,17 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, { DBUG_ASSERT(fixed == 0); if (fix_left(thd, tables, ref)) - return 1; + return TRUE; if (args[0]->maybe_null) maybe_null=1; if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args+1)) - return 1; + return TRUE; Item_in_subselect * sub= (Item_in_subselect *)args[1]; if (args[0]->cols() != sub->engine->cols()) { my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols()); - return 1; + return TRUE; } if (args[1]->maybe_null) maybe_null=1; @@ -619,7 +619,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, not_null_tables_cache|= args[1]->not_null_tables(); const_item_cache&= args[1]->const_item(); fixed= 1; - return 0; + return FALSE; } @@ -754,7 +754,7 @@ void Item_func_interval::fix_length_and_dec() (intervals=(double*) sql_alloc(sizeof(double)*(row->cols()-1)))) { for (uint i=1 ; i < row->cols(); i++) - intervals[i-1]=row->el(i)->val(); + intervals[i-1]= row->el(i)->val_real(); } } maybe_null= 0; @@ -776,7 +776,7 @@ void Item_func_interval::fix_length_and_dec() longlong Item_func_interval::val_int() { DBUG_ASSERT(fixed == 1); - double value= row->el(0)->val(); + double value= row->el(0)->val_real(); uint i; if (row->el(0)->null_value) @@ -799,7 +799,7 @@ longlong Item_func_interval::val_int() for (i=1 ; i < row->cols() ; i++) { - if (row->el(i)->val() > value) + if (row->el(i)->val_real() > value) return i-1; } return i-1; @@ -873,7 +873,7 @@ longlong Item_func_between::val_int() } else if (cmp_type == INT_RESULT) { - longlong value=args[0]->val_int(),a,b; + longlong value=args[0]->val_int(), a, b; if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ a=args[1]->val_int(); @@ -893,11 +893,11 @@ longlong Item_func_between::val_int() } else { - double value=args[0]->val(),a,b; + double value= args[0]->val_real(),a,b; if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ - a=args[1]->val(); - b=args[2]->val(); + a= args[1]->val_real(); + b= args[2]->val_real(); if (!args[1]->null_value && !args[2]->null_value) return (value >= a && value <= b) ? 1 : 0; if (args[1]->null_value && args[2]->null_value) @@ -954,16 +954,16 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table) } double -Item_func_ifnull::val() +Item_func_ifnull::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if (!args[0]->null_value) { null_value=0; return value; } - value=args[1]->val(); + value= args[1]->val_real(); if ((null_value=args[1]->null_value)) return 0.0; return value; @@ -1042,11 +1042,11 @@ Item_func_if::fix_length_and_dec() double -Item_func_if::val() +Item_func_if::val_real() { DBUG_ASSERT(fixed == 1); Item *arg= args[0]->val_int() ? args[1] : args[2]; - double value=arg->val(); + double value= arg->val_real(); null_value=arg->null_value; return value; } @@ -1095,7 +1095,7 @@ Item_func_nullif::fix_length_and_dec() */ double -Item_func_nullif::val() +Item_func_nullif::val_real() { DBUG_ASSERT(fixed == 1); double value; @@ -1104,7 +1104,7 @@ Item_func_nullif::val() null_value=1; return 0.0; } - value=args[0]->val(); + value= args[0]->val_real(); null_value=args[0]->null_value; return value; } @@ -1179,7 +1179,7 @@ Item *Item_func_case::find_item(String *str) return else_expr_num != -1 ? args[else_expr_num] : 0; break; case REAL_RESULT: - first_expr_real= args[first_expr_num]->val(); + first_expr_real= args[first_expr_num]->val_real(); if (args[first_expr_num]->null_value) return else_expr_num != -1 ? args[else_expr_num] : 0; break; @@ -1212,7 +1212,7 @@ Item *Item_func_case::find_item(String *str) return args[i+1]; break; case REAL_RESULT: - if (args[i]->val()==first_expr_real && !args[i]->null_value) + if (args[i]->val_real() == first_expr_real && !args[i]->null_value) return args[i+1]; break; case ROW_RESULT: @@ -1264,7 +1264,7 @@ longlong Item_func_case::val_int() return res; } -double Item_func_case::val() +double Item_func_case::val_real() { DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; @@ -1277,7 +1277,7 @@ double Item_func_case::val() null_value=1; return 0; } - res=item->val(); + res= item->val_real(); null_value=item->null_value; return res; } @@ -1400,13 +1400,13 @@ longlong Item_func_coalesce::val_int() return 0; } -double Item_func_coalesce::val() +double Item_func_coalesce::val_real() { DBUG_ASSERT(fixed == 1); null_value=0; for (uint i=0 ; i < arg_count ; i++) { - double res=args[i]->val(); + double res= args[i]->val_real(); if (!args[i]->null_value) return res; } @@ -1559,12 +1559,12 @@ in_double::in_double(uint elements) void in_double::set(uint pos,Item *item) { - ((double*) base)[pos]=item->val(); + ((double*) base)[pos]= item->val_real(); } byte *in_double::get_value(Item *item) { - tmp= item->val(); + tmp= item->val_real(); if (item->null_value) return 0; /* purecov: inspected */ return (byte*) &tmp; @@ -1956,7 +1956,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) and_tables_cache= ~(table_map) 0; if (check_stack_overrun(thd, buff)) - return 1; // Fatal error flag is set! + return TRUE; // Fatal error flag is set! while ((item=li++)) { table_map tmp_table_map; @@ -1974,7 +1974,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if ((!item->fixed && item->fix_fields(thd, tables, li.ref())) || (item= *li.ref())->check_cols(1)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ used_tables_cache|= item->used_tables(); tmp_table_map= item->not_null_tables(); not_null_tables_cache|= tmp_table_map; @@ -1987,7 +1987,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) thd->lex->current_select->cond_count+= list.elements; fix_length_and_dec(); fixed= 1; - return 0; + return FALSE; } bool Item_cond::walk(Item_processor processor, byte *arg) @@ -2339,12 +2339,12 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) DBUG_ASSERT(fixed == 0); if (Item_bool_func2::fix_fields(thd, tlist, ref) || escape_item->fix_fields(thd, tlist, &escape_item)) - return 1; + return TRUE; if (!escape_item->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); - return 1; + return TRUE; } if (escape_item->const_item()) @@ -2362,7 +2362,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) { String* res2 = args[1]->val_str(&tmp_value2); if (!res2) - return 0; // Null argument + return FALSE; // Null argument const size_t len = res2->length(); const char* first = res2->ptr(); @@ -2395,7 +2395,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) } } } - return 0; + return FALSE; } #ifdef USE_REGEX @@ -2406,13 +2406,13 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) || args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; max_length= 1; decimals= 0; if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV)) - return 1; + return TRUE; used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); not_null_tables_cache= (args[0]->not_null_tables() | @@ -2426,7 +2426,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (args[1]->null_value) { // Will always return NULL maybe_null=1; - return 0; + return FALSE; } int error; if ((error=regcomp(&preg,res->c_ptr(), @@ -2436,8 +2436,8 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) cmp_collation.collation))) { (void) regerror(error,&preg,buff,sizeof(buff)); - my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); - return 1; + my_error(ER_REGEXP_ERROR, MYF(0), buff); + return TRUE; } regex_compiled=regex_is_const=1; maybe_null=args[0]->maybe_null; @@ -2445,7 +2445,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else maybe_null=1; fixed= 1; - return 0; + return FALSE; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index af2c385b296..02d5f6a1f7a 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -420,7 +420,7 @@ public: Item_func_ifnull(Item *a,Item *b) :Item_func(a,b), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -439,7 +439,7 @@ public: Item_func_if(Item *a,Item *b,Item *c) :Item_func(a,b,c), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -462,7 +462,7 @@ public: Item_func_nullif(Item *a,Item *b) :Item_bool_func2(a,b), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -481,7 +481,7 @@ public: Item_func_coalesce(List<Item> &list) :Item_func(list),cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -517,7 +517,7 @@ public: } set_arguments(list); } - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -674,11 +674,11 @@ class cmp_item_real :public cmp_item public: void store_value(Item *item) { - value= item->val(); + value= item->val_real(); } int cmp(Item *arg) { - return value != arg->val(); + return value != arg->val_real(); } int compare(cmp_item *c) { diff --git a/sql/item_func.cc b/sql/item_func.cc index 185d4f115ad..8d4ad54b511 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -45,10 +45,10 @@ bool check_reserved_words(LEX_STRING *name) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } static void my_coll_agg_error(DTCollation &c1, @@ -56,11 +56,11 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c3, const char *fname) { - my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - c3.collation->name,c3.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_3COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + c3.collation->name, c3.derivation_name(), + fname); } @@ -74,7 +74,7 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname) args[2]->collation, fname); else - my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); + my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), fname); } @@ -281,8 +281,8 @@ Item_func::Item_func(THD *thd, Item_func *item) item. RETURN VALUES - 0 ok - 1 Got error. Stored with my_error(). + FALSE ok + TRUE Got error. Stored with my_error(). */ bool @@ -298,7 +298,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) const_item_cache=1; if (check_stack_overrun(thd, buff)) - return 1; // Fatal error if flag is set! + return TRUE; // Fatal error if flag is set! if (arg_count) { // Print purify happy for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) @@ -310,7 +310,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) */ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || (*arg)->check_cols(allowed_arg_cols)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ item= *arg; if (item->maybe_null) maybe_null=1; @@ -322,10 +322,10 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } } fix_length_and_dec(); - if (thd->net.last_errno) // An error inside fix_length_and_dec occured - return 1; + if (thd->net.report_error) // An error inside fix_length_and_dec occured + return TRUE; fixed= 1; - return 0; + return FALSE; } bool Item_func::walk (Item_processor processor, byte *argument) @@ -516,7 +516,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) String *Item_real_func::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals, &my_charset_bin); @@ -539,7 +539,7 @@ String *Item_num_func::val_str(String *str) } else { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -616,7 +616,7 @@ String *Item_num_op::val_str(String *str) } else { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -643,10 +643,10 @@ void Item_func_unsigned::print(String *str) } -double Item_func_plus::val() +double Item_func_plus::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val()+args[1]->val(); + double value= args[0]->val_real() + args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; return value; @@ -662,7 +662,7 @@ longlong Item_func_plus::val_int() return 0; return value; } - return (longlong) Item_func_plus::val(); + return (longlong) Item_func_plus::val_real(); } @@ -680,10 +680,10 @@ void Item_func_minus::fix_length_and_dec() } -double Item_func_minus::val() +double Item_func_minus::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val() - args[1]->val(); + double value= args[0]->val_real() - args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; return value; @@ -699,14 +699,14 @@ longlong Item_func_minus::val_int() return 0; return value; } - return (longlong) Item_func_minus::val(); + return (longlong) Item_func_minus::val_real(); } -double Item_func_mul::val() +double Item_func_mul::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val()*args[1]->val(); + double value= args[0]->val_real() * args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; /* purecov: inspected */ return value; @@ -722,15 +722,15 @@ longlong Item_func_mul::val_int() return 0; /* purecov: inspected */ return value; } - return (longlong) Item_func_mul::val(); + return (longlong) Item_func_mul::val_real(); } -double Item_func_div::val() +double Item_func_div::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); - double val2=args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0.0; if (val2 == 0.0) @@ -758,7 +758,7 @@ longlong Item_func_div::val_int() } return value/val2; } - return (longlong) Item_func_div::val(); + return (longlong) Item_func_div::val_real(); } @@ -800,11 +800,11 @@ void Item_func_int_div::fix_length_and_dec() } -double Item_func_mod::val() +double Item_func_mod::val_real() { DBUG_ASSERT(fixed == 1); - double value= args[0]->val(); - double val2= args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0.0; /* purecov: inspected */ if (val2 == 0.0) @@ -836,10 +836,10 @@ void Item_func_mod::fix_length_and_dec() } -double Item_func_neg::val() +double Item_func_neg::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return -value; } @@ -879,10 +879,10 @@ void Item_func_neg::fix_length_and_dec() } -double Item_func_abs::val() +double Item_func_abs::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return fabs(value); } @@ -911,10 +911,10 @@ void Item_func_abs::fix_length_and_dec() /* Gateway to natural LOG function */ -double Item_func_ln::val() +double Item_func_ln::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; return log(value); @@ -925,15 +925,15 @@ double Item_func_ln::val() We have to check if all values are > zero and first one is not one as these are the cases then result is not a number. */ -double Item_func_log::val() +double Item_func_log::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; if (arg_count == 2) { - double value2= args[1]->val(); + double value2= args[1]->val_real(); if ((null_value=(args[1]->null_value || value2 <= 0.0 || value == 1.0))) return 0.0; return log(value2) / log(value); @@ -941,47 +941,47 @@ double Item_func_log::val() return log(value); } -double Item_func_log2::val() +double Item_func_log2::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; return log(value) / M_LN2; } -double Item_func_log10::val() +double Item_func_log10::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; /* purecov: inspected */ return log10(value); } -double Item_func_exp::val() +double Item_func_exp::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; /* purecov: inspected */ return exp(value); } -double Item_func_sqrt::val() +double Item_func_sqrt::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value < 0))) return 0.0; /* purecov: inspected */ return sqrt(value); } -double Item_func_pow::val() +double Item_func_pow::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); - double val2=args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value=(args[0]->null_value || args[1]->null_value))) return 0.0; /* purecov: inspected */ return pow(value,val2); @@ -989,35 +989,35 @@ double Item_func_pow::val() // Trigonometric functions -double Item_func_acos::val() +double Item_func_acos::val_real() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(acos(value)); } -double Item_func_asin::val() +double Item_func_asin::val_real() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(asin(value)); } -double Item_func_atan::val() +double Item_func_atan::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; if (arg_count == 2) { - double val2= args[1]->val(); + double val2= args[1]->val_real(); if ((null_value=args[1]->null_value)) return 0.0; return fix_result(atan2(value,val2)); @@ -1025,28 +1025,28 @@ double Item_func_atan::val() return fix_result(atan(value)); } -double Item_func_cos::val() +double Item_func_cos::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(cos(value)); } -double Item_func_sin::val() +double Item_func_sin::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(sin(value)); } -double Item_func_tan::val() +double Item_func_tan::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(tan(value)); @@ -1110,7 +1110,7 @@ void Item_func_integer::fix_length_and_dec() longlong Item_func_ceiling::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return (longlong) ceil(value); } @@ -1119,7 +1119,7 @@ longlong Item_func_floor::val_int() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #3051 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); null_value=args[0]->null_value; return (longlong) floor(value); } @@ -1138,10 +1138,10 @@ void Item_func_round::fix_length_and_dec() } } -double Item_func_round::val() +double Item_func_round::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); int dec=(int) args[1]->val_int(); uint abs_dec=abs(dec); double tmp; @@ -1224,7 +1224,7 @@ void Item_func_rand::update_used_tables() } -double Item_func_rand::val() +double Item_func_rand::val_real() { DBUG_ASSERT(fixed == 1); return my_rnd(rand); @@ -1233,16 +1233,16 @@ double Item_func_rand::val() longlong Item_func_sign::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return value < 0.0 ? -1 : (value > 0 ? 1 : 0); } -double Item_func_units::val() +double Item_func_units::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0; return value*mul+add; @@ -1288,7 +1288,7 @@ String *Item_func_min_max::val_str(String *str) } case REAL_RESULT: { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -1332,7 +1332,7 @@ String *Item_func_min_max::val_str(String *str) } -double Item_func_min_max::val() +double Item_func_min_max::val_real() { DBUG_ASSERT(fixed == 1); double value=0.0; @@ -1341,12 +1341,12 @@ double Item_func_min_max::val() { if (null_value) { - value=args[i]->val(); + value= args[i]->val_real(); null_value=args[i]->null_value; } else { - double tmp=args[i]->val(); + double tmp= args[i]->val_real(); if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0) value=tmp; } @@ -1502,10 +1502,10 @@ longlong Item_func_field::val_int() } else { - double val= args[0]->val(); + double val= args[0]->val_real(); for (uint i=1; i < arg_count ; i++) { - if (val == args[i]->val()) + if (val == args[i]->val_real()) return (longlong) (i); } } @@ -1708,15 +1708,14 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, DBUG_ENTER("Item_udf_func::fix_fields"); if (check_stack_overrun(thd, buff)) - DBUG_RETURN(1); // Fatal error flag is set! + DBUG_RETURN(TRUE); // Fatal error flag is set! udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1); if (!tmp_udf) { - my_printf_error(ER_CANT_FIND_UDF,ER(ER_CANT_FIND_UDF),MYF(0),u_d->name.str, - errno); - DBUG_RETURN(1); + my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno); + DBUG_RETURN(TRUE); } u_d=tmp_udf; args=arguments; @@ -1733,7 +1732,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, { free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } uint i; Item **arg,**arg_end; @@ -1746,7 +1745,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; if (item->check_cols(1)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* TODO: We should think about this. It is not always right way just to set an UDF result to return my_charset_bin @@ -1779,7 +1778,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, sizeof(long)))) { free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } func->fix_length_and_dec(); @@ -1818,7 +1817,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, } break; case Item::REAL_ITEM: - *((double*) to) = arguments[i]->val(); + *((double*) to)= arguments[i]->val_real(); if (!arguments[i]->null_value) { f_args.args[i]=to; @@ -1835,10 +1834,10 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, u_d->func_init; if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) { - my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name.str, thd->net.last_error); + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), + u_d->name.str, thd->net.last_error); free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } func->max_length=min(initid.max_length,MAX_BLOB_WIDTH); func->maybe_null=initid.maybe_null; @@ -1848,11 +1847,11 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, initialized=1; if (error) { - my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name.str, ER(ER_UNKNOWN_ERROR)); - DBUG_RETURN(1); + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), + u_d->name.str, ER(ER_UNKNOWN_ERROR)); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1885,7 +1884,7 @@ bool udf_handler::get_arguments() } break; case REAL_RESULT: - *((double*) to) = args[i]->val(); + *((double*) to)= args[i]->val_real(); if (!args[i]->null_value) { f_args.args[i]=to; @@ -1940,7 +1939,7 @@ String *udf_handler::val_str(String *str,String *save_str) -double Item_func_udf_float::val() +double Item_func_udf_float::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_float::val"); @@ -1953,7 +1952,7 @@ double Item_func_udf_float::val() String *Item_func_udf_float::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -2374,7 +2373,7 @@ longlong Item_func_benchmark::val_int() { switch (args[0]->result_type()) { case REAL_RESULT: - (void) args[0]->val(); + (void) args[0]->val_real(); break; case INT_RESULT: (void) args[0]->val_int(); @@ -2463,7 +2462,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */ if (Item_func::fix_fields(thd, tables, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) - return 1; + return TRUE; /* Remember the last query which updated it, this way a query can later know if this variable is a constant item in the query (it is if update_query_id @@ -2489,7 +2488,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, entry->collation.set(args[0]->collation); collation.set(entry->collation); cached_result_type= args[0]->result_type(); - return 0; + return FALSE; } @@ -2647,7 +2646,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, will be catched by thd->net.report_error check in sql_set_variables(). RETURN - 0 - OK. + FALSE OK. */ bool @@ -2658,7 +2657,7 @@ Item_func_set_user_var::check() switch (cached_result_type) { case REAL_RESULT: { - save_result.vreal= args[0]->val(); + save_result.vreal= args[0]->val_real(); break; } case INT_RESULT: @@ -2677,7 +2676,7 @@ Item_func_set_user_var::check() DBUG_ASSERT(0); break; } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -2739,7 +2738,7 @@ Item_func_set_user_var::update() } -double Item_func_set_user_var::val() +double Item_func_set_user_var::val_real() { DBUG_ASSERT(fixed == 1); check(); @@ -2795,7 +2794,7 @@ Item_func_get_user_var::val_str(String *str) } -double Item_func_get_user_var::val() +double Item_func_get_user_var::val_real() { DBUG_ASSERT(fixed == 1); if (!var_entry) @@ -3140,7 +3139,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) !args[0]->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); - return 1; + return TRUE; } const_item_cache=0; @@ -3163,7 +3162,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) if (key == NO_SUCH_KEY && !(flags & FT_BOOL)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); - return 1; + return TRUE; } table=((Item_field *)item)->field->table; table->fulltext_searched=1; @@ -3245,7 +3244,8 @@ err: key=NO_SUCH_KEY; return 0; } - my_error(ER_FT_MATCHING_KEY_NOT_FOUND,MYF(0)); + my_message(ER_FT_MATCHING_KEY_NOT_FOUND, + ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0)); return 1; } @@ -3266,7 +3266,7 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const } -double Item_func_match::val() +double Item_func_match::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_match::val"); @@ -3374,7 +3374,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, { if (!var->is_struct()) { - net_printf(thd, ER_VARIABLE_IS_NOT_STRUCT, base_name->str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); return 0; } } @@ -3539,8 +3539,7 @@ Item_func_sp::execute(Item **itp) m_sp= sp_find_function(thd, m_name); if (! m_sp) { - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); DBUG_RETURN(-1); } @@ -3574,8 +3573,7 @@ Item_func_sp::field_type() const DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); DBUG_RETURN(m_sp->m_returns); } - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); DBUG_RETURN(MYSQL_TYPE_STRING); } @@ -3591,8 +3589,7 @@ Item_func_sp::result_type() const { DBUG_RETURN(m_sp->result()); } - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); DBUG_RETURN(STRING_RESULT); } @@ -3605,8 +3602,7 @@ Item_func_sp::fix_length_and_dec() m_sp= sp_find_function(current_thd, m_name); if (! m_sp) { - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); } else { diff --git a/sql/item_func.h b/sql/item_func.h index 602b77ae956..03df78d721d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -165,7 +165,8 @@ public: Item_real_func(Item *a,Item *b) :Item_func(a,b) {} Item_real_func(List<Item> &list) :Item_func(list) {} String *val_str(String*str); - longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) val_real(); } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } }; @@ -179,10 +180,11 @@ public: Item_num_func(Item *a) :Item_func(a),hybrid_type(REAL_RESULT) {} Item_num_func(Item *a,Item *b) :Item_func(a,b),hybrid_type(REAL_RESULT) {} String *val_str(String*str); - longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) val_real(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); } - bool is_null() { (void) val(); return null_value; } + bool is_null() { (void) val_real(); return null_value; } }; @@ -197,7 +199,7 @@ class Item_num_op :public Item_func enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); } void find_num_type(void); - bool is_null() { (void) val(); return null_value; } + bool is_null() { (void) val_real(); return null_value; } }; @@ -210,7 +212,7 @@ public: Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; } Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; } Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() {} @@ -222,9 +224,9 @@ class Item_func_signed :public Item_int_func public: Item_func_signed(Item *a) :Item_int_func(a) {} const char *func_name() const { return "cast_as_signed"; } - double val() + double val_real() { - double tmp= args[0]->val(); + double tmp= args[0]->val_real(); null_value= args[0]->null_value; return tmp; } @@ -256,7 +258,7 @@ class Item_func_plus :public Item_num_op public: Item_func_plus(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "+"; } - double val(); + double val_real(); longlong val_int(); }; @@ -265,7 +267,7 @@ class Item_func_minus :public Item_num_op public: Item_func_minus(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "-"; } - double val(); + double val_real(); longlong val_int(); void fix_length_and_dec(); }; @@ -276,7 +278,7 @@ class Item_func_mul :public Item_num_op public: Item_func_mul(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "*"; } - double val(); + double val_real(); longlong val_int(); }; @@ -285,7 +287,7 @@ class Item_func_div :public Item_num_op { public: Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "/"; } void fix_length_and_dec(); @@ -297,7 +299,7 @@ class Item_func_int_div :public Item_num_op public: Item_func_int_div(Item *a,Item *b) :Item_num_op(a,b) { hybrid_type=INT_RESULT; } - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); const char *func_name() const { return "DIV"; } void fix_length_and_dec(); @@ -308,7 +310,7 @@ class Item_func_mod :public Item_num_op { public: Item_func_mod(Item *a,Item *b) :Item_num_op(a,b) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "%"; } void fix_length_and_dec(); @@ -319,7 +321,7 @@ class Item_func_neg :public Item_num_func { public: Item_func_neg(Item *a) :Item_num_func(a) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "-"; } void fix_length_and_dec(); @@ -331,7 +333,7 @@ class Item_func_abs :public Item_num_func public: Item_func_abs(Item *a) :Item_num_func(a) {} const char *func_name() const { return "abs"; } - double val(); + double val_real(); longlong val_int(); enum Item_result result_type () const { return args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT; } @@ -368,7 +370,7 @@ class Item_func_exp :public Item_dec_func { public: Item_func_exp(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "exp"; } }; @@ -377,7 +379,7 @@ class Item_func_ln :public Item_dec_func { public: Item_func_ln(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "ln"; } }; @@ -387,7 +389,7 @@ class Item_func_log :public Item_dec_func public: Item_func_log(Item *a) :Item_dec_func(a) {} Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "log"; } }; @@ -396,7 +398,7 @@ class Item_func_log2 :public Item_dec_func { public: Item_func_log2(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "log2"; } }; @@ -405,7 +407,7 @@ class Item_func_log10 :public Item_dec_func { public: Item_func_log10(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "log10"; } }; @@ -414,7 +416,7 @@ class Item_func_sqrt :public Item_dec_func { public: Item_func_sqrt(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "sqrt"; } }; @@ -423,7 +425,7 @@ class Item_func_pow :public Item_dec_func { public: Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "pow"; } }; @@ -432,7 +434,7 @@ class Item_func_acos :public Item_dec_func { public: Item_func_acos(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "acos"; } }; @@ -440,7 +442,7 @@ class Item_func_asin :public Item_dec_func { public: Item_func_asin(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "asin"; } }; @@ -449,7 +451,7 @@ class Item_func_atan :public Item_dec_func public: Item_func_atan(Item *a) :Item_dec_func(a) {} Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "atan"; } }; @@ -457,7 +459,7 @@ class Item_func_cos :public Item_dec_func { public: Item_func_cos(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "cos"; } }; @@ -465,7 +467,7 @@ class Item_func_sin :public Item_dec_func { public: Item_func_sin(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "sin"; } }; @@ -473,7 +475,7 @@ class Item_func_tan :public Item_dec_func { public: Item_func_tan(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "tan"; } }; @@ -511,7 +513,7 @@ public: Item_func_round(Item *a,Item *b,bool trunc_arg) :Item_real_func(a,b),truncate(trunc_arg) {} const char *func_name() const { return truncate ? "truncate" : "round"; } - double val(); + double val_real(); void fix_length_and_dec(); }; @@ -522,7 +524,7 @@ class Item_func_rand :public Item_real_func public: Item_func_rand(Item *a) :Item_real_func(a), rand(0) {} Item_func_rand() :Item_real_func() {} - double val(); + double val_real(); const char *func_name() const { return "rand"; } bool const_item() const { return 0; } void update_used_tables(); @@ -546,7 +548,7 @@ class Item_func_units :public Item_real_func public: Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg) :Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {} - double val(); + double val_real(); const char *func_name() const { return name; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } }; @@ -560,7 +562,7 @@ class Item_func_min_max :public Item_func public: Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -799,8 +801,11 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) Item_func_udf_float::val(); } - double val(); + { + DBUG_ASSERT(fixed == 1); + return (longlong) Item_func_udf_float::val_real(); + } + double val_real(); String *val_str(String *str); void fix_length_and_dec() { fix_num_length_and_dec(); } }; @@ -813,7 +818,7 @@ public: Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} longlong val_int(); - double val() { return (double) Item_func_udf_int::val_int(); } + double val_real() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { decimals=0; max_length=21; } @@ -827,7 +832,7 @@ public: Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} String *val_str(String *); - double val() + double val_real() { int err; String *res; res=val_str(&str_value); @@ -850,7 +855,7 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } }; @@ -870,7 +875,7 @@ public: Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - double val() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { maybe_null=1; max_length=0; } @@ -945,7 +950,7 @@ public: Item_func_set_user_var(LEX_STRING a,Item *b) :Item_func(b), cached_result_type(INT_RESULT), name(a) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); bool update_hash(void *ptr, uint length, enum Item_result type, @@ -971,7 +976,7 @@ public: Item_func(), name(a) {} enum Functype functype() const { return GUSERVAR_FUNC; } LEX_STRING get_name() { return name; } - double val(); + double val_real(); longlong val_int(); String *val_str(String* str); void fix_length_and_dec(); @@ -1044,8 +1049,8 @@ public: bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool eq(const Item *, bool binary_cmp) const; /* The following should be safe, even if we compare doubles */ - longlong val_int() { DBUG_ASSERT(fixed == 1); return val()!=0.0; } - double val(); + longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; } + double val_real(); void print(String *str); bool fix_index(); @@ -1134,10 +1139,10 @@ public: longlong val_int() { - return (longlong)Item_func_sp::val(); + return (longlong)Item_func_sp::val_real(); } - double val() + double val_real() { Item *it; double d; @@ -1147,7 +1152,7 @@ public: null_value= 1; return 0.0; } - d= it->val(); + d= it->val_real(); null_value= it->null_value; return d; } diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 7c3319bbfea..163260f6428 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -320,8 +320,8 @@ err: String *Item_func_point::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double x= args[0]->val(); - double y= args[1]->val(); + double x= args[0]->val_real(); + double y= args[1]->val_real(); if ((null_value= (args[0]->null_value || args[1]->null_value || @@ -628,7 +628,7 @@ longlong Item_func_numpoints::val_int() } -double Item_func_x::val() +double Item_func_x::val_real() { DBUG_ASSERT(fixed == 1); double res= 0.0; // In case of errors @@ -645,7 +645,7 @@ double Item_func_x::val() } -double Item_func_y::val() +double Item_func_y::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors @@ -662,7 +662,7 @@ double Item_func_y::val() } -double Item_func_area::val() +double Item_func_area::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors @@ -679,7 +679,7 @@ double Item_func_area::val() return res; } -double Item_func_glength::val() +double Item_func_glength::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 79e4f804a04..e19036cc982 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -263,7 +263,7 @@ class Item_func_x: public Item_real_func String value; public: Item_func_x(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "x"; } }; @@ -273,7 +273,7 @@ class Item_func_y: public Item_real_func String value; public: Item_func_y(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "y"; } }; @@ -316,7 +316,7 @@ class Item_func_area: public Item_real_func String value; public: Item_func_area(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "area"; } }; @@ -326,7 +326,7 @@ class Item_func_glength: public Item_real_func String value; public: Item_func_glength(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "glength"; } }; diff --git a/sql/item_row.cc b/sql/item_row.cc index 8a020861fef..0c7eae9d920 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -62,7 +62,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) { if ((*arg)->fix_fields(thd, tabl, arg)) - return 1; + return TRUE; // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; used_tables_cache |= item->used_tables(); @@ -81,7 +81,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) with_sum_func= with_sum_func || item->with_sum_func; } fixed= 1; - return 0; + return FALSE; } void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array, diff --git a/sql/item_row.h b/sql/item_row.h index ef5856dcdd3..64bd5cbbb44 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -41,7 +41,7 @@ public: { illegal_method_call((const char*)"make_field"); }; - double val() + double val_real() { illegal_method_call((const char*)"val"); return 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 889b00eb6a0..bf172e1744d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -42,10 +42,10 @@ String my_empty_string("",default_charset_info); static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } uint nr_of_decimals(const char *str) @@ -59,7 +59,7 @@ uint nr_of_decimals(const char *str) return 0; } -double Item_str_func::val() +double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -1629,7 +1629,7 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) String *Item_func_format::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr =args[0]->val(); + double nr= args[0]->val_real(); uint32 diff,length,str_length; uint dec; if ((null_value=args[0]->null_value)) @@ -1697,14 +1697,14 @@ void Item_func_elt::fix_length_and_dec() } -double Item_func_elt::val() +double Item_func_elt::val_real() { DBUG_ASSERT(fixed == 1); uint tmp; null_value=1; if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) return 0.0; - double result= args[tmp]->val(); + double result= args[tmp]->val_real(); null_value= args[tmp]->null_value; return result; } @@ -2226,8 +2226,8 @@ void Item_func_set_collation::fix_length_and_dec() if (!set_collation || !my_charset_same(args[0]->collation.collation,set_collation)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - colname,args[0]->collation.collation->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + colname, args[0]->collation.collation->csname); return; } collation.set(set_collation, DERIVATION_EXPLICIT); @@ -2574,9 +2574,12 @@ String* Item_func_inet_ntoa::val_str(String* str) This function is very useful when you want to generate SQL statements - RETURN VALUES + NOTE + QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes). + + RETURN VALUES str Quoted string - NULL Argument to QUOTE() was NULL or out of memory. + NULL Out of memory. */ #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7)) @@ -2601,7 +2604,12 @@ String *Item_func_quote::val_str(String *str) String *arg= args[0]->val_str(str); uint arg_length, new_length; if (!arg) // Null argument - goto null; + { + str->copy("NULL", 4, collation.collation); // Return the string 'NULL' + null_value= 0; + return str; + } + arg_length= arg->length(); new_length= arg_length+2; /* for beginning and ending ' signs */ diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index afc4b9da0a1..647cf022d79 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -32,7 +32,7 @@ public: Item_str_func(Item *a,Item *b,Item *c,Item *d, Item* e) :Item_func(a,b,c,d,e) {decimals=NOT_FIXED_DEC; } Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; } longlong val_int(); - double val(); + double val_real(); enum Item_result result_type () const { return STRING_RESULT; } void left_right_max_length(); }; @@ -377,7 +377,7 @@ class Item_func_elt :public Item_str_func { public: Item_func_elt(List<Item> &list) :Item_str_func(list) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); void fix_length_and_dec(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index f426f14a25f..f8c5c0aac90 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -66,7 +66,7 @@ void Item_subselect::init(st_select_lex *select_lex, parsing_place= unit->item->parsing_place; unit->item->engine= 0; unit->item= this; - engine->change_item(this, result); + engine->change_result(this, result); } else { @@ -133,13 +133,13 @@ Item_subselect::select_transformer(JOIN *join) bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) { char const *save_where= thd_param->where; - int res; + bool res; DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); if (check_stack_overrun(thd, (gptr)&res)) - return 1; + return TRUE; res= engine->prepare(); @@ -171,7 +171,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) if (engine->cols() > max_columns) { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); - return 1; + return TRUE; } fix_length_and_dec(); } @@ -441,13 +441,13 @@ void Item_singlerow_subselect::bring_value() exec(); } -double Item_singlerow_subselect::val() +double Item_singlerow_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { null_value= 0; - return value->val(); + return value->val_real(); } else { @@ -565,7 +565,7 @@ void Item_exists_subselect::fix_length_and_dec() max_columns= engine->cols(); } -double Item_exists_subselect::val() +double Item_exists_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (exec()) @@ -599,7 +599,7 @@ String *Item_exists_subselect::val_str(String *str) return str; } -double Item_in_subselect::val() +double Item_in_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (exec()) @@ -1504,12 +1504,12 @@ void subselect_indexsubquery_engine::print(String *str) res new select_result object RETURN - 0 OK - -1 error + FALSE OK + TRUE error */ -int subselect_single_select_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_single_select_engine::change_result(Item_subselect *si, + select_subselect *res) { item= si; result= res; @@ -1526,12 +1526,12 @@ int subselect_single_select_engine::change_item(Item_subselect *si, res new select_result object RETURN - 0 OK - -1 error + FALSE OK + TRUE error */ -int subselect_union_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_union_engine::change_result(Item_subselect *si, + select_subselect *res) { item= si; int rc= unit->change_result(res, result); @@ -1549,14 +1549,15 @@ int subselect_union_engine::change_item(Item_subselect *si, res new select_result object RETURN - -1 error + FALSE OK + TRUE error */ -int subselect_uniquesubquery_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_uniquesubquery_engine::change_result(Item_subselect *si, + select_subselect *res) { DBUG_ASSERT(0); - return -1; + return TRUE; } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 6efb9052115..d0ff3654e48 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -134,7 +134,7 @@ public: void reset(); trans_res select_transformer(JOIN *join); void store(uint i, Item* item); - double val(); + double val_real(); longlong val_int (); String *val_str (String *); enum Item_result result_type() const; @@ -179,7 +179,7 @@ public: enum Item_result result_type() const { return INT_RESULT;} longlong val_int(); - double val(); + double val_real(); String *val_str(String*); void fix_length_and_dec(); void print(String *str); @@ -224,7 +224,7 @@ public: Comp_creator *func); trans_res row_value_transformer(JOIN * join); longlong val_int(); - double val(); + double val_real(); String *val_str(String*); void top_level_item() { abort_on_null=1; } bool test_limit(st_select_lex_unit *unit); @@ -290,7 +290,7 @@ public: virtual table_map upper_select_const_tables()= 0; static table_map calc_const_tables(TABLE_LIST *); virtual void print(String *str)= 0; - virtual int change_item(Item_subselect *si, select_subselect *result)= 0; + virtual bool change_result(Item_subselect *si, select_subselect *result)= 0; virtual bool no_tables()= 0; }; @@ -315,7 +315,7 @@ public: void exclude(); table_map upper_select_const_tables(); void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); bool no_tables(); }; @@ -336,7 +336,7 @@ public: void exclude(); table_map upper_select_const_tables(); void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); bool no_tables(); }; @@ -366,7 +366,7 @@ public: void exclude(); table_map upper_select_const_tables() { return 0; } void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); bool no_tables(); }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 72c85e2dd40..cd98a3cc309 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -143,7 +143,7 @@ String * Item_sum_num::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -173,8 +173,9 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); + return TRUE; } thd->allow_sum_func=0; // No included group funcs decimals=0; @@ -182,7 +183,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) - return 1; + return TRUE; if (decimals < args[i]->decimals) decimals=args[i]->decimals; maybe_null |= args[i]->maybe_null; @@ -193,7 +194,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) fix_length_and_dec(); thd->allow_sum_func=1; // Allow group functions fixed= 1; - return 0; + return FALSE; } @@ -205,8 +206,9 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item *item= args[0]; if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); + return TRUE; } thd->allow_sum_func=0; // No included group funcs @@ -214,7 +216,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!item->fixed && item->fix_fields(thd, tables, args) || (item= args[0])->check_cols(1)) - return 1; + return TRUE; hybrid_type= item->result_type(); if (hybrid_type == INT_RESULT) @@ -245,7 +247,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else hybrid_field_type= Item::field_type(); fixed= 1; - return 0; + return FALSE; } @@ -267,14 +269,14 @@ void Item_sum_sum::clear() bool Item_sum_sum::add() { - sum+=args[0]->val(); + sum+= args[0]->val_real(); if (!args[0]->null_value) null_value= 0; return 0; } -double Item_sum_sum::val() +double Item_sum_sum::val_real() { DBUG_ASSERT(fixed == 1); return sum; @@ -359,8 +361,8 @@ void Item_sum_sum_distinct::clear() bool Item_sum_sum_distinct::add() { - /* args[0]->val() may reset args[0]->null_value */ - double val= args[0]->val(); + /* args[0]->val_real() may reset args[0]->null_value */ + double val= args[0]->val_real(); if (!args[0]->null_value) { DBUG_ASSERT(tree); @@ -383,7 +385,7 @@ static int sum_sum_distinct(void *element, element_count num_of_dups, C_MODE_END -double Item_sum_sum_distinct::val() +double Item_sum_sum_distinct::val_real() { /* We don't have a tree only if 'setup()' hasn't been called; @@ -456,7 +458,7 @@ void Item_sum_avg::clear() bool Item_sum_avg::add() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value) { sum+=nr; @@ -465,7 +467,7 @@ bool Item_sum_avg::add() return 0; } -double Item_sum_avg::val() +double Item_sum_avg::val_real() { DBUG_ASSERT(fixed == 1); if (!count) @@ -482,10 +484,10 @@ double Item_sum_avg::val() Standard deviation */ -double Item_sum_std::val() +double Item_sum_std::val_real() { DBUG_ASSERT(fixed == 1); - double tmp= Item_sum_variance::val(); + double tmp= Item_sum_variance::val_real(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -513,7 +515,7 @@ void Item_sum_variance::clear() bool Item_sum_variance::add() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value) { sum+=nr; @@ -523,7 +525,7 @@ bool Item_sum_variance::add() return 0; } -double Item_sum_variance::val() +double Item_sum_variance::val_real() { DBUG_ASSERT(fixed == 1); if (!count) @@ -540,7 +542,7 @@ double Item_sum_variance::val() void Item_sum_variance::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (args[0]->null_value) @@ -565,7 +567,7 @@ void Item_sum_variance::update_field() float8get(old_sqr, res+sizeof(double)); field_count=sint8korr(res+sizeof(double)*2); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -587,7 +589,7 @@ void Item_sum_hybrid::clear() null_value= 1; } -double Item_sum_hybrid::val() +double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -620,7 +622,7 @@ longlong Item_sum_hybrid::val_int() return 0; if (hybrid_type == INT_RESULT) return sum_int; - return (longlong) Item_sum_hybrid::val(); + return (longlong) Item_sum_hybrid::val_real(); } @@ -696,7 +698,7 @@ bool Item_sum_min::add() break; case REAL_RESULT: { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value && (null_value || nr < sum)) { sum=nr; @@ -749,7 +751,7 @@ bool Item_sum_max::add() break; case REAL_RESULT: { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value && (null_value || nr > sum)) { sum=nr; @@ -829,7 +831,7 @@ bool Item_sum_and::add() void Item_sum_num::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (maybe_null) @@ -883,7 +885,7 @@ void Item_sum_hybrid::reset_field() } else // REAL_RESULT { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (maybe_null) { @@ -902,7 +904,7 @@ void Item_sum_hybrid::reset_field() void Item_sum_sum::reset_field() { - double nr=args[0]->val(); // Nulls also return 0 + double nr= args[0]->val_real(); // Nulls also return 0 float8store(result_field->ptr,nr); if (args[0]->null_value) result_field->set_null(); @@ -930,7 +932,7 @@ void Item_sum_count::reset_field() void Item_sum_avg::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (args[0]->null_value) @@ -968,7 +970,7 @@ void Item_sum_sum::update_field() char *res=result_field->ptr; float8get(old_nr,res); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -1005,7 +1007,7 @@ void Item_sum_avg::update_field() float8get(old_nr,res); field_count=sint8korr(res+sizeof(double)); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -1051,7 +1053,7 @@ Item_sum_hybrid::min_max_update_real_field() double nr,old_nr; old_nr=result_field->val_real(); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { if (result_field->is_null(0) || @@ -1103,7 +1105,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item) } -double Item_avg_field::val() +double Item_avg_field::val_real() { // fix_fields() never calls for this Item double nr; @@ -1124,7 +1126,7 @@ double Item_avg_field::val() String *Item_avg_field::val_str(String *str) { // fix_fields() never calls for this Item - double nr=Item_avg_field::val(); + double nr= Item_avg_field::val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -1136,10 +1138,10 @@ Item_std_field::Item_std_field(Item_sum_std *item) { } -double Item_std_field::val() +double Item_std_field::val_real() { // fix_fields() never calls for this Item - double tmp= Item_variance_field::val(); + double tmp= Item_variance_field::val_real(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -1152,7 +1154,7 @@ Item_variance_field::Item_variance_field(Item_sum_variance *item) maybe_null=1; } -double Item_variance_field::val() +double Item_variance_field::val_real() { // fix_fields() never calls for this Item double sum,sum_sqr; @@ -1175,7 +1177,7 @@ double Item_variance_field::val() String *Item_variance_field::val_str(String *str) { // fix_fields() never calls for this Item - double nr=val(); + double nr= val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -1553,7 +1555,7 @@ Item *Item_sum_udf_float::copy_or_same(THD* thd) return new (thd->mem_root) Item_sum_udf_float(thd, this); } -double Item_sum_udf_float::val() +double Item_sum_udf_float::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_float::val"); @@ -1565,7 +1567,7 @@ double Item_sum_udf_float::val() String *Item_sum_udf_float::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals, &my_charset_bin); @@ -2004,8 +2006,9 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); + return TRUE; } thd->allow_sum_func= 0; @@ -2019,7 +2022,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) - return 1; + return TRUE; if (i < arg_count_field) maybe_null|= args[i]->maybe_null; } @@ -2029,12 +2032,12 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) max_length= group_concat_max_len; thd->allow_sum_func= 1; if (!(tmp_table_param= new TMP_TABLE_PARAM)) - return 1; + return TRUE; /* We'll convert all blobs to varchar fields in the temporary table */ tmp_table_param->convert_blob_length= group_concat_max_len; tables_list= tables; fixed= 1; - return 0; + return FALSE; } diff --git a/sql/item_sum.h b/sql/item_sum.h index cede5a1e02e..85651c80288 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -107,7 +107,10 @@ public: Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {} bool fix_fields(THD *, TABLE_LIST *, Item **); longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) val(); } /* Real as default */ + { + DBUG_ASSERT(fixed == 1); + return (longlong) val_real(); /* Real as default */ + } String *val_str(String*str); void reset_field(); }; @@ -119,7 +122,7 @@ public: Item_sum_int(Item *item_par) :Item_sum_num(item_par) {} Item_sum_int(List<Item> &list) :Item_sum_num(list) {} Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() @@ -139,7 +142,7 @@ class Item_sum_sum :public Item_sum_num enum Sumfunctype sum_func () const {return SUM_FUNC;} void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); void no_rows_in_result() {} @@ -169,7 +172,7 @@ public: bool setup(THD *thd); void clear(); bool add(); - double val(); + double val_real(); inline void add(double val) { sum+= val; } enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; } @@ -302,8 +305,9 @@ public: Field *field; Item_avg_field(Item_sum_avg *item); enum Type type() const { return FIELD_AVG_ITEM; } - double val(); - longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } + double val_real(); + longlong val_int() + { /* can't be fix_fields()ed */ return (longlong) val_real(); } bool is_null() { (void) val_int(); return null_value; } String *val_str(String*); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -329,7 +333,7 @@ class Item_sum_avg :public Item_sum_num enum Sumfunctype sum_func () const {return AVG_FUNC;} void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); Item *result_item(Field *field) @@ -347,8 +351,9 @@ public: Field *field; Item_variance_field(Item_sum_variance *item); enum Type type() const {return FIELD_VARIANCE_ITEM; } - double val(); - longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } + double val_real(); + longlong val_int() + { /* can't be fix_fields()ed */ return (longlong) val_real(); } String *val_str(String*); bool is_null() { (void) val_int(); return null_value; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -386,7 +391,7 @@ class Item_sum_variance : public Item_sum_num enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); Item *result_item(Field *field) @@ -403,7 +408,7 @@ class Item_std_field :public Item_variance_field public: Item_std_field(Item_sum_std *item); enum Type type() const { return FIELD_STD_ITEM; } - double val(); + double val_real(); }; /* @@ -418,7 +423,7 @@ class Item_sum_std :public Item_sum_variance :Item_sum_variance(thd, item) {} enum Sumfunctype sum_func () const { return STD_FUNC; } - double val(); + double val_real(); Item *result_item(Field *field) { return new Item_std_field(this); } const char *func_name() const { return "std"; } @@ -456,7 +461,7 @@ class Item_sum_hybrid :public Item_sum bool const_item() const { return !used_table_cache; } void clear(); - double val(); + double val_real(); longlong val_int(); void reset_field(); String *val_str(String *); @@ -594,8 +599,11 @@ class Item_sum_udf_float :public Item_udf_sum Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_udf_sum(thd, item) {} longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) Item_sum_udf_float::val(); } - double val(); + { + DBUG_ASSERT(fixed == 1); + return (longlong) Item_sum_udf_float::val_real(); + } + double val_real(); String *val_str(String*str); void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); @@ -611,7 +619,7 @@ public: Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_udf_sum(thd, item) {} longlong val_int(); - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } @@ -629,7 +637,7 @@ public: Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) :Item_udf_sum(thd, item) {} String *val_str(String *); - double val() + double val_real() { int err; String *res; res=val_str(&str_value); @@ -657,7 +665,7 @@ class Item_sum_udf_float :public Item_sum_num Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -673,7 +681,7 @@ public: :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } - double val() { DBUG_ASSERT(fixed == 1); return 0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -689,7 +697,7 @@ public: :Item_sum_num(thd, item) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - double val() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { maybe_null=1; max_length=0; } @@ -761,7 +769,7 @@ class Item_func_group_concat : public Item_sum bool setup(THD *thd); void make_unique(); virtual void update_field() {} - double val() + double val_real() { String *res; res=val_str(&str_value); return res ? my_atof(res->c_ptr()) : 0.0; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 566cacca487..d1b490008df 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -161,21 +161,24 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, { int weekday= 0, yearday= 0, daypart= 0; int week_number= -1; - CHARSET_INFO *cs= &my_charset_bin; int error= 0; - bool usa_time= 0; - bool sunday_first_n_first_week_non_iso= -2; - bool strict_week_number; int strict_week_number_year= -1; - bool strict_week_number_year_type= -1; int frac_part; + bool usa_time= 0; + bool sunday_first_n_first_week_non_iso; + bool strict_week_number; + bool strict_week_number_year_type; const char *val_begin= val; const char *val_end= val + length; const char *ptr= format->format.str; const char *end= ptr + format->format.length; + CHARSET_INFO *cs= &my_charset_bin; DBUG_ENTER("extract_date_time"); LINT_INIT(strict_week_number); + /* Remove valgrind varnings when using gcc 3.3 and -O1 */ + PURIFY_OR_LINT_INIT(strict_week_number_year_type); + PURIFY_OR_LINT_INIT(sunday_first_n_first_week_non_iso); if (!sub_pattern_end) bzero((char*) l_time, sizeof(*l_time)); @@ -1666,7 +1669,7 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re { String str; if (Item_date_func::fix_fields(thd_arg, tables_arg, ref)) - return 1; + return TRUE; tz_tables= thd_arg->lex->time_zone_tables_used; @@ -1676,7 +1679,7 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re if (args[2]->const_item()) to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); - return 0; + return FALSE; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 694f2dc583c..dccba7f52b1 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -88,7 +88,7 @@ class Item_func_month :public Item_func public: Item_func_month(Item *a) :Item_func(a) {} longlong val_int(); - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } String *val_str(String *str) { @@ -250,7 +250,7 @@ public: Item_func_weekday(Item *a,bool type_arg) :Item_func(a), odbc_type(type_arg) {} longlong val_int(); - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -326,7 +326,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATE; } String *val_str(String *str); longlong val_int(); - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } const char *func_name() const { return "date"; } void fix_length_and_dec() { @@ -369,7 +369,7 @@ public: Item_func_curtime(Item *a) :Item_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String *val_str(String *str); void fix_length_and_dec(); @@ -452,7 +452,7 @@ public: Item_func_now() :Item_date_func() {} Item_func_now(Item *a) :Item_date_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); @@ -512,7 +512,7 @@ class Item_func_from_unixtime :public Item_date_func THD *thd; public: Item_func_from_unixtime(Item *a) :Item_date_func(a) {} - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_from_unixtime::val_int(); @@ -552,7 +552,7 @@ class Item_func_convert_tz :public Item_date_func Item_func_convert_tz(Item *a, Item *b, Item *c): Item_date_func(a, b, c) {} longlong val_int(); - double val() { return (double) val_int(); } + double val_real() { return (double) val_int(); } String *val_str(String *str); const char *func_name() const { return "convert_tz"; } bool fix_fields(THD *, struct st_table_list *, Item **); @@ -565,7 +565,7 @@ class Item_func_sec_to_time :public Item_str_func { public: Item_func_sec_to_time(Item *item) :Item_str_func(item) {} - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_sec_to_time::val_int(); @@ -615,7 +615,7 @@ public: const char *func_name() const { return "date_add_interval"; } void fix_length_and_dec(); enum_field_types field_type() const { return cached_field_type; } - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); bool get_date(TIME *res, uint fuzzy_date); void print(String *str); diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 5582537bdbb..e74c09ca3c4 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -27,7 +27,7 @@ class Item_func_unique_users :public Item_real_func public: Item_func_unique_users(Item *name_arg,int start,int end,List<Item> &list) :Item_real_func(list) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void fix_length_and_dec() { decimals=0; max_length=6; } void print(String *str) { str->append("0.0", 3); } }; @@ -40,7 +40,7 @@ public: :Item_sum_num(item_arg) {} Item_sum_unique_users(THD *thd, Item_sum_unique_users *item) :Item_sum_num(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;} void clear() {} bool add() { return 0; } @@ -50,7 +50,7 @@ public: { DBUG_ASSERT(fixed == 0); fixed= 1; - return 0; + return FALSE; } Item *copy_or_same(THD* thd) { diff --git a/sql/lex.h b/sql/lex.h index 89daf46218c..db31b3af994 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -120,6 +120,7 @@ static SYMBOL symbols[] = { { "CONCURRENT", SYM(CONCURRENT)}, { "CONDITION", SYM(CONDITION_SYM)}, { "CONNECTION", SYM(CONNECTION_SYM)}, + { "CONSISTENT", SYM(CONSISTENT_SYM)}, { "CONSTRAINT", SYM(CONSTRAINT)}, { "CONTAINS", SYM(CONTAINS_SYM)}, { "CONTINUE", SYM(CONTINUE_SYM)}, @@ -421,6 +422,7 @@ static SYMBOL symbols[] = { { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, { "SOME", SYM(ANY_SYM)}, { "SONAME", SYM(UDF_SONAME_SYM)}, diff --git a/sql/lock.cc b/sql/lock.cc index 6d5ca5bf6b4..c4f1d681b76 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -430,7 +430,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name); + my_error(ER_OPEN_AS_READONLY, MYF(0), table->table_name); my_free((gptr) sql_lock,MYF(0)); return 0; } @@ -795,7 +795,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, if (thd->global_read_lock) // This thread had the read locks { if (is_not_commit) - my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0)); + my_message(ER_CANT_UPDATE_WITH_READLOCK, + ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0)); (void) pthread_mutex_unlock(&LOCK_open); /* We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does. diff --git a/sql/log.cc b/sql/log.cc index ef538c3b03f..75a1743febc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1464,7 +1464,8 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", if (flush_io_cache(file) || sync_binlog(file)) goto err; - if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log)) + if (opt_using_transactions && + !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* LOAD DATA INFILE in AUTOCOMMIT=1 mode writes to the binlog @@ -1515,7 +1516,7 @@ err: if (error) { if (my_errno == EFBIG) - my_error(ER_TRANS_CACHE_FULL, MYF(0)); + my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(0)); else my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno); write_error=1; @@ -1612,6 +1613,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) { Query_log_event qinfo(thd, "BEGIN", 5, TRUE); /* + Imagine this is rollback due to net timeout, after all statements of + the transaction succeeded. Then we want a zero-error code in BEGIN. + In other words, if there was a really serious error code it's already + in the statement's events. + This is safer than thd->clear_error() against kills at shutdown. + */ + qinfo.error_code= 0; + /* Now this Query_log_event has artificial log_pos 0. It must be adjusted to reflect the real position in the log. Not doing it would confuse the slave: it would prevent this one from knowing where he is in the @@ -1643,6 +1652,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) commit_or_rollback ? "COMMIT" : "ROLLBACK", commit_or_rollback ? 6 : 8, TRUE); + qinfo.error_code= 0; if (qinfo.write(&log_file) || flush_io_cache(&log_file) || sync_binlog(&log_file)) goto err; @@ -1714,12 +1724,19 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, time_t current_time; if (!is_open()) return 0; + DBUG_ENTER("MYSQL_LOG::write"); + VOID(pthread_mutex_lock(&LOCK_log)); if (is_open()) { // Safety agains reopen int tmp_errno=0; char buff[80],*end; end=buff; + if (!(thd->options & OPTION_UPDATE_LOG)) + { + VOID(pthread_mutex_unlock(&LOCK_log)); + DBUG_RETURN(0); + } if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT) || query_start_arg) { current_time=time(NULL); @@ -1818,7 +1835,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, } } VOID(pthread_mutex_unlock(&LOCK_log)); - return error; + DBUG_RETURN(error); } @@ -1838,16 +1855,19 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, THD::enter_cond() (see NOTES in sql_class.h). */ -void MYSQL_LOG:: wait_for_update(THD* thd, bool master_or_slave) +void MYSQL_LOG::wait_for_update(THD* thd, bool master_or_slave) { - const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log, - master_or_slave ? - "Has read all relay log; waiting for \ -the slave I/O thread to update it" : - "Has sent all binlog to slave; \ -waiting for binlog to be updated"); + const char *old_msg; + DBUG_ENTER("wait_for_update"); + old_msg= thd->enter_cond(&update_cond, &LOCK_log, + master_or_slave ? + "Has read all relay log; waiting for the slave I/O " + "thread to update it" : + "Has sent all binlog to slave; waiting for binlog " + "to be updated"); pthread_cond_wait(&update_cond, &LOCK_log); thd->exit_cond(old_msg); + DBUG_VOID_RETURN; } @@ -2204,6 +2224,15 @@ void MYSQL_LOG::report_pos_in_innodb() DBUG_VOID_RETURN; } + +void MYSQL_LOG::signal_update() +{ + DBUG_ENTER("MYSQL_LOG::signal_update"); + pthread_cond_broadcast(&update_cond); + DBUG_VOID_RETURN; +} + + #ifdef __NT__ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, uint length, int buffLen) diff --git a/sql/log_event.cc b/sql/log_event.cc index c7f6f25e74a..ccc563d31ac 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1362,7 +1362,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) Thank you. */ thd->catalog= (char*) catalog; - thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->db_length= db_len; + thd->db= (char*) rewrite_db(db, &thd->db_length); thd->variables.auto_increment_increment= auto_increment_increment; thd->variables.auto_increment_offset= auto_increment_offset; @@ -1384,11 +1385,6 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - /* - We cannot use db_len from event to fill thd->db_length, because - rewrite_db() may have changed db. - */ - thd->db_length= thd->db ? strlen(thd->db) : 0; thd->query_length= q_len; thd->query = (char*)query; VOID(pthread_mutex_lock(&LOCK_thread_count)); @@ -1466,10 +1462,10 @@ START SLAVE; . Query: '%s'", expected_error, thd->query); Query caused different errors on master and slave. \ Error on master: '%s' (%d), Error on slave: '%s' (%d). \ Default database: '%s'. Query: '%s'", - ER_SAFE(expected_error), - expected_error, - actual_error ? thd->net.last_error: "no error", - actual_error, + ER_SAFE(expected_error), + expected_error, + actual_error ? thd->net.last_error: "no error", + actual_error, print_slave_db_safe(db), query); thd->query_error= 1; } @@ -1489,9 +1485,9 @@ Default database: '%s'. Query: '%s'", { slave_print_error(rli,actual_error, "Error '%s' on query. Default database: '%s'. Query: '%s'", - (actual_error ? thd->net.last_error : - "unexpected success or fatal error"), - print_slave_db_safe(db), query); + (actual_error ? thd->net.last_error : + "unexpected success or fatal error"), + print_slave_db_safe(thd->db), query); thd->query_error= 1; } @@ -2435,7 +2431,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, bool use_rli_only_for_errors) { char *load_data_query= 0; - thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->db_length= db_len; + thd->db= (char*) rewrite_db(db, &thd->db_length); DBUG_ASSERT(thd->query == 0); thd->query_length= 0; // Should not be needed thd->query_error= 0; @@ -2467,7 +2464,6 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - thd->db_length= thd->db ? strlen(thd->db) : 0; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -2573,7 +2569,7 @@ Slave: load data infile on table '%s' at log position %s in log \ (char*) table_name, llstr(log_pos,llbuff), RPL_LOG_NAME, (ulong) thd->cuted_fields, - print_slave_db_safe(db)); + print_slave_db_safe(thd->db)); } if (net) net->pkt_nr= thd->net.pkt_nr; @@ -2591,6 +2587,7 @@ Slave: load data infile on table '%s' at log position %s in log \ } thd->net.vio = 0; + char *save_db= thd->db; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= thd->catalog= 0; thd->query= 0; @@ -2601,7 +2598,7 @@ Slave: load data infile on table '%s' at log position %s in log \ my_afree(load_data_query); if (thd->query_error) { - /* this err/sql_errno code is copy-paste from send_error() */ + /* this err/sql_errno code is copy-paste from net_send_error() */ const char *err; int sql_errno; if ((err=thd->net.last_error)[0]) @@ -2613,7 +2610,7 @@ Slave: load data infile on table '%s' at log position %s in log \ } slave_print_error(rli,sql_errno,"\ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", - err, (char*)table_name, print_slave_db_safe(db)); + err, (char*)table_name, print_slave_db_safe(save_db)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); return 1; } @@ -2623,7 +2620,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", { slave_print_error(rli,ER_UNKNOWN_ERROR, "\ Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", - (char*)table_name, print_slave_db_safe(db)); + (char*)table_name, print_slave_db_safe(save_db)); return 1; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b343beaa4e4..7a49799c7cd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -247,6 +247,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; key checks in some cases */ #define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27) #define SELECT_NO_UNLOCK (1L << 28) +#define OPTION_SCHEMA_TABLE (1L << 29) /* The rest of the file is included in the server only */ #ifndef MYSQL_CLIENT @@ -405,23 +406,24 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert); void free_items(Item *item); void cleanup_items(Item *item); class THD; -void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0); +void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0, + TABLE *stopper= 0); bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); -int multi_update_precheck(THD *thd, TABLE_LIST *tables); -int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); -int mysql_multi_update_prepare(THD *thd); -int mysql_multi_delete_prepare(THD *thd); -int mysql_insert_select_prepare(THD *thd); -int insert_select_precheck(THD *thd, TABLE_LIST *tables); -int update_precheck(THD *thd, TABLE_LIST *tables); -int delete_precheck(THD *thd, TABLE_LIST *tables); -int insert_precheck(THD *thd, TABLE_LIST *tables); -int create_table_precheck(THD *thd, TABLE_LIST *tables, - TABLE_LIST *create_table); +bool multi_update_precheck(THD *thd, TABLE_LIST *tables); +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); +bool mysql_multi_update_prepare(THD *thd); +bool mysql_multi_delete_prepare(THD *thd); +bool mysql_insert_select_prepare(THD *thd); +bool insert_select_precheck(THD *thd, TABLE_LIST *tables); +bool update_precheck(THD *thd, TABLE_LIST *tables); +bool delete_precheck(THD *thd, TABLE_LIST *tables); +bool insert_precheck(THD *thd, TABLE_LIST *tables); +bool create_table_precheck(THD *thd, TABLE_LIST *tables, + TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); #include "sql_class.h" #include "opt_range.h" @@ -471,12 +473,12 @@ struct Query_cache_query_flags #define prepare_execute(A) ((A)->command == COM_EXECUTE) -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); -int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); -int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); +bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); +bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); +bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags); -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary); +bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary); int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, bool log_query); int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables, @@ -504,7 +506,7 @@ extern "C" pthread_handler_decl(handle_one_connection,arg); extern "C" pthread_handler_decl(handle_bootstrap,arg); void end_thread(THD *thd,bool put_in_cache); void flush_thread_cache(); -int mysql_execute_command(THD *thd); +bool mysql_execute_command(THD *thd); bool do_command(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); @@ -523,22 +525,22 @@ bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, bool no_errors); bool check_global_access(THD *thd, ulong want_access); -int mysql_backup_table(THD* thd, TABLE_LIST* table_list); -int mysql_restore_table(THD* thd, TABLE_LIST* table_list); - -int mysql_checksum_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_check_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_repair_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list, - LEX_STRING *key_cache_name); -int mysql_preload_keys(THD* thd, TABLE_LIST* table_list); +bool mysql_backup_table(THD* thd, TABLE_LIST* table_list); +bool mysql_restore_table(THD* thd, TABLE_LIST* table_list); + +bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_check_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_repair_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_analyze_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_optimize_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list, + LEX_STRING *key_cache_name); +bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list); int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache, KEY_CACHE *dst_cache); @@ -551,23 +553,23 @@ int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List<Item> &fields, List<Item> &all_fields, ORDER *order, bool *hidden_group_fields); -int handle_select(THD *thd, LEX *lex, select_result *result); -int mysql_select(THD *thd, Item ***rref_pointer_array, - TABLE_LIST *tables, uint wild_num, List<Item> &list, - COND *conds, uint og_num, ORDER *order, ORDER *group, - Item *having, ORDER *proc_param, ulong select_type, - select_result *result, SELECT_LEX_UNIT *unit, - SELECT_LEX *select_lex); +bool handle_select(THD *thd, LEX *lex, select_result *result); +bool mysql_select(THD *thd, Item ***rref_pointer_array, + TABLE_LIST *tables, uint wild_num, List<Item> &list, + COND *conds, uint og_num, ORDER *order, ORDER *group, + Item *having, ORDER *proc_param, ulong select_type, + select_result *result, SELECT_LEX_UNIT *unit, + SELECT_LEX *select_lex); void free_underlaid_joins(THD *thd, SELECT_LEX *select); -int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, - select_result *result); +bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, + select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, select_result *result); -int mysql_union(THD *thd, LEX *lex, select_result *result, - SELECT_LEX_UNIT *unit); +bool mysql_union(THD *thd, LEX *lex, select_result *result, + SELECT_LEX_UNIT *unit); int mysql_handle_derived(LEX *lex, int (*processor)(THD *thd, - st_lex *lex, - st_table_list *table)); + LEX *lex, + TABLE_LIST *table)); int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t); int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, @@ -578,61 +580,61 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, List<Key> &keys, uint &db_options, handler *file, KEY *&key_info_buffer, uint &key_count, int select_field_count); -int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List<create_field> &fields, List<Key> &keys, - bool tmp_table, uint select_field_count); +bool mysql_create_table(THD *thd,const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + List<create_field> &fields, List<Key> &keys, + bool tmp_table, uint select_field_count); TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE_LIST *create_table, List<create_field> *extra_fields, List<Key> *keys, List<Item> *items, - MYSQL_LOCK **lock); -int mysql_alter_table(THD *thd, char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - List<create_field> &fields, - List<Key> &keys, - uint order_num, ORDER *order, - enum enum_duplicates handle_duplicates, - ALTER_INFO *alter_info, bool do_send_ok=1); -int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); -int mysql_create_like_table(THD *thd, TABLE_LIST *table, - HA_CREATE_INFO *create_info, - Table_ident *src_table); + MYSQL_LOCK **lock); +bool mysql_alter_table(THD *thd, char *new_db, char *new_name, + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List<create_field> &fields, + List<Key> &keys, + uint order_num, ORDER *order, + enum enum_duplicates handle_duplicates, + ALTER_INFO *alter_info, bool do_send_ok=1); +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); +bool mysql_create_like_table(THD *thd, TABLE_LIST *table, + HA_CREATE_INFO *create_info, + Table_ident *src_table); bool mysql_rename_table(enum db_type base, const char *old_db, const char * old_name, const char *new_db, const char * new_name); -int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); -int mysql_drop_index(THD *thd, TABLE_LIST *table_list, - ALTER_INFO *alter_info); -int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, - Item **conds, uint order_num, ORDER *order); -int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, - List<Item> &values,COND *conds, - uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates); -int mysql_multi_update(THD *thd, TABLE_LIST *table_list, - List<Item> *fields, List<Item> *values, - COND *conds, ulong options, - enum enum_duplicates handle_duplicates, - SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); -int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, - List<Item> &fields, List_item *values, - List<Item> &update_fields, - List<Item> &update_values, enum_duplicates duplic); -int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, - List<List_item> &values, List<Item> &update_fields, - List<Item> &update_values, enum_duplicates flag); +bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); +bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, + ALTER_INFO *alter_info); +bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, + Item **conds, uint order_num, ORDER *order); +bool mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, + List<Item> &values,COND *conds, + uint order_num, ORDER *order, ha_rows limit, + enum enum_duplicates handle_duplicates); +bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, + List<Item> *fields, List<Item> *values, + COND *conds, ulong options, + enum enum_duplicates handle_duplicates, + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, + List<Item> &fields, List_item *values, + List<Item> &update_fields, + List<Item> &update_values, enum_duplicates duplic); +bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, + List<List_item> &values, List<Item> &update_fields, + List<Item> &update_values, enum_duplicates flag); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry); -int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); -int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, - ha_rows rows, ulong options); -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); -int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create); +bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); +bool mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, + ha_rows rows, ulong options); +bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); +bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem, bool *refresh); @@ -649,10 +651,15 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); void execute_init_command(THD *thd, sys_var_str *init_command_var, rw_lock_t *var_mutex); -extern const Field *not_found_field; -extern const Field *view_ref_found; +extern Field *not_found_field; +extern Field *view_ref_found; + +enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, + IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE, + IGNORE_EXCEPT_NON_UNIQUE}; Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, - Item **ref, bool report_error, + Item **ref, + find_item_error_report_type report_error, bool check_privileges); Field * find_field_in_table(THD *thd, TABLE_LIST *table_list, @@ -684,46 +691,57 @@ void free_des_key_file(); #endif /* HAVE_OPENSSL */ /* sql_do.cc */ -int mysql_do(THD *thd, List<Item> &values); +bool mysql_do(THD *thd, List<Item> &values); /* sql_show.cc */ -int mysqld_show_dbs(THD *thd,const char *wild); -int mysqld_show_open_tables(THD *thd,const char *wild); -int mysqld_show_tables(THD *thd, const char *db, const char *wild, - bool verbose); -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild); -int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild, - bool verbose); -int mysqld_show_keys(THD *thd, TABLE_LIST *table); -int mysqld_show_logs(THD *thd); +bool mysqld_show_open_tables(THD *thd,const char *wild); +bool mysqld_show_logs(THD *thd); void append_identifier(THD *thd, String *packet, const char *name, uint length); int get_quote_char_for_identifier(THD *thd, const char *name, uint length); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1); -int mysqld_show_create(THD *thd, TABLE_LIST *table_list); -int mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); +bool mysqld_show_create(THD *thd, TABLE_LIST *table_list); +bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); -int mysqld_show(THD *thd, const char *wild, show_var_st *variables, +bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, enum enum_var_type value_type, pthread_mutex_t *mutex, struct system_status_var *status_var); int mysql_find_files(THD *thd,List<char> *files, const char *db, const char *path, const char *wild, bool dir); -int mysqld_show_charsets(THD *thd,const char *wild); -int mysqld_show_collations(THD *thd,const char *wild); -int mysqld_show_storage_engines(THD *thd); -int mysqld_show_privileges(THD *thd); -int mysqld_show_column_types(THD *thd); -int mysqld_help (THD *thd, const char *text); +bool mysqld_show_storage_engines(THD *thd); +bool mysqld_show_privileges(THD *thd); +bool mysqld_show_column_types(THD *thd); +bool mysqld_help (THD *thd, const char *text); void calc_sum_of_all_status(STATUS_VAR *to); + + +/* information schema */ +extern LEX_STRING information_schema_name; +LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, + const char* str, uint length, + bool allocate_lex_string= 0); +ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name); +ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx); +int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, + enum enum_schema_tables schema_table_idx); +int make_schema_select(THD *thd, SELECT_LEX *sel, + enum enum_schema_tables schema_table_idx); +int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list); +int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +bool get_schema_tables_result(JOIN *join); + /* sql_prepare.cc */ -int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, - LEX_STRING *name=NULL); +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, + LEX_STRING *name=NULL); void mysql_stmt_execute(THD *thd, char *packet, uint packet_length); void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name); void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length); @@ -738,13 +756,13 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, const char *format, ...); void mysql_reset_errors(THD *thd); -my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show); +bool mysqld_show_warnings(THD *thd, ulong levels_to_show); /* sql_handler.cc */ -int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen= 0); -int mysql_ha_close(THD *thd, TABLE_LIST *tables); -int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, - List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); +bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen= 0); +bool mysql_ha_close(THD *thd, TABLE_LIST *tables); +bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, + List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags); /* mysql_ha_flush mode_flags bits */ #define MYSQL_HA_CLOSE_FINAL 0x00 @@ -771,9 +789,7 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error, bool allow_null_cond= false); -enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, - IGNORE_ERRORS}; -extern const Item **not_found_item; +extern Item **not_found_item; Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter, find_item_error_report_type report_error, bool *unaliased); @@ -786,16 +802,16 @@ bool insert_fields(THD *thd,TABLE_LIST *tables, bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num); -int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables, - List<Item> &item, bool set_query_id, - List<Item> *sum_func_list, bool allow_sum_func); +bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables, + List<Item> &item, bool set_query_id, + List<Item> *sum_func_list, bool allow_sum_func); int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); int setup_ftfuncs(SELECT_LEX* select); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); -int open_and_lock_tables(THD *thd,TABLE_LIST *tables); +bool open_and_lock_tables(THD *thd,TABLE_LIST *tables); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); @@ -820,8 +836,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table, bool return_if_owned_by_thd=0); bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables); void copy_field_from_tmp_record(Field *field,int offset); -int fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors); -int fill_record(Field **field,List<Item> &values, bool ignore_errors); +bool fill_record(THD *thd, List<Item> &fields, List<Item> &values, + bool ignore_errors); +bool fill_record(THD *thd, Field **field, List<Item> &values, + bool ignore_errors); OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild); inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, @@ -845,10 +863,10 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table, bool eval_const_cond(COND *cond); /* sql_load.cc */ -int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, - List<Item> &fields, enum enum_duplicates handle_duplicates, - bool local_file, thr_lock_type lock_type, - bool ignore_check_option_errors); +bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, + List<Item> &fields, enum enum_duplicates handle_duplicates, + bool local_file, thr_lock_type lock_type, + bool ignore_check_option_errors); int write_record(THD *thd, TABLE *table, COPY_INFO *info); /* sql_manager.cc */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 196b7af46b1..a3a3290565a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -543,7 +543,7 @@ static void close_connections(void) struct timespec abstime; int error; LINT_INIT(error); - DBUG_PRINT("info",("Waiting for select_thread")); + DBUG_PRINT("info",("Waiting for select thread")); #ifndef DONT_USE_THR_ALARM if (pthread_kill(select_thread,THR_CLIENT_ALARM)) @@ -1172,7 +1172,8 @@ static void server_init(void) WSADATA WsaData; if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData)) { - my_message(0,"WSAStartup Failed\n",MYF(0)); + /* errors are not read yet, so we use test here */ + my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0)); unireg_abort(1); } } @@ -1334,8 +1335,9 @@ void yyerror(const char *s) /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s=ER(ER_SYNTAX_ERROR); - net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", - thd->lex->yylineno); + my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, + (yytext ? (char*) yytext : ""), + thd->lex->yylineno); } @@ -1366,7 +1368,7 @@ void close_connection(THD *thd, uint errcode, bool lock) if ((vio=thd->net.vio) != 0) { if (errcode) - send_error(thd, errcode, ER(errcode)); /* purecov: inspected */ + net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */ vio_close(vio); /* vio is freed in delete thd */ } if (lock) @@ -2130,6 +2132,11 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags) THD *thd; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); + /* + Put here following assertion when situation with EE_* error codes + will be fixed + DBUG_ASSERT(error != 0); + */ if ((thd= current_thd)) { if (thd->spcont && @@ -2137,6 +2144,9 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags) { DBUG_RETURN(0); } + + thd->query_error= 1; // needed to catch query errors during replication + /* thd->lex->current_select == 0 if lex structure is not inited (not query command (COM_QUERY)) @@ -2155,6 +2165,9 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags) { NET *net= &thd->net; net->report_error= 1; +#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ + query_cache_abort(net); +#endif if (!net->last_error[0]) // Return only first message { strmake(net->last_error, str, sizeof(net->last_error)-1); @@ -2313,8 +2326,6 @@ bool init_global_datetime_format(timestamp_type format_type, static int init_common_variables(const char *conf_file_name, int argc, char **argv, const char **groups) { - my_umask=0660; // Default umask for new files - my_umask_dir=0700; // Default umask for new directories umask(((~my_umask) & 0666)); tzset(); // Set tzname @@ -3430,10 +3441,10 @@ static void create_new_thread(THD *thd) ("Can't create thread to handle request (error %d)", error)); thread_count--; - thd->killed= THD::KILL_CONNECTION; // Safety + thd->killed= THD::KILL_CONNECTION; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); statistic_increment(aborted_connects,&LOCK_status); - net_printf(thd,ER_CANT_CREATE_THREAD,error); + net_printf_error(thd, ER_CANT_CREATE_THREAD, error); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(thd,0,0); delete thd; @@ -4337,7 +4348,7 @@ Disable with --skip-innodb (will save memory).", "Percentage of dirty pages allowed in bufferpool.", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, {"innodb_max_purge_lag", OPT_INNODB_MAX_PURGE_LAG, - "", + "Desired maximum length of the purge queue (0 = no limit)", (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, @@ -4346,7 +4357,7 @@ Disable with --skip-innodb (will save memory).", (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS, - "If Innodb should enforce LOCK TABLE", + "Enable InnoDB locking in LOCK TABLES", (gptr*) &global_system_variables.innodb_table_locks, (gptr*) &global_system_variables.innodb_table_locks, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bcb1f8634c0..02fc1691b8b 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -96,7 +96,7 @@ extern void query_cache_insert(NET *net, const char *packet, ulong length); #define update_statistics(A) A #else #define update_statistics(A) -#define thd_increment_bytes_sent() +#define thd_increment_bytes_sent(N) #endif #define TEST_BLOCKING 8 diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 30033bc39eb..f9a51a8348f 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -131,7 +131,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) for (table= tables; table; table= table->next_local) { if (outer_tables || (table->table->file->table_flags() & - HA_NOT_EXACT_COUNT)) + HA_NOT_EXACT_COUNT) || table->schema_table) { const_result= 0; // Can't optimize left join break; diff --git a/sql/parse_file.cc b/sql/parse_file.cc index c3043ed2c73..6c3a81384a6 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -668,7 +668,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, parameter->offset)))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -680,7 +680,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, (base + parameter->offset)))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -690,7 +690,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, if (!(eol= strchr(ptr, '\n'))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + parameter->name.str, line); DBUG_RETURN(TRUE); } { @@ -708,7 +708,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, if (ptr[PARSE_FILE_TIMESTAMPLENGTH] != '\n') { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + parameter->name.str, line); DBUG_RETURN(TRUE); } memcpy(val->str, ptr, PARSE_FILE_TIMESTAMPLENGTH); @@ -748,7 +748,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, list_err_w_message: my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + parameter->name.str, line); list_err: DBUG_RETURN(TRUE); } @@ -761,8 +761,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, // skip unknown parameter if (!(ptr= strchr(ptr, '\n'))) { - my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), - line); + my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), line); DBUG_RETURN(TRUE); } ptr++; diff --git a/sql/procedure.cc b/sql/procedure.cc index 7779f5ce085..420a4f6262b 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -65,8 +65,7 @@ setup_procedure(THD *thd,ORDER *param,select_result *result, DBUG_RETURN(proc); } } - my_printf_error(ER_UNKNOWN_PROCEDURE,ER(ER_UNKNOWN_PROCEDURE),MYF(0), - (*param->item)->name); + my_error(ER_UNKNOWN_PROCEDURE, MYF(0), (*param->item)->name); *error=1; DBUG_RETURN(0); } diff --git a/sql/procedure.h b/sql/procedure.h index 5365b2e1102..160777967ff 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -60,7 +60,7 @@ public: void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } - double val() { return value; } + double val_real() { return value; } longlong val_int() { return (longlong) value; } String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } unsigned int size_of() { return sizeof(*this);} @@ -78,7 +78,7 @@ public: void set(longlong nr) { value=nr; } void set(const char *str,uint length, CHARSET_INFO *cs) { int err; value=my_strntoll(cs,str,length,10,NULL,&err); } - double val() { return (double) value; } + double val_real() { return (double) value; } longlong val_int() { return value; } String *val_str(String *s) { s->set(value, default_charset()); return s; } unsigned int size_of() { return sizeof(*this);} @@ -96,7 +96,7 @@ public: void set(longlong nr) { str_value.set(nr, default_charset()); } void set(const char *str, uint length, CHARSET_INFO *cs) { str_value.copy(str,length,cs); } - double val() + double val_real() { int err; CHARSET_INFO *cs=str_value.charset(); diff --git a/sql/protocol.cc b/sql/protocol.cc index 2b0ae60f944..88be2710422 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -53,14 +53,14 @@ bool Protocol_prep::net_store_data(const char *from, uint length) /* Send a error string to client */ -void send_error(THD *thd, uint sql_errno, const char *err) +void net_send_error(THD *thd, uint sql_errno, const char *err) { #ifndef EMBEDDED_LIBRARY uint length; char buff[MYSQL_ERRMSG_SIZE+2], *pos; #endif NET *net= &thd->net; - DBUG_ENTER("send_error"); + DBUG_ENTER("net_send_error"); DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err ? err : net->last_error[0] ? net->last_error : "NULL")); @@ -70,9 +70,6 @@ void send_error(THD *thd, uint sql_errno, const char *err) { DBUG_VOID_RETURN; } -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ - query_cache_abort(net); -#endif thd->query_error= 1; // needed to catch query errors during replication if (!err) { @@ -130,7 +127,6 @@ void send_error(THD *thd, uint sql_errno, const char *err) thd->net.report_error= 0; /* Abort multi-result sets */ - thd->lex->found_colon= 0; thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; } @@ -172,7 +168,7 @@ void send_warning(THD *thd, uint sql_errno, const char *err) */ void -net_printf(THD *thd, uint errcode, ...) +net_printf_error(THD *thd, uint errcode, ...) { va_list args; uint length,offset; @@ -185,7 +181,7 @@ net_printf(THD *thd, uint errcode, ...) #endif NET *net= &thd->net; - DBUG_ENTER("net_printf"); + DBUG_ENTER("net_printf_error"); DBUG_PRINT("enter",("message: %u",errcode)); if (thd->spcont && thd->spcont->find_handler(errcode, @@ -199,8 +195,8 @@ net_printf(THD *thd, uint errcode, ...) #endif va_start(args,errcode); /* - The following is needed to make net_printf() work with 0 argument for - errorcode and use the argument after that as the format string. This + The following is needed to make net_printf_error() work with 0 argument + for errorcode and use the argument after that as the format string. This is useful for rare errors that are not worth the hassle to put in errmsg.sys, but at the same time, the message is not fixed text */ @@ -627,7 +623,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags) DBUG_RETURN(prepare_for_send(list)); err: - send_error(thd,ER_OUT_OF_RESOURCES); /* purecov: inspected */ + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/sql/protocol.h b/sql/protocol.h index d342af3ee9f..fddd3ceba94 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -173,7 +173,8 @@ public: }; void send_warning(THD *thd, uint sql_errno, const char *err=0); -void net_printf(THD *thd,uint sql_errno, ...); +void net_printf_error(THD *thd, uint sql_errno, ...); +void net_send_error(THD *thd, uint sql_errno=0, const char *err=0); void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, const char *info=0); void send_eof(THD *thd, bool no_flush=0); diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index 104457b3bcc..a5bf94469e7 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -84,7 +84,8 @@ bool Protocol_cursor::send_fields(List<Item> *list, uint flags) DBUG_RETURN(FALSE); err: - send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */ + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(TRUE); /* purecov: inspected */ } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 253b2c96545..5f67143065b 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -194,7 +194,6 @@ err: my_message(ER_UNKNOWN_ERROR, "Wrong parameters to function register_slave", MYF(0)); err2: - send_error(thd); return 1; } @@ -438,7 +437,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, This function is broken now. See comment for translate_master(). */ -int show_new_master(THD* thd) +bool show_new_master(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_new_master"); @@ -451,8 +450,8 @@ int show_new_master(THD* thd) { if (errmsg[0]) my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), - "SHOW NEW MASTER", errmsg); - DBUG_RETURN(-1); + "SHOW NEW MASTER", errmsg); + DBUG_RETURN(TRUE); } else { @@ -461,14 +460,14 @@ int show_new_master(THD* thd) MYSQL_TYPE_LONGLONG)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); protocol->store(lex_mi->log_file_name, &my_charset_bin); protocol->store((ulonglong) lex_mi->pos); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } } @@ -631,7 +630,7 @@ err: } -int show_slave_hosts(THD* thd) +bool show_slave_hosts(THD* thd) { List<Item> field_list; Protocol *protocol= thd->protocol; @@ -653,7 +652,7 @@ int show_slave_hosts(THD* thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); pthread_mutex_lock(&LOCK_slave_list); @@ -674,12 +673,12 @@ int show_slave_hosts(THD* thd) if (protocol->write()) { pthread_mutex_unlock(&LOCK_slave_list); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } pthread_mutex_unlock(&LOCK_slave_list); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -760,7 +759,7 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db, - No active transaction (flush_relay_log_info would not work in this case) */ -int load_master_data(THD* thd) +bool load_master_data(THD* thd) { MYSQL mysql; MYSQL_RES* master_status_res = 0; @@ -782,16 +781,15 @@ int load_master_data(THD* thd) (error=terminate_slave_threads(active_mi,restart_thread_mask, 1 /*skip lock*/))) { - send_error(thd,error); + my_message(error, ER(error), MYF(0)); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); - return 1; + return TRUE; } if (connect_to_master(thd, &mysql, active_mi)) { - net_printf(thd, error= ER_CONNECT_TO_MASTER, - mysql_error(&mysql)); + my_error(error= ER_CONNECT_TO_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -803,8 +801,7 @@ int load_master_data(THD* thd) if (mysql_real_query(&mysql, "SHOW DATABASES", 14) || !(db_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -817,7 +814,7 @@ int load_master_data(THD* thd) if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) { - net_printf(thd, error = ER_OUTOFMEMORY); + my_message(error = ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0)); goto err; } @@ -831,8 +828,7 @@ int load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW MASTER STATUS",18) || !(master_status_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -877,7 +873,6 @@ int load_master_data(THD* thd) if (mysql_create_db(thd, db, &create_info, 1)) { - send_error(thd, 0, 0); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -886,8 +881,7 @@ int load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW TABLES", 11) || !(*cur_table_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -925,7 +919,7 @@ int load_master_data(THD* thd) if (init_master_info(active_mi, master_info_file, relay_log_info_file, 0)) - send_error(thd, ER_MASTER_INFO); + my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error); @@ -944,8 +938,7 @@ int load_master_data(THD* thd) if (mysql_real_query(&mysql, "UNLOCK TABLES", 13)) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } } @@ -954,10 +947,10 @@ int load_master_data(THD* thd) 0 /* not only reset, but also reinit */, &errmsg)) { - send_error(thd, 0, "Failed purging old relay logs"); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); - return 1; + return TRUE; } pthread_mutex_lock(&active_mi->rli.data_lock); active_mi->rli.group_master_log_pos = active_mi->master_log_pos; diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index ad0219bb735..dfaacf557e8 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -38,11 +38,11 @@ int update_slave_list(MYSQL* mysql, MASTER_INFO* mi); extern HASH slave_list; -int load_master_data(THD* thd); +bool load_master_data(THD* thd); int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi); -int show_new_master(THD* thd); -int show_slave_hosts(THD* thd); +bool show_new_master(THD* thd); +bool show_slave_hosts(THD* thd); int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg); void init_slave_list(); void end_slave_list(); diff --git a/sql/set_var.cc b/sql/set_var.cc index ccac3082d5b..e5f3e17d17d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -899,8 +899,8 @@ bool sys_var_str::check(THD *thd, set_var *var) return 0; if ((res=(*check_func)(thd, var)) < 0) - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, - var->value->str_value.ptr()); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), + name, var->value->str_value.ptr()); return res; } @@ -1537,8 +1537,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (var_type != OPT_DEFAULT) { - net_printf(thd, ER_INCORRECT_GLOBAL_LOCAL_VAR, - name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); + my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), + name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); return 0; } /* As there was no local variable, return the global value */ @@ -1581,7 +1581,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) return tmp; } default: - net_printf(thd, ER_VAR_CANT_BE_READ, name); + my_error(ER_VAR_CANT_BE_READ, MYF(0), name); } return 0; } @@ -1967,8 +1967,8 @@ bool sys_var_character_set_server::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing \ -the global server character set or collation", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), + "character set, collation"); return 1; } return sys_var_character_set::check(thd,var); @@ -2074,8 +2074,8 @@ bool sys_var_collation_server::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing \ -the global server character set or collation", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), + "character set, collation"); return 1; } return sys_var_collation::check(thd,var); @@ -2353,7 +2353,7 @@ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) pthread_mutex_lock(&active_mi->rli.run_lock); if (active_mi->rli.slave_running) { - my_error(ER_SLAVE_MUST_STOP, MYF(0)); + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); result=1; } pthread_mutex_unlock(&active_mi->rli.run_lock); @@ -2424,8 +2424,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing " - "of the global server time zone", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone"); return 1; } #endif @@ -2703,9 +2702,6 @@ void set_var_free() length Length of variable. zero means that we should use strlen() on the variable - NOTE - We have to use net_printf() as this is called during the parsing stage - RETURN VALUES pointer pointer to variable definitions 0 Unknown variable (error message is given) @@ -2718,7 +2714,7 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - net_printf(current_thd, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); return var; } @@ -2804,9 +2800,8 @@ int set_var::check(THD *thd) { if (var->check_type(type)) { - my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, - MYF(0), - var->name); + int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; + my_error(err, MYF(0), var->name); return -1; } if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) @@ -2849,9 +2844,8 @@ int set_var::light_check(THD *thd) { if (var->check_type(type)) { - my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, - MYF(0), - var->name); + int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; + my_error(err, MYF(0), var->name); return -1; } if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)) @@ -2917,7 +2911,7 @@ int set_var_user::update(THD *thd) if (user_var_item->update()) { /* Give an error if it's not given already */ - my_error(ER_SET_CONSTANTS_ONLY, MYF(0)); + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0)); return -1; } return 0; @@ -2979,7 +2973,7 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var) err: my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value); - return 1; + return 1; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index e3c08eeca89..c6ee78ffbb2 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -399,3 +399,24 @@ character-set=latin2 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 78610219ade..37b523526ce 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -390,3 +390,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 051a2a13ab8..7cf441e899d 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -399,3 +399,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index bb2a9cb59ba..990e3819053 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -387,3 +387,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 14764d764aa..ff2f2a922ce 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -392,3 +392,24 @@ character-set=latin7 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 7c3e833c903..b9062214ecc 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -209,7 +209,7 @@ character-set=latin1 "Erreur d'écriture réseau reçue du maître", "Impossible de trouver un index FULLTEXT correspondant à cette liste de colonnes", "Impossible d'exécuter la commande car vous avez des tables verrouillées ou une transaction active", -"Variable système '%-.64' inconnue", +"Variable système '%-.64s' inconnue", "La table '%-.64s' est marquée 'crashed' et devrait être réparée", "La table '%-.64s' est marquée 'crashed' et le dernier 'repair' a échoué", "Attention: certaines tables ne supportant pas les transactions ont été changées et elles ne pourront pas être restituées", @@ -387,3 +387,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 7cda8bef089..757274bf1d5 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -400,3 +400,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 7b9bf7e967e..883bd0887c9 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -168,7 +168,7 @@ character-set=greek "You have an error in your SQL syntax", "Delayed insert thread couldn't get requested lock for table %-.64s", "Too many delayed threads in use", -"Aborted connection %ld to db: '%-.64s' user: '%-32s' (%-.64s)", +"Aborted connection %ld to db: '%-.64s' user: '%-.32s' (%-.64s)", "Got a packet bigger than 'max_allowed_packet' bytes", "Got a read error from the connection pipe", "Got an error from fcntl()", @@ -387,3 +387,24 @@ character-set=greek "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index d4e5c5c744f..e93970e7eb8 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -392,3 +392,24 @@ character-set=latin2 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index c697edb4cd7..1745c31f114 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -387,3 +387,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index e1a32f1894b..969bacc8d8f 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -391,3 +391,24 @@ character-set=ujis "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index adb08b67474..cdb67ba004c 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -387,3 +387,24 @@ character-set=euckr "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 057accd3c5b..35b5a3d464b 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -389,3 +389,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 5506d95592a..bb34b3d653c 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -389,3 +389,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 38cefd45338..e4dfb9442dd 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -392,3 +392,24 @@ character-set=latin2 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 7689db06451..4f3c73b900b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -211,7 +211,7 @@ character-set=latin1 "Erro de rede gravando no 'master'", "Não pode encontrar um índice para o texto todo que combine com a lista de colunas", "Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma transação ativa", -"Variável de sistema '%-.64' desconhecida", +"Variável de sistema '%-.64s' desconhecida", "Tabela '%-.64s' está marcada como danificada e deve ser reparada", "Tabela '%-.64s' está marcada como danificada e a última reparação (automática?) falhou", "Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas (rolled back)", @@ -389,3 +389,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index ad486367ec9..b96ddc1fe88 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -173,7 +173,7 @@ character-set=latin2 "Aveti o eroare in sintaxa RSQL", "Thread-ul pentru inserarea aminata nu a putut obtine lacatul (lock) pentru tabela %-.64s", "Prea multe threaduri aminate care sint in uz", -"Conectie terminata %ld la baza de date: '%-.64s' utilizator: '%-32s' (%-.64s)", +"Conectie terminata %ld la baza de date: '%-.64s' utilizator: '%-.32s' (%-.64s)", "Un packet mai mare decit 'max_allowed_packet' a fost primit", "Eroare la citire din cauza lui 'connection pipe'", "Eroare obtinuta de la fcntl()", @@ -392,3 +392,24 @@ character-set=latin2 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index d057ab53256..2da6cbdfc1a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -392,3 +392,24 @@ character-set=koi8r "CHECK OPTION ÄÌÑ ÎÅÏÂÎÏ×ÌÑÅÍÏÇÏ VIEW '%-.64s.%-.64s'" "ÐÒÏ×ÅÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÐÒÏ×ÁÌÉÌÁÓØ" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 6e38b1c3d11..461a4942131 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -202,7 +202,7 @@ character-set=cp1250 "Greška u slanju mrežnih paketa na glavni server u klasteru", "Ne mogu da pronaðem 'FULLTEXT' indeks koli odgovara listi kolona", "Ne mogu da izvršim datu komandu zbog toga što su tabele zakljuèane ili je transakcija u toku", -"Nepoznata sistemska promenljiva '%-.64'", +"Nepoznata sistemska promenljiva '%-.64s'", "Tabela '%-.64s' je markirana kao ošteæena i trebala bi biti popravljena", "Tabela '%-.64s' je markirana kao ošteæena, a zadnja (automatska?) popravka je bila neuspela", "Upozorenje: Neke izmenjene tabele ne podržavaju komandu 'ROLLBACK'", @@ -380,3 +380,24 @@ character-set=cp1250 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index a9667b8ba62..862ca741640 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -395,3 +395,24 @@ character-set=latin2 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 17600f336c0..64e6da34d2b 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -238,9 +238,9 @@ character-set=latin1 "No puede adicionar clave extranjera constraint", "No puede adicionar una línea hijo: falla de clave extranjera constraint", "No puede deletar una línea padre: falla de clave extranjera constraint", -"Error de coneccion a master: %-128s", -"Error executando el query en master: %-128%", -"Error de %s: %-128%", +"Error de coneccion a master: %-.128s", +"Error executando el query en master: %-.128s", +"Error de %s: %-.128s", "Equivocado uso de %s y %s", "El comando SELECT usado tiene diferente número de columnas", "No puedo ejecutar el query porque usted tiene conflicto de traba de lectura", @@ -391,3 +391,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 8b061ac0eec..bb7cd72f3df 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -101,7 +101,7 @@ character-set=latin1 "Tabellen '%-.64s' har inget index som motsvarar det angivna i CREATE INDEX. Skapa om tabellen", "Fältseparatorerna är vad som förväntades. Kontrollera mot manualen", "Man kan inte använda fast radlängd med blobs. Använd 'fields terminated by'", -"Textfilen '%' måste finnas i databasbiblioteket eller vara läsbar för alla", +"Textfilen '%.64s' måste finnas i databasbiblioteket eller vara läsbar för alla", "Filen '%-.64s' existerar redan", "Rader: %ld Bortagna: %ld Dubletter: %ld Varningar: %ld", "Rader: %ld Dubletter: %ld", @@ -200,7 +200,7 @@ character-set=latin1 "Fick fel %d vid ROLLBACK", "Fick fel %d vid FLUSH_LOGS", "Fick fel %d vid CHECKPOINT", -"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.32s', host '%-.64s' (%.-64s)", +"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.32s', host '%-.64s' (%-.64s)", "Tabellhanteraren klarar inte en binär kopiering av tabellen", "Binärloggen stängdes medan FLUSH MASTER utfördes", "Failed rebuilding the index of dumped table '%-.64s'", @@ -387,3 +387,24 @@ character-set=latin1 "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 317b2d596fa..a7b139bc2c3 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -393,3 +393,24 @@ character-set=koi8u "CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÝÏ ÎÅ ÍÏÖÅ ÂÕÔÉ ÏÎÏ×ÌÅÎÎÉÍ" "ÐÅÒÅצÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÎÅ ÐÒÏÊÛÌÁ" "Access denied; you are not the procedure/function definer of '%s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/slave.cc b/sql/slave.cc index 88dffbd8411..34785f1a18f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1150,7 +1150,7 @@ bool net_request_file(NET* net, const char* fname) } -const char *rewrite_db(const char* db) +const char *rewrite_db(const char* db, uint *new_len) { if (replicate_rewrite_db.is_empty() || !db) return db; @@ -1160,7 +1160,10 @@ const char *rewrite_db(const char* db) while ((tmp=it++)) { if (!strcmp(tmp->key, db)) + { + *new_len= strlen(tmp->val); return tmp->val; + } } return db; } @@ -1174,7 +1177,7 @@ const char *rewrite_db(const char* db) const char *print_slave_db_safe(const char* db) { - return (db ? rewrite_db(db) : ""); + return (db ? db : ""); } /* @@ -1490,7 +1493,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, packet_len= my_net_read(net); // read create table statement if (packet_len == packet_error) { - send_error(thd, ER_MASTER_NET_READ); + my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0)); DBUG_RETURN(1); } if (net->read_pos[0] == 255) // error from master @@ -1499,7 +1502,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, err_msg= (char*) net->read_pos + ((mysql->server_capabilities & CLIENT_PROTOCOL_41) ? 3+SQLSTATE_LENGTH+1 : 3); - net_printf(thd, ER_MASTER, err_msg); + my_error(ER_MASTER, MYF(0), err_msg); DBUG_RETURN(1); } thd->command = COM_TABLE_DUMP; @@ -1508,7 +1511,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, if (!(query = thd->strmake((char*) net->read_pos, packet_len))) { sql_print_error("create_table_from_dump: out of memory"); - net_printf(thd, ER_GET_ERRNO, "Out of memory"); + my_message(ER_GET_ERRNO, "Out of memory", MYF(0)); DBUG_RETURN(1); } thd->query= query; @@ -1522,7 +1525,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, /* Drop the table if 'overwrite' is true */ if (overwrite && mysql_rm_table(thd,&tables,1,0)) /* drop if exists */ { - send_error(thd); sql_print_error("create_table_from_dump: failed to drop the table"); goto err; } @@ -1549,7 +1551,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, tables.lock_type = TL_WRITE; if (!open_ltable(thd, &tables, TL_WRITE)) { - send_error(thd,0,0); // Send error from open_ltable sql_print_error("create_table_from_dump: could not open created table"); goto err; } @@ -1559,7 +1560,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, /* Copy the data file */ if (file->net_read_dump(net)) { - net_printf(thd, ER_MASTER_NET_READ); + my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0)); sql_print_error("create_table_from_dump: failed in\ handler::net_read_dump()"); goto err; @@ -1579,7 +1580,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) - net_printf(thd, ER_INDEX_REBUILD,tables.table->real_name); + my_error(ER_INDEX_REBUILD, MYF(0), tables.table->real_name); err: close_thread_tables(thd); @@ -1602,12 +1603,11 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, { if (!(mysql = mysql_init(NULL))) { - send_error(thd); // EOM DBUG_RETURN(1); } if (connect_to_master(thd, mysql, mi)) { - net_printf(thd, ER_CONNECT_TO_MASTER, mysql_error(mysql)); + my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql)); mysql_close(mysql); DBUG_RETURN(1); } @@ -1631,7 +1631,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, if (!called_connected) mysql_close(mysql); if (errmsg && thd->vio_ok()) - send_error(thd, error, errmsg); + my_message(error, errmsg, MYF(0)); DBUG_RETURN(test(error)); // Return 1 on error } @@ -2268,7 +2268,7 @@ void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a) } } -int show_master_info(THD* thd, MASTER_INFO* mi) +bool show_master_info(THD* thd, MASTER_INFO* mi) { // TODO: fix this for multi-master List<Item> field_list; @@ -2332,7 +2332,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (mi->host[0]) { @@ -2431,10 +2431,10 @@ int show_master_info(THD* thd, MASTER_INFO* mi) pthread_mutex_unlock(&mi->data_lock); if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -2829,7 +2829,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi, DBUG_ENTER("request_dump"); // TODO if big log files: Change next to int8store() - int4store(buf, (longlong) mi->master_log_pos); + int4store(buf, (ulong) mi->master_log_pos); int2store(buf + 4, binlog_flags); int4store(buf + 6, server_id); len = (uint) strlen(logname); diff --git a/sql/slave.h b/sql/slave.h index 2a9b96b75a1..34e3e20ce06 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -490,8 +490,8 @@ int fetch_master_table(THD* thd, const char* db_name, const char* table_name, void table_rule_ent_hash_to_str(String* s, HASH* h); void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a); -int show_master_info(THD* thd, MASTER_INFO* mi); -int show_binlog_info(THD* thd); +bool show_master_info(THD* thd, MASTER_INFO* mi); +bool show_binlog_info(THD* thd); /* See if the query uses any tables that should not be replicated */ int tables_ok(THD* thd, TABLE_LIST* tables); @@ -508,8 +508,8 @@ int add_table_rule(HASH* h, const char* table_spec); int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); void init_table_rule_hash(HASH* h, bool* h_inited); void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited); -const char *rewrite_db(const char* db); -const char *print_slave_db_safe(const char* db); +const char *rewrite_db(const char* db, uint *new_db_len); +const char *print_slave_db_safe(const char *db); int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code); void skip_load_data_infile(NET* net); void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...); diff --git a/sql/sp.cc b/sql/sp.cc index 96bb8a17a49..5798eedbad9 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -615,7 +615,7 @@ db_show_routine_status(THD *thd, int type, const char *wild) Item_field *field= new Item_field("mysql", "proc", used_field->field_name); if (!(used_field->field= find_field_in_tables(thd, field, &tables, - 0, TRUE, 1))) + 0, REPORT_ALL_ERRORS, 1))) { res= SP_INTERNAL_ERROR; goto err_case1; @@ -1001,7 +1001,7 @@ sp_cache_functions(THD *thd, LEX *lex) { delete newlex; thd->lex= oldlex; - net_printf(thd, ER_SP_DOES_NOT_EXIST, "FUNCTION", ls->str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", ls->str); ret= 1; break; } @@ -1163,7 +1163,7 @@ sp_change_db(THD *thd, char *name, bool no_access_check) { if ((db_length > NAME_LEN) || check_db_name(dbname)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1182,11 +1182,10 @@ sp_change_db(THD *thd, char *name, bool no_access_check) if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_printf_error(ER_DBACCESS_DENIED_ERROR, ER(ER_DBACCESS_DENIED_ERROR), - MYF(0), - thd->priv_user, - thd->priv_host, - dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1202,7 +1201,7 @@ sp_change_db(THD *thd, char *name, bool no_access_check) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 47e3952bcdd..7db79128bb8 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -134,7 +134,7 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) } case REAL_RESULT: { - double d= it->val(); + double d= it->val_real(); if (it->null_value) { @@ -148,7 +148,7 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) uint8 decimals= it->decimals; uint32 max_length= it->max_length; DBUG_PRINT("info", ("REAL_RESULT: %g", d)); - it= new Item_real(it->val()); + it= new Item_real(it->val_real()); it->decimals= decimals; it->max_length= max_length; } @@ -494,16 +494,17 @@ sp_head::execute(THD *thd) case SP_HANDLER_CONTINUE: ctx->save_variables(hf); ctx->push_hstack(ip); - // Fall through + // Fall through default: ip= hip; ret= 0; ctx->clear_handler(); ctx->in_handler= TRUE; + thd->clear_error(); continue; } } - } while (ret == 0 && !thd->killed && !thd->query_error); + } while (ret == 0 && !thd->killed); cleanup_items(thd->current_arena->free_list); thd->current_arena= old_arena; @@ -512,7 +513,7 @@ sp_head::execute(THD *thd) DBUG_PRINT("info", ("ret=%d killed=%d query_error=%d", ret, thd->killed, thd->query_error)); - if (thd->killed || thd->query_error) + if (thd->killed) ret= -1; /* If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ @@ -543,8 +544,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { // Need to use my_printf_error here, or it will not terminate the // invoking query properly. - my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0), - "FUNCTION", m_name.str, params, argcount); + my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), + "FUNCTION", m_name.str, params, argcount); DBUG_RETURN(-1); } @@ -595,8 +596,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) *resp= it; else { - my_printf_error(ER_SP_NORETURNEND, ER(ER_SP_NORETURNEND), MYF(0), - m_name.str); + my_error(ER_SP_NORETURNEND, MYF(0), m_name.str); ret= -1; } } @@ -622,8 +622,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (args->elements != params) { - net_printf(thd, ER_SP_WRONG_NO_OF_ARGS, "PROCEDURE", m_name.str, - params, args->elements); + my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE", + m_name.str, params, args->elements); DBUG_RETURN(-1); } @@ -694,13 +694,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (! ret) ret= execute(thd); - // Don't copy back OUT values if we got an error - if (ret) - { - if (thd->net.report_error) - send_error(thd, 0, NullS); - } - else if (csize > 0) + if (!ret && csize > 0) { List_iterator_fast<Item> li(*args); Item *it; @@ -898,7 +892,7 @@ sp_head::check_backpatch(THD *thd) { if (bp->lab->type == SP_LAB_REF) { - net_printf(thd, ER_SP_LILABEL_MISMATCH, "GOTO", bp->lab->name); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name); return -1; } } @@ -1791,7 +1785,7 @@ sp_instr_error::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_error::execute"); - my_error(m_errcode, MYF(0)); + my_message(m_errcode, ER(m_errcode), MYF(0)); *nextp= m_ip+1; DBUG_RETURN(-1); } diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 51a1bb2e550..609882b84c6 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -153,7 +153,8 @@ sp_cursor::pre_open(THD *thd) { if (m_isopen) { - send_error(thd, ER_SP_CURSOR_ALREADY_OPEN); + my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN), + MYF(0)); return NULL; } @@ -187,7 +188,7 @@ sp_cursor::close(THD *thd) { if (! m_isopen) { - send_error(thd, ER_SP_CURSOR_NOT_OPEN); + my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0)); return -1; } destroy(); @@ -217,12 +218,12 @@ sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars) if (! m_isopen) { - send_error(thd, ER_SP_CURSOR_NOT_OPEN); + my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0)); return -1; } if (m_current_row == NULL) { - send_error(thd, ER_SP_FETCH_NO_DATA); + my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0)); return -1; } @@ -234,7 +235,8 @@ sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars) if (fldcount >= m_prot->get_field_count()) { - send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, + ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); return -1; } s= row[fldcount]; @@ -260,7 +262,8 @@ sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars) } if (fldcount < m_prot->get_field_count()) { - send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, + ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); return -1; } m_current_row= m_current_row->next; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3e3642dd0bd..8ffba2579f3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1057,6 +1057,7 @@ ulong acl_get(const char *host, const char *ip, db_access=0; host_access= ~0; char key[ACL_KEY_LENGTH],*tmp_db,*end; acl_entry *entry; + DBUG_ENTER("acl_get"); VOID(pthread_mutex_lock(&acl_cache->lock)); end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); @@ -1070,7 +1071,8 @@ ulong acl_get(const char *host, const char *ip, { db_access=entry->access; VOID(pthread_mutex_unlock(&acl_cache->lock)); - return db_access; + DBUG_PRINT("exit", ("access: 0x%lx", db_access)); + DBUG_RETURN(db_access); } /* @@ -1122,7 +1124,8 @@ exit: acl_cache->add(entry); } VOID(pthread_mutex_unlock(&acl_cache->lock)); - return (db_access & host_access); + DBUG_PRINT("exit", ("access: 0x%lx", db_access & host_access)); + DBUG_RETURN(db_access & host_access); } /* @@ -1225,8 +1228,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, { if (!initialized) { - net_printf(thd,ER_OPTION_PREVENTS_STATEMENT, - "--skip-grant-tables"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); return(1); } if (!thd->slave_thread && @@ -1238,16 +1240,15 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && !thd->user[0]) { - send_error(thd, ER_PASSWORD_ANONYMOUS_USER); + my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER), + MYF(0)); return(1); } uint len=strlen(new_password); if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH && len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - net_printf(thd, 0, - "Password hash should be a %d-digit hexadecimal number", - SCRAMBLED_PASSWORD_CHAR_LENGTH); + my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); return -1; } return(0); @@ -1285,7 +1286,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (!(acl_user= find_acl_user(host, user))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); - send_error(thd, ER_PASSWORD_NO_MATCH); + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); DBUG_RETURN(1); } /* update loaded acl entry: */ @@ -1298,7 +1299,6 @@ bool change_password(THD *thd, const char *host, const char *user, new_password, new_password_len)) { VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */ - send_error(thd,0); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */ } @@ -1471,7 +1471,8 @@ static bool update_user_table(THD *thd, const char *host, const char *user, (byte*) table->field[0]->ptr,0, HA_READ_KEY_EXACT)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), + MYF(0)); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); @@ -1528,6 +1529,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, uint password_len= 0; char what= (revoke_grant) ? 'N' : 'Y'; DBUG_ENTER("replace_user_table"); + LEX *lex= thd->lex; safe_mutex_assert_owner(&acl_cache->lock); if (combo.password.str && combo.password.str[0]) @@ -1535,9 +1537,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH && combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - my_printf_error(ER_UNKNOWN_ERROR, - "Password hash should be a %d-digit hexadecimal number", - MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); + my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); DBUG_RETURN(-1); } password_len= combo.password.length; @@ -1600,8 +1600,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given table->field[2]->store(password, password_len, &my_charset_latin1); - else if (!rights && !revoke_grant && thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && - !thd->lex->mqh.bits) + else if (!rights && !revoke_grant && + lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !lex->mqh.bits) { DBUG_RETURN(0); } @@ -1624,7 +1624,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (table->fields >= 31) /* From 4.0.0 we have more fields */ { /* We write down SSL related ACL stuff */ - switch (thd->lex->ssl_type) { + switch (lex->ssl_type) { case SSL_TYPE_ANY: table->field[24]->store("ANY",3, &my_charset_latin1); table->field[25]->store("", 0, &my_charset_latin1); @@ -1642,15 +1642,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[25]->store("", 0, &my_charset_latin1); table->field[26]->store("", 0, &my_charset_latin1); table->field[27]->store("", 0, &my_charset_latin1); - if (thd->lex->ssl_cipher) - table->field[25]->store(thd->lex->ssl_cipher, - strlen(thd->lex->ssl_cipher), &my_charset_latin1); - if (thd->lex->x509_issuer) - table->field[26]->store(thd->lex->x509_issuer, - strlen(thd->lex->x509_issuer), &my_charset_latin1); - if (thd->lex->x509_subject) - table->field[27]->store(thd->lex->x509_subject, - strlen(thd->lex->x509_subject), &my_charset_latin1); + if (lex->ssl_cipher) + table->field[25]->store(lex->ssl_cipher, + strlen(lex->ssl_cipher), &my_charset_latin1); + if (lex->x509_issuer) + table->field[26]->store(lex->x509_issuer, + strlen(lex->x509_issuer), &my_charset_latin1); + if (lex->x509_subject) + table->field[27]->store(lex->x509_subject, + strlen(lex->x509_subject), &my_charset_latin1); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1662,7 +1662,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, break; } - USER_RESOURCES mqh= thd->lex->mqh; + USER_RESOURCES mqh= lex->mqh; if (mqh.bits & 1) table->field[28]->store((longlong) mqh.questions); if (mqh.bits & 2) @@ -1704,19 +1704,19 @@ end: if (old_row_exists) acl_update_user(combo.user.str, combo.host.str, combo.password.str, password_len, - thd->lex->ssl_type, - thd->lex->ssl_cipher, - thd->lex->x509_issuer, - thd->lex->x509_subject, - &thd->lex->mqh, + lex->ssl_type, + lex->ssl_cipher, + lex->x509_issuer, + lex->x509_subject, + &lex->mqh, rights); else acl_insert_user(combo.user.str, combo.host.str, password, password_len, - thd->lex->ssl_type, - thd->lex->ssl_cipher, - thd->lex->x509_issuer, - thd->lex->x509_subject, - &thd->lex->mqh, + lex->ssl_type, + lex->ssl_cipher, + lex->x509_issuer, + lex->x509_subject, + &lex->mqh, rights); } DBUG_RETURN(error); @@ -1747,7 +1747,7 @@ static int replace_db_table(TABLE *table, const char *db, /* Check if there is such a user in user table in memory? */ if (!find_acl_user(combo.host.str,combo.user.str)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); DBUG_RETURN(-1); } @@ -1797,7 +1797,7 @@ static int replace_db_table(TABLE *table, const char *db, goto table_error; /* purecov: deadcode */ } } - else if ((error=table->file->write_row(table->record[0]))) + else if (rights && (error=table->file->write_row(table->record[0]))) { if (error && error != HA_ERR_FOUND_DUPP_KEY) /* purecov: inspected */ goto table_error; /* purecov: deadcode */ @@ -1807,6 +1807,7 @@ static int replace_db_table(TABLE *table, const char *db, if (old_row_exists) acl_update_db(combo.user.str,combo.host.str,db,rights); else + if (rights) acl_insert_db(combo.user.str,combo.host.str,db,rights); DBUG_RETURN(0); @@ -2067,7 +2068,8 @@ static int replace_column_table(GRANT_TABLE *g_t, if (revoke_grant) { my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), - combo.user.str, combo.host.str, table_name); /* purecov: inspected */ + combo.user.str, combo.host.str, + table_name); /* purecov: inspected */ result= -1; /* purecov: inspected */ continue; /* purecov: inspected */ } @@ -2210,7 +2212,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, */ if (!find_acl_user(combo.host.str,combo.user.str)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), + MYF(0)); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } @@ -2234,7 +2237,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, { // no row, no revoke my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), combo.user.str, combo.host.str, - table_name); /* purecov: deadcode */ + table_name); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } old_row_exists = 0; @@ -2316,11 +2319,11 @@ table_error: revoke_grant Set to 1 if this is a REVOKE command RETURN - 0 ok - 1 error + FALSE ok + TRUE error */ -int mysql_table_grant(THD *thd, TABLE_LIST *table_list, +bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, List <LEX_USER> &user_list, List <LEX_COLUMN> &columns, ulong rights, bool revoke_grant) @@ -2337,12 +2340,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); /* purecov: inspected */ - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (rights & ~TABLE_ACLS) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE,MYF(0)); - DBUG_RETURN(-1); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); + DBUG_RETURN(TRUE); } if (columns.elements && !revoke_grant) @@ -2351,8 +2355,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, List_iterator <LEX_COLUMN> column_iter(columns); int res; - if ((res= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); while ((column = column_iter++)) { @@ -2364,7 +2368,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_BAD_FIELD_ERROR, MYF(0), column->column.c_ptr(), table_list->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } column_priv|= column->rights; } @@ -2379,7 +2383,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (access(buf,F_OK)) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } @@ -2412,19 +2416,19 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, */ tables[0].updating= tables[1].updating= tables[2].updating= 1; if (!tables_ok(0, tables)) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } #endif if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ - DBUG_RETURN(-1); /* purecov: deadcode */ + DBUG_RETURN(TRUE); /* purecov: deadcode */ } if (!revoke_grant) create_new_users= test_if_create_new_users(thd); - int result=0; + bool result= FALSE; rw_wrlock(&LOCK_grant); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; @@ -2436,8 +2440,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (Str->host.length > HOSTNAME_LENGTH || Str->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); - result= -1; + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); + result= TRUE; continue; } /* Create user if needed */ @@ -2447,7 +2452,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, pthread_mutex_unlock(&acl_cache->lock); if (error) { - result= -1; // Remember error + result= TRUE; // Remember error continue; // Add next user } @@ -2467,7 +2472,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), Str->user.str, Str->host.str, table_list->real_name); - result= -1; + result= TRUE; continue; } grant_table = new GRANT_TABLE (Str->host.str, db_name, @@ -2476,7 +2481,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, column_priv); if (!grant_table) // end of memory { - result= -1; /* purecov: deadcode */ + result= TRUE; /* purecov: deadcode */ continue; /* purecov: deadcode */ } my_hash_insert(&column_priv_hash,(byte*) grant_table); @@ -2521,7 +2526,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, rights, column_priv, revoke_grant)) { /* Should only happen if table is crashed */ - result= -1; /* purecov: deadcode */ + result= TRUE; /* purecov: deadcode */ } else if (tables[2].table) { @@ -2530,7 +2535,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, db_name, real_name, rights, revoke_grant))) { - result= -1; + result= TRUE; } } } @@ -2544,8 +2549,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } -int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, - ulong rights, bool revoke_grant) +bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, + ulong rights, bool revoke_grant) { List_iterator <LEX_USER> str_list (list); LEX_USER *Str; @@ -2557,7 +2562,7 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); /* purecov: tested */ - DBUG_RETURN(-1); /* purecov: tested */ + DBUG_RETURN(TRUE); /* purecov: tested */ } if (lower_case_table_names && db) @@ -2588,14 +2593,14 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, */ tables[0].updating= tables[1].updating= 1; if (!tables_ok(0, tables)) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } #endif if (simple_open_n_lock_tables(thd,tables)) { // This should never happen close_thread_tables(thd); /* purecov: deadcode */ - DBUG_RETURN(-1); /* purecov: deadcode */ + DBUG_RETURN(TRUE); /* purecov: deadcode */ } if (!revoke_grant) @@ -2612,7 +2617,8 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, if (Str->host.length > HOSTNAME_LENGTH || Str->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); result= -1; continue; } @@ -2846,7 +2852,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, for (table= tables; table && number--; table= table->next_global) { GRANT_TABLE *grant_table; - if (!(~table->grant.privilege & want_access) || table->derived) + if (!(~table->grant.privilege & want_access) || + table->derived || table->schema_table) { /* It is subquery in the FROM clause. VIEW set table->derived after @@ -2909,11 +2916,11 @@ err: command= "create view"; else if (want_access & SHOW_VIEW_ACL) command= "show create view"; - net_printf(thd,ER_TABLEACCESS_DENIED_ERROR, - command, - thd->priv_user, - thd->host_or_ip, - table ? table->real_name : "unknown"); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + table ? table->real_name : "unknown"); } DBUG_RETURN(1); } @@ -2959,21 +2966,18 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, } #endif - /* We must use my_printf_error() here! */ err: rw_unlock(&LOCK_grant); if (!show_tables) { char command[128]; get_privilege_desc(command, sizeof(command), want_access); - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - name, - table_name); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + name, + table_name); } return 1; } @@ -3020,7 +3024,6 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, rw_unlock(&LOCK_grant); return 0; - /* We must use my_printf_error() here! */ err: rw_unlock(&LOCK_grant); err2: @@ -3029,14 +3032,12 @@ err2: command= "select"; else if (want_access & INSERT_ACL) command= "insert"; - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - fields->name(), - table_name); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + fields->name(), + table_name); return 1; } @@ -3175,7 +3176,7 @@ static uint command_lengths[]= Send to client grant-like strings depicting user@host privileges */ -int mysql_show_grants(THD *thd,LEX_USER *lex_user) +bool mysql_show_grants(THD *thd,LEX_USER *lex_user) { ulong want_access; uint counter,index; @@ -3190,7 +3191,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!initialized) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!lex_user->host.str) @@ -3201,8 +3202,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (lex_user->host.length > HOSTNAME_LENGTH || lex_user->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); - DBUG_RETURN(-1); + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); + DBUG_RETURN(TRUE); } for (counter=0 ; counter < acl_users.elements ; counter++) @@ -3221,7 +3223,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) { my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } Item_string *field=new Item_string("",0,&my_charset_latin1); @@ -3233,7 +3235,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) field_list.push_back(field); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3555,7 +3557,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) if (!initialized) { - net_printf(thd,ER_OPTION_PREVENTS_STATEMENT, "--skip-grant-tables"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); DBUG_RETURN(-1); } @@ -3624,7 +3626,7 @@ ACL_USER *check_acl_user(LEX_USER *user_name, } -int mysql_drop_user(THD *thd, List <LEX_USER> &list) +bool mysql_drop_user(THD *thd, List <LEX_USER> &list) { uint counter, acl_userd; int result; @@ -3635,7 +3637,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) DBUG_ENTER("mysql_drop_user"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : 1); + DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3723,7 +3725,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) record[0]))) { tables[0].table->file->print_error(error, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } delete_dynamic_element(&acl_users, acl_userd); } @@ -3733,11 +3735,11 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_DROP_USER, MYF(0)); + my_message(ER_DROP_USER, ER(ER_DROP_USER), MYF(0)); DBUG_RETURN(result); } -int mysql_revoke_all(THD *thd, List <LEX_USER> &list) +bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) { uint counter, revoked; int result; @@ -3746,7 +3748,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) DBUG_ENTER("mysql_revoke_all"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : 1); + DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3860,7 +3862,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) close_thread_tables(thd); if (result) - my_error(ER_REVOKE_GRANTS, MYF(0)); + my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); DBUG_RETURN(result); } @@ -3923,6 +3925,229 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) DBUG_RETURN (*str != '\0'); } + +void update_schema_privilege(TABLE *table, char *buff, const char* db, + const char* t_name, const char* column, + uint col_length, const char *priv, + uint priv_length, const char* is_grantable) +{ + int i= 2; + CHARSET_INFO *cs= system_charset_info; + restore_record(table, default_values); + table->field[0]->store(buff, strlen(buff), cs); + if (db) + table->field[i++]->store(db, strlen(db), cs); + if (t_name) + table->field[i++]->store(t_name, strlen(t_name), cs); + if (column) + table->field[i++]->store(column, col_length, cs); + table->field[i++]->store(priv, priv_length, cs); + table->field[i]->store(is_grantable, strlen(is_grantable), cs); + table->file->write_row(table->record[0]); +} + + +int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint counter; + ACL_USER *acl_user; + ulong want_access; + + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_user_privileges"); + for (counter=0 ; counter < acl_users.elements ; counter++) + { + const char *user,*host, *is_grantable="YES"; + acl_user=dynamic_element(&acl_users,counter,ACL_USER*); + if (!(user=acl_user->user)) + user= ""; + if (!(host=acl_user->host.hostname)) + host= ""; + want_access= acl_user->access; + if (!(want_access & GRANT_ACL)) + is_grantable= "NO"; + + strxmov(buff,"'",user,"'@'",host,"'",NullS); + if (!(want_access & ~GRANT_ACL)) + update_schema_privilege(table, buff, 0, 0, 0, 0, "USAGE", 5, is_grantable); + else + { + uint priv_id; + ulong j,test_access= want_access & ~GRANT_ACL; + for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1) + { + if (test_access & j) + update_schema_privilege(table, buff, 0, 0, 0, 0, + command_array[priv_id], + command_lengths[priv_id], is_grantable); + } + } + } + DBUG_RETURN(0); +#else + return(0); +#endif +} + + +int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint counter; + ACL_DB *acl_db; + ulong want_access; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_schema_privileges"); + + for (counter=0 ; counter < acl_dbs.elements ; counter++) + { + const char *user, *host, *is_grantable="YES"; + + acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); + if (!(user=acl_db->user)) + user= ""; + if (!(host=acl_db->host.hostname)) + host= ""; + + want_access=acl_db->access; + if (want_access) + { + if (!(want_access & GRANT_ACL)) + { + is_grantable= "NO"; + } + strxmov(buff,"'",user,"'@'",host,"'",NullS); + if (!(want_access & ~GRANT_ACL)) + update_schema_privilege(table, buff, acl_db->db, 0, 0, + 0, "USAGE", 5, is_grantable); + else + { + int cnt; + ulong j,test_access= want_access & ~GRANT_ACL; + for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) + if (test_access & j) + update_schema_privilege(table, buff, acl_db->db, 0, 0, 0, + command_array[cnt], command_lengths[cnt], + is_grantable); + } + } + } + DBUG_RETURN(0); +#else + return (0); +#endif +} + + +int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint index; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_privileges"); + + for (index=0 ; index < column_priv_hash.records ; index++) + { + const char *user, *is_grantable= "YES"; + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, + index); + if (!(user=grant_table->user)) + user= ""; + ulong table_access= grant_table->privs; + if (table_access != 0) + { + ulong test_access= table_access & ~GRANT_ACL; + if (!(table_access & GRANT_ACL)) + is_grantable= "NO"; + + strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + if (!test_access) + update_schema_privilege(table, buff, grant_table->db, grant_table->tname, + 0, 0, "USAGE", 5, is_grantable); + else + { + ulong j; + int cnt; + for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) + { + if (test_access & j) + update_schema_privilege(table, buff, grant_table->db, + grant_table->tname, 0, 0, command_array[cnt], + command_lengths[cnt], is_grantable); + } + } + } + } + DBUG_RETURN(0); +#else + return (0); +#endif +} + + +int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint index; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_privileges"); + + for (index=0 ; index < column_priv_hash.records ; index++) + { + const char *user, *is_grantable= "YES"; + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, + index); + if (!(user=grant_table->user)) + user= ""; + ulong table_access= grant_table->cols; + if (table_access != 0) + { + if (!(grant_table->privs & GRANT_ACL)) + is_grantable= "NO"; + + ulong test_access= table_access & ~GRANT_ACL; + strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + if (!test_access) + continue; + else + { + ulong j; + int cnt; + for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) + { + if (test_access & j) + { + for (uint col_index=0 ; + col_index < grant_table->hash_columns.records ; + col_index++) + { + GRANT_COLUMN *grant_column = (GRANT_COLUMN*) + hash_element(&grant_table->hash_columns,col_index); + if ((grant_column->rights & j) && (table_access & j)) + update_schema_privilege(table, buff, grant_table->db, + grant_table->tname, + grant_column->column, + grant_column->key_length, + command_array[cnt], + command_lengths[cnt], is_grantable); + } + } + } + } + } + } + DBUG_RETURN(0); +#else + return (0); +#endif +} + + #ifndef NO_EMBEDDED_ACCESS_CHECKS /* fill effective privileges for table diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 390106c1546..f6074da5279 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -158,11 +158,11 @@ bool check_change_password(THD *thd, const char *host, const char *user, char *password); bool change_password(THD *thd, const char *host, const char *user, char *password); -int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, - ulong rights, bool revoke); -int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list, - List <LEX_COLUMN> &column_list, ulong rights, - bool revoke); +bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, + ulong rights, bool revoke); +bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list, + List <LEX_COLUMN> &column_list, ulong rights, + bool revoke); my_bool grant_init(THD *thd); void grant_free(void); void grant_reload(THD *thd); @@ -179,11 +179,11 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table); ulong get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name); -int mysql_show_grants(THD *thd, LEX_USER *user); +bool mysql_show_grants(THD *thd, LEX_USER *user); void get_privilege_desc(char *to, uint max_length, ulong access); void get_mqh(const char *user, const char *host, USER_CONN *uc); -int mysql_drop_user(THD *thd, List <LEX_USER> &list); -int mysql_revoke_all(THD *thd, List <LEX_USER> &list); +bool mysql_drop_user(THD *thd, List <LEX_USER> &list); +bool mysql_revoke_all(THD *thd, List <LEX_USER> &list); void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 1e0aebbc1ec..2259d3bead8 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -78,7 +78,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, { // first parameter if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -93,7 +93,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, } // second parameter if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -102,7 +102,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, pc->max_treemem = (uint) (*param->item)->val_int(); } else if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -364,7 +364,7 @@ void field_str::add() void field_real::add() { char buff[MAX_FIELD_WIDTH], *ptr, *end; - double num = item->val(); + double num= item->val_real(); uint length, zero_count, decs; TREE_ELEMENT *element; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4fae481e5f2..629216249cd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -370,7 +370,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, Put all normal tables used by thread in free list. */ -void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) +void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived, + TABLE *stopper) { bool found_old_table; DBUG_ENTER("close_thread_tables"); @@ -408,7 +409,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables)); found_old_table= 0; - while (thd->open_tables) + while (thd->open_tables != stopper) found_old_table|=close_thread_table(thd, &thd->open_tables); thd->some_tables_deleted=0; @@ -582,6 +583,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, if ((!strcmp(table->db, db_name) && !strcmp(table->real_name, table_name)) || (table->view && + table->table->table_cache_key && // it is not temporary table !my_strcasecmp(table_alias_charset, table->table->table_cache_key, db_name) && !my_strcasecmp(table_alias_charset, @@ -626,6 +628,9 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) TABLE_LIST *res; const char *d_name= table->db, *t_name= table->real_name; char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; + /* temporary table is always unique */ + if (table->table && table->table->tmp_table != NO_TMP_TABLE) + return 0; if (table->view) { /* it is view and table opened */ @@ -643,11 +648,6 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) d_name= table->table->table_cache_key; t_name= table->table->table_name; } - if (d_name == 0) - { - /* it's temporary table => always unique */ - return 0; - } } DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); @@ -892,8 +892,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, { if (table->query_id == thd->query_id) { - my_printf_error(ER_CANT_REOPEN_TABLE, - ER(ER_CANT_REOPEN_TABLE), MYF(0), table->table_name); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->table_name); DBUG_RETURN(0); } table->query_id= thd->query_id; @@ -950,7 +949,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_unlock(&LOCK_open)); } } - my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias); + my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); DBUG_RETURN(0); } @@ -1263,7 +1262,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh) next=table->next; if (!tables || (!db_stat && reopen_table(table,1))) { - my_error(ER_CANT_REOPEN_TABLE,MYF(0),table->table_name); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->table_name); VOID(hash_delete(&open_cache,(byte*) table)); error=1; } @@ -1657,6 +1656,12 @@ int open_tables(THD *thd, TABLE_LIST *start, uint *counter) */ if (tables->derived) continue; + if (tables->schema_table) + { + if (!mysql_schema_table(thd, thd->lex, tables)) + continue; + DBUG_RETURN(-1); + } (*counter)++; if (!tables->table && !(tables->table= open_table(thd, tables, &new_frm_mem, &refresh))) @@ -1741,9 +1746,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) { - my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, - ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), - MYF(0),table->table_name); + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->table_name); DBUG_RETURN(1); } if ((error=table->file->start_stmt(thd))) @@ -1854,15 +1857,14 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) tables - list of tables for open&locking RETURN - 0 - ok - -1 - error - 1 - error reported to user + FALSE - ok + TRUE - error NOTE The lock will automaticly be freed by close_thread_tables() */ -int open_and_lock_tables(THD *thd, TABLE_LIST *tables) +bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("open_and_lock_tables"); uint counter; @@ -1871,7 +1873,7 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) mysql_handle_derived(thd->lex, &mysql_derived_prepare) || (thd->fill_derived_tables() && mysql_handle_derived(thd->lex, &mysql_derived_filling))) - DBUG_RETURN(thd->net.report_error ? -1 : 1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ relink_tables_for_multidelete(thd); DBUG_RETURN(0); } @@ -2046,8 +2048,8 @@ bool rm_temporary_table(enum db_type base, char *path) ******************************************************************************/ /* Special Field pointers for find_field_in_tables returning */ -const Field *not_found_field= (Field*) 0x1; -const Field *view_ref_found= (Field*) 0x2; +Field *not_found_field= (Field*) 0x1; +Field *view_ref_found= (Field*) 0x2; #define WRONG_GRANT (Field*) -1 @@ -2225,25 +2227,32 @@ Field *find_field_in_real_table(THD *thd, TABLE *table, find_field_in_tables() thd Pointer to current thread structure item Field item that should be found - tables Tables for scanning - ref if view field is found, pointer to view item will - be returned via this parameter - report_error If FALSE then do not report error if item not found - and return not_found_field + tables Tables to be searched for item + ref If 'item' is resolved to a view field, ref is set to + point to the found view field + report_error Degree of error reporting: + - IGNORE_ERRORS then do not report any error + - IGNORE_EXCEPT_NON_UNIQUE report only non-unique + fields, suppress all other errors + - REPORT_EXCEPT_NON_UNIQUE report all other errors + except when non-unique fields were found + - REPORT_ALL_ERRORS check_privileges need to check privileges RETURN VALUES - 0 Field is not found or field is not unique- error - message is reported - not_found_field Function was called with report_error == FALSE and - field was not found. no error message reported. - view_ref_found view field is found, item passed through ref parameter - found field + 0 If error: the found field is not unique, or there are + no sufficient access priviliges for the found field, + or the field is qualified with non-existing table. + not_found_field The function was called with report_error == + (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a + field was not found. + view_ref_found View field is found, item passed through ref parameter + found field If a item was resolved to some field */ Field * find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, - Item **ref, bool report_error, + Item **ref, find_item_error_report_type report_error, bool check_privileges) { Field *found=0; @@ -2261,8 +2270,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, TABLE_LIST *tables is not changed during query execution (which is true for all queries except RENAME but luckily RENAME doesn't use fields...) so we can rely on reusing pointer to its member. - With this optimisation we also miss case when addition of one more - field makes some prepared query ambiguous and so erronous, but we + With this optimization we also miss case when addition of one more + field makes some prepared query ambiguous and so erroneous, but we accept this trade off. */ found= find_field_in_real_table(thd, item->cached_table->table, @@ -2283,7 +2292,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, if (db && lower_case_table_names) { /* - convert database to lower case for comparision. + convert database to lower case for comparison. We can't do this in Item_field as this would change the 'name' of the item which may be used in the select list */ @@ -2320,8 +2329,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return find; if (found) { - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == IGNORE_EXCEPT_NON_UNIQUE) + my_error(ER_NON_UNIQ_ERROR, MYF(0), + item->full_name(),thd->where); return (Field*) 0; } found=find; @@ -2330,7 +2341,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, } if (found) return found; - if (!found_table && report_error) + if (!found_table && (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE)) { char buff[NAME_LEN*2+1]; if (db && db[0]) @@ -2338,30 +2350,29 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); table_name=buff; } - if (report_error) - { - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - table_name, thd->where); - } + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) + my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where); else return (Field*) not_found_field; } else - if (report_error) - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(),thd->where); else return (Field*) not_found_field; return (Field*) 0; } + bool allow_rowid= tables && !tables->next_local; // Only one table for (; tables ; tables= tables->next_local) { if (!tables->table) { - if (report_error) - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(),thd->where); return (Field*) not_found_field; } @@ -2384,8 +2395,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (!thd->where) // Returns first found break; - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - name,thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == IGNORE_EXCEPT_NON_UNIQUE) + my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where); return (Field*) 0; } found=field; @@ -2393,9 +2405,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, } if (found) return found; - if (report_error) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), - MYF(0), item->full_name(), thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where); else return (Field*) not_found_field; return (Field*) 0; @@ -2432,8 +2444,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, found field */ -// Special Item pointer for find_item_in_list returning -const Item **not_found_item= (const Item**) 0x1; +/* Special Item pointer to serve as a return value from find_item_in_list(). */ +Item **not_found_item= (Item**) 0x1; Item ** @@ -2507,8 +2519,8 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, unaliased names only and will have duplicate error anyway. */ if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item**) 0; } found_unaliased= li.ref(); @@ -2532,8 +2544,8 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, if ((*found)->eq(item, 0)) continue; // Same field twice if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item**) 0; } found= li.ref(); @@ -2576,8 +2588,8 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, if (found_unaliased_non_uniq) { if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), MYF(0), - find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item **) 0; } if (found_unaliased) @@ -2592,8 +2604,8 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, if (report_error != REPORT_EXCEPT_NOT_FOUND) { if (report_error == REPORT_ALL_ERRORS) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - find->full_name(), current_thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item **) 0; } else @@ -2678,9 +2690,9 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, ** Check that all given fields exists and fill struct with current data ****************************************************************************/ -int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, - List<Item> &fields, bool set_query_id, - List<Item> *sum_func_list, bool allow_sum_func) +bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, + List<Item> &fields, bool set_query_id, + List<Item> *sum_func_list, bool allow_sum_func) { reg2 Item *item; List_iterator<Item> it(fields); @@ -2698,7 +2710,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, (item= *(it.ref()))->check_cols(1)) { select_lex->no_wrap_view_item= 0; - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (ref) *(ref++)= item; @@ -2806,8 +2818,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, (pos= find_type(&table->keynames, name->ptr(), name->length(), 1)) <= 0) { - my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), - table->real_name); + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), + name->c_ptr(), table->real_name); map->set_all(); return 1; } @@ -2830,7 +2842,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, any_privileges 0 If we should ensure that we have SELECT privileges for all columns 1 If any privilege is ok - allocate_view_names if true view names will be copied to current Item_arena memory (made for SP/PS) + allocate_view_names if true view names will be copied to current Item_arena + memory (made for SP/PS) RETURN 0 ok 'it' is updated to point at last inserted @@ -2889,7 +2902,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, &view_iter)) goto err; } - else + else if (!tables->schema_table) { table_iter.set(tables); if (check_grant_all_columns(thd, SELECT_ACL, &table->grant, @@ -2969,21 +2982,20 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, db= tables->db; tab= tables->real_name; } - if (!(fld->have_privileges= (get_column_grant(thd, + if (!tables->schema_table && + !(fld->have_privileges= (get_column_grant(thd, &table->grant, db, tab, fld->field_name) & VIEW_ANY_ACL))) { - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - fld->field_name, - tab); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "ANY", + thd->priv_user, + thd->host_or_ip, + fld->field_name, + tab); goto err; } } @@ -3022,7 +3034,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, DBUG_RETURN(0); if (!table_name) - my_error(ER_NO_TABLES_USED, MYF(0)); + my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); else my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name); @@ -3041,6 +3053,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) SELECT_LEX *select_lex= thd->lex->current_select; Item_arena *arena= thd->current_arena, backup; bool save_wrapper= thd->lex->current_select->no_wrap_view_item; + TABLE_LIST *table= NULL; // For HP compilers DBUG_ENTER("setup_conds"); if (select_lex->conds_processed_with_permanent_arena || @@ -3060,7 +3073,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } /* Check if we are using outer joins */ - for (TABLE_LIST *table= tables; table; table= table->next_local) + for (table= tables; table; table= table->next_local) { TABLE_LIST *embedded; TABLE_LIST *embedding= table; @@ -3245,8 +3258,25 @@ err_no_arena: ** Returns : 1 if some field has wrong type ******************************************************************************/ -int -fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors) + +/* + Fill fields with given items. + + SYNOPSIS + fill_record() + thd thread handler + fields Item_fields list to be filled + values values to fill with + ignore_errors TRUE if we should ignore errors + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record(THD * thd, List<Item> &fields, List<Item> &values, + bool ignore_errors) { List_iterator_fast<Item> f(fields),v(values); Item *value; @@ -3261,14 +3291,32 @@ fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors) if (rfield == table->next_number_field) table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) - DBUG_RETURN(1); + { + my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); + DBUG_RETURN(TRUE); + } } - DBUG_RETURN(0); + DBUG_RETURN(thd->net.report_error); } -int -fill_record(Field **ptr,List<Item> &values, bool ignore_errors) +/* + Fill field buffer with values from Field list + + SYNOPSIS + fill_record() + thd thread handler + ptr pointer on pointer to record + values list of fields + ignore_errors TRUE if we should ignore errors + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors) { List_iterator_fast<Item> v(values); Item *value; @@ -3282,9 +3330,12 @@ fill_record(Field **ptr,List<Item> &values, bool ignore_errors) if (field == table->next_number_field) table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(field, 0) < 0) && !ignore_errors) - DBUG_RETURN(1); + { + my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); + DBUG_RETURN(TRUE); + } } - DBUG_RETURN(0); + DBUG_RETURN(thd->net.report_error); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 15e1cc7e212..e69c0f52c93 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -702,7 +702,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) if (!new_table) { my_error(EE_OUTOFMEMORY, MYF(ME_BELL), - ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); + ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); killed= KILL_CONNECTION; return 0; } @@ -821,7 +821,7 @@ select_result::select_result() void select_result::send_error(uint errcode,const char *err) { - ::send_error(thd, errcode, err); + my_message(errcode, err, MYF(0)); } @@ -925,7 +925,7 @@ bool select_send::send_eof() void select_to_file::send_error(uint errcode,const char *err) { - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); if (file > 0) { (void) end_io_cache(&cache); @@ -1249,7 +1249,7 @@ bool select_dump::send_data(List<Item> &items) } if (row_count++ > 1) { - my_error(ER_TOO_MANY_ROWS, MYF(0)); + my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); goto err; } while ((item=li++)) @@ -1262,7 +1262,7 @@ bool select_dump::send_data(List<Item> &items) } else if (my_b_write(&cache,(byte*) res->ptr(),res->length())) { - my_error(ER_ERROR_ON_WRITE,MYF(0), path, my_errno); + my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno); goto err; } } @@ -1345,7 +1345,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items) bool select_max_min_finder_subselect::cmp_real() { Item *maxmin= ((Item_singlerow_subselect *)item)->el(0); - double val1= cache->val(), val2= maxmin->val(); + double val1= cache->val_real(), val2= maxmin->val_real(); if (fmax) return (cache->null_value && !maxmin->null_value) || (!cache->null_value && !maxmin->null_value && @@ -1421,7 +1421,8 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) if (var_list.elements != list.elements) { - my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); + my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, + ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0)); return 1; } while ((item=li++)) @@ -1722,7 +1723,7 @@ bool select_dumpvar::send_data(List<Item> &items) } if (row_count++) { - my_error(ER_TOO_MANY_ROWS, MYF(0)); + my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); DBUG_RETURN(1); } while ((zz=my_li++) && (item=it++)) diff --git a/sql/sql_class.h b/sql/sql_class.h index f820f8b9cb9..41a560d41cf 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -41,6 +41,7 @@ enum enum_check_fields { CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, CHECK_FIELD_ERROR_FOR_NULL }; extern char internal_table_name[2]; +extern const char **errmesg; /* log info errors */ #define LOG_INFO_EOF -1 @@ -153,7 +154,7 @@ public: DBUG_VOID_RETURN; } void set_max_size(ulong max_size_arg); - void signal_update() { pthread_cond_broadcast(&update_cond);} + void signal_update(); void wait_for_update(THD* thd, bool master_or_slave); void set_need_start_event() { need_start_event = 1; } void init(enum_log_type log_type_arg, @@ -1157,6 +1158,7 @@ public: net.last_error[0]= 0; net.last_errno= 0; net.report_error= 0; + query_error= 0; } inline bool vio_ok() const { return net.vio != 0; } #else @@ -1209,7 +1211,8 @@ public: } inline void send_kill_message() const { - my_error(killed_errno(), MYF(0)); + int err= killed_errno(); + my_message(err, ER(err), MYF(0)); } /* return TRUE if we will abort query if we make a warning now */ inline bool really_abort_on_warning() @@ -1251,8 +1254,6 @@ public: class JOIN; -void send_error(THD *thd, uint sql_errno=0, const char *err=0); - class select_result :public Sql_alloc { protected: THD *thd; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7a100d05b93..ad4887146d8 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -31,11 +31,6 @@ const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -const char *known_exts[]= -{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db", ".ibd", NullS}; -static TYPELIB known_extentions= -{array_elements(known_exts)-1,"known_exts", known_exts, NULL}; - static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level); @@ -379,13 +374,13 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) In this case the entry should not be logged. RETURN VALUES - 0 ok - -1 Error + FALSE ok + TRUE Error */ -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, - bool silent) +bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, + bool silent) { char path[FN_REFLEN+16]; long result= 1; @@ -413,7 +408,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { - my_error(ER_DB_CREATE_EXISTS,MYF(0),db); + my_error(ER_DB_CREATE_EXISTS, MYF(0), db); error= -1; goto exit; } @@ -423,12 +418,12 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (my_errno != ENOENT) { - my_error(EE_STAT, MYF(0),path,my_errno); + my_error(EE_STAT, MYF(0), path, my_errno); goto exit; } if (my_mkdir(path,0777,MYF(0)) < 0) { - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno); error= -1; goto exit; } @@ -489,7 +484,7 @@ exit2: /* db-name is already validated when we come here */ -int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) +bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { char path[FN_REFLEN+16]; long result=1; @@ -532,7 +527,7 @@ exit: start_waiting_global_read_lock(thd); exit2: VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); - DBUG_RETURN(error ? -1 : 0); /* -1 to delegate send_error() */ + DBUG_RETURN(error); } @@ -548,11 +543,11 @@ exit2: silent Don't generate errors RETURN - 0 ok (Database dropped) - -1 Error generated + FALSE ok (Database dropped) + ERROR Error */ -int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) +bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { long deleted=0; int error= 0; @@ -582,7 +577,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (!if_exists) { error= -1; - my_error(ER_DB_DROP_EXISTS,MYF(0),db); + my_error(ER_DB_DROP_EXISTS, MYF(0), db); goto exit; } else @@ -755,7 +750,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, extension= fn_ext(file->name); if (find_type(extension, &deletable_extentions,1+2) <= 0) { - if (find_type(extension, &known_extentions,1+2) <= 0) + if (find_type(extension, ha_known_exts(),1+2) <= 0) found_other_files++; continue; } @@ -990,12 +985,13 @@ bool mysql_change_db(THD *thd, const char *name) if (!dbname || !(db_length= strlen(dbname))) { x_free(dbname); /* purecov: inspected */ - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (check_db_name(dbname)) { - net_printf(thd, ER_WRONG_DB_NAME, dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1008,10 +1004,10 @@ bool mysql_change_db(THD *thd, const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1026,7 +1022,7 @@ bool mysql_change_db(THD *thd, const char *name) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - net_printf(thd,ER_BAD_DB_ERROR,dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8bdf19195f3..e764e957a16 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -29,8 +29,8 @@ #include "sp_head.h" #include "sql_trigger.h" -int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, - ha_rows limit, ulong options) +bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, + SQL_LIST *order, ha_rows limit, ulong options) { int error; TABLE *table; @@ -39,32 +39,39 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, bool using_limit=limit != HA_POS_ERROR; bool transactional_table, log_delayed, safe_update, const_cond; ha_rows deleted; + SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_delete"); - if ((error= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(error); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; table->map=1; - if ((error= mysql_prepare_delete(thd, table_list, &conds))) - DBUG_RETURN(error); + if (mysql_prepare_delete(thd, table_list, &conds)) + DBUG_RETURN(TRUE); const_cond= (!conds || conds->const_item()); safe_update=test(thd->options & OPTION_SAFE_UPDATES); if (safe_update && const_cond) { - send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); - DBUG_RETURN(1); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); + DBUG_RETURN(TRUE); } if (thd->lex->duplicates == DUP_IGNORE) - thd->lex->select_lex.no_error= 1; + select_lex->no_error= 1; - /* Test if the user wants to delete all rows */ + /* + Test if the user wants to delete all rows and deletion doesn't have + any side-effects (because of triggers), so we can use optimized + handler::delete_all_rows() method. + */ if (!using_limit && const_cond && (!conds || conds->val_int()) && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) + !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && + !(table->triggers && table->triggers->has_delete_triggers())) { deleted= table->file->records; if (!(error=table->file->delete_all_rows())) @@ -85,11 +92,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, table->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table,0,0,conds,&error); if (error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if ((select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; send_ok(thd,0L); DBUG_RETURN(0); // Nothing to delete @@ -102,9 +109,10 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (safe_update && !using_limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); - send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); - DBUG_RETURN(1); + free_underlaid_joins(thd, select_lex); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); + DBUG_RETURN(TRUE); } } if (options & OPTION_QUICK) @@ -124,8 +132,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (thd->lex->select_lex.setup_ref_array(thd, order->elements) || - setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, + if (select_lex->setup_ref_array(thd, order->elements) || + setup_order(thd, select_lex->ref_pointer_array, &tables, fields, all_fields, (ORDER*) order->first) || !(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) || (table->sort.found_records = filesort(thd, table, sortorder, length, @@ -134,8 +142,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, == HA_POS_ERROR) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); // This will force out message + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); } /* Filesort has already found and selected the rows we want to delete, @@ -149,12 +157,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (select && select->quick && select->quick->reset()) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); // This will force out message + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); } init_read_record(&info,thd,table,select,1,1); deleted=0L; - init_ftfuncs(thd, &thd->lex->select_lex, 1); + init_ftfuncs(thd, select_lex, 1); thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed && !thd->net.report_error) @@ -252,16 +260,14 @@ cleanup: mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); - if (error >= 0 || thd->net.report_error) - send_error(thd,thd->killed_errno()); - else + free_underlaid_joins(thd, select_lex); + if (error < 0) { thd->row_count_func= deleted; send_ok(thd,deleted); DBUG_PRINT("info",("%d records deleted",deleted)); } - DBUG_RETURN(0); + DBUG_RETURN(error >= 0 || thd->net.report_error); } @@ -275,11 +281,10 @@ cleanup: conds - conditions RETURN VALUE - 0 - OK - 1 - error (message is sent to user) - -1 - error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) +bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) { SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_delete"); @@ -287,19 +292,19 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) if (setup_tables(thd, table_list, conds) || setup_conds(thd, table_list, conds) || setup_ftfuncs(select_lex)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (unique_table(table_list, table_list->next_global)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -323,16 +328,15 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b) thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_multi_delete_prepare(THD *thd) +bool mysql_multi_delete_prepare(THD *thd) { LEX *lex= thd->lex; TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxilliary_table_list.first; TABLE_LIST *target_tbl; - int res= 0; DBUG_ENTER("mysql_multi_delete_prepare"); /* @@ -342,7 +346,7 @@ int mysql_multi_delete_prepare(THD *thd) lex->query_tables also point on local list of DELETE SELECT_LEX */ if (setup_tables(thd, lex->query_tables, &lex->select_lex.where)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Fix tables-to-be-deleted-from list to point at opened tables */ for (target_tbl= (TABLE_LIST*) aux_tables; @@ -353,9 +357,9 @@ int mysql_multi_delete_prepare(THD *thd) if (!target_tbl->correspondent_table->updatable || check_key_in_view(thd, target_tbl->correspondent_table)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), target_tbl->real_name, - "DELETE"); - DBUG_RETURN(-1); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + target_tbl->real_name, "DELETE"); + DBUG_RETURN(TRUE); } /* Check are deleted table used somewhere inside subqueries. @@ -373,12 +377,11 @@ int mysql_multi_delete_prepare(THD *thd) { my_error(ER_UPDATE_TABLE_USED, MYF(0), target_tbl->correspondent_table->real_name); - res= -1; - break; + DBUG_RETURN(TRUE); } } } - DBUG_RETURN(res); + DBUG_RETURN(FALSE); } @@ -524,7 +527,7 @@ void multi_delete::send_error(uint errcode,const char *err) DBUG_ENTER("multi_delete::send_error"); /* First send error what ever it is ... */ - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); /* If nothing deleted return */ if (!deleted) @@ -670,9 +673,7 @@ bool multi_delete::send_eof() if (ha_autocommit_or_rollback(thd,local_error > 0)) local_error=1; - if (local_error) - ::send_error(thd); - else + if (!local_error) { thd->row_count_func= deleted; ::send_ok(thd, deleted); @@ -697,12 +698,12 @@ bool multi_delete::send_eof() - If we want to have a name lock on the table on exit without errors. */ -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) +bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) { HA_CREATE_INFO create_info; char path[FN_REFLEN]; TABLE **table_ptr; - int error; + bool error; DBUG_ENTER("mysql_truncate"); bzero((char*) &create_info,sizeof(create_info)); @@ -738,9 +739,9 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) db_type table_type; if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN) { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, - table_list->real_name); - DBUG_RETURN(-1); + my_error(ER_NO_SUCH_TABLE, MYF(0), + table_list->db, table_list->real_name); + DBUG_RETURN(TRUE); } if (!ha_supports_generate(table_type)) { @@ -753,11 +754,11 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) DBUG_RETURN(error); } if (lock_and_wait_for_table_name(thd, table_list)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } *fn_ext(path)=0; // Remove the .frm extension - error= ha_create_table(path,&create_info,1) ? -1 : 0; + error= ha_create_table(path,&create_info,1); query_cache_invalidate3(thd, table_list, 0); end: @@ -784,5 +785,5 @@ end: unlock_table_name(thd, table_list); VOID(pthread_mutex_unlock(&LOCK_open)); } - DBUG_RETURN(error ? -1 : 0); + DBUG_RETURN(error); } diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 25a8359f3d2..3ca3bea743a 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -20,16 +20,16 @@ #include "mysql_priv.h" #include "sql_acl.h" -int mysql_do(THD *thd, List<Item> &values) +bool mysql_do(THD *thd, List<Item> &values) { List_iterator<Item> li(values); Item *value; DBUG_ENTER("mysql_do"); if (setup_fields(thd, 0, 0, values, 0, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); while ((value = li++)) value->val_int(); thd->clear_error(); // DO always is OK send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 3fbefdd37ef..adae481d608 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -183,14 +183,14 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, Takes into account the current LIMIT RETURN VALUES - 0 ok - 1 Error sending data to client + FALSE ok + TRUE Error sending data to client */ static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; static int warning_level_length[]= { 4, 7, 5, 1 }; -my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) +bool mysqld_show_warnings(THD *thd, ulong levels_to_show) { List<Item> field_list; DBUG_ENTER("mysqld_show_warnings"); @@ -201,7 +201,7 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) if (thd->protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); MYSQL_ERROR *err; SELECT_LEX *sel= &thd->lex->select_lex; @@ -225,10 +225,10 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) protocol->store((uint32) err->code); protocol->store(err->msg, strlen(err->msg), system_charset_info); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (!--limit) break; } - send_eof(thd); - DBUG_RETURN(0); + send_eof(thd); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index edb895fd24a..853b3dd37c6 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -140,11 +140,11 @@ static void mysql_ha_hash_free(TABLE_LIST *tables) error messages. RETURN - 0 ok - != 0 error + FALSE OK + TRUE Error */ -int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) +bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) { TABLE_LIST *hash_tables; char *db, *name, *alias; @@ -173,8 +173,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) { DBUG_PRINT("info",("duplicate '%s'", tables->alias)); if (! reopen) - my_printf_error(ER_NONUNIQ_TABLE, ER(ER_NONUNIQ_TABLE), - MYF(0), tables->alias); + my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias); goto err; } } @@ -198,7 +197,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER)) { if (! reopen) - my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->alias); + my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); mysql_ha_close(thd, tables); goto err; } @@ -236,11 +235,11 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) if (! reopen) send_ok(thd); DBUG_PRINT("exit",("OK")); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: DBUG_PRINT("exit",("ERROR")); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -257,11 +256,11 @@ err: will be closed. Broadcasts a COND_refresh condition. RETURN - 0 ok - != 0 error + FALSE ok + TRUE error */ -int mysql_ha_close(THD *thd, TABLE_LIST *tables) +bool mysql_ha_close(THD *thd, TABLE_LIST *tables) { TABLE_LIST *hash_tables; TABLE **table_ptr; @@ -299,15 +298,14 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables) } else { - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - tables->alias, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); DBUG_PRINT("exit",("ERROR")); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_ok(thd); DBUG_PRINT("exit", ("OK")); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -327,15 +325,15 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables) offset_limit RETURN - 0 ok - != 0 error + FALSE ok + TRUE error */ -int mysql_ha_read(THD *thd, TABLE_LIST *tables, - enum enum_ha_read_modes mode, char *keyname, - List<Item> *key_expr, - enum ha_rkey_function ha_rkey_mode, Item *cond, - ha_rows select_limit,ha_rows offset_limit) +bool mysql_ha_read(THD *thd, TABLE_LIST *tables, + enum enum_ha_read_modes mode, char *keyname, + List<Item> *key_expr, + enum ha_rkey_function ha_rkey_mode, Item *cond, + ha_rows select_limit,ha_rows offset_limit) { TABLE_LIST *hash_tables; TABLE *table; @@ -403,11 +401,9 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, strxnmov(buff, sizeof(buff), tables->db, ".", tables->real_name, NullS); else strncpy(buff, tables->alias, sizeof(buff)); - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - buff, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), buff, "HANDLER"); #else - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - tables->alias, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); #endif goto err0; } @@ -422,8 +418,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, { if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0) { - my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0), - keyname,tables->alias); + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); goto err0; } table->file->ha_index_or_rnd_end(); @@ -491,8 +486,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, KEY_PART_INFO *key_part=keyinfo->key_part; if (key_expr->elements > keyinfo->key_parts) { - my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS), - MYF(0),keyinfo->key_parts); + my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts); goto err; } List_iterator<Item> it_ke(*key_expr); @@ -512,10 +506,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, key_len+=key_part->store_length; } if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len)))) - { - send_error(thd,ER_OUTOFMEMORY); goto err; - } key_copy(key, table->record[0], table->key_info + keyno, key_len); error= table->file->index_read(table->record[0], key,key_len,ha_rkey_mode); @@ -523,7 +514,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, break; } default: - send_error(thd,ER_ILLEGAL_HA); + my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0)); goto err; } @@ -552,7 +543,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, if (item->send(thd->protocol, &buffer)) { protocol->free(); // Free used - my_error(ER_OUT_OF_RESOURCES,MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); goto err; } } @@ -564,13 +555,13 @@ ok: mysql_unlock_tables(thd,lock); send_eof(thd); DBUG_PRINT("exit",("OK")); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: mysql_unlock_tables(thd,lock); err0: DBUG_PRINT("exit",("ERROR")); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_help.cc b/sql/sql_help.cc index b3d7bebe96a..33bf4c481a2 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -88,7 +88,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables, Item_field *field= new Item_field("mysql", find_fields->table_name, find_fields->field_name); if (!(find_fields->field= find_field_in_tables(thd, field, tables, - 0, TRUE, 1))) + 0, REPORT_ALL_ERRORS, 1))) DBUG_RETURN(1); } DBUG_RETURN(0); @@ -276,7 +276,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, (iindex_relations= find_type((char*) primary_key_name, &relations->keynames, 1+2)-1)<0) { - send_error(thd,ER_CORRUPT_HELP_DB); + my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0)); DBUG_RETURN(-1); } rtopic_id= find_fields[help_relation_help_topic_id].field; @@ -607,12 +607,11 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, thd Thread handler RETURN VALUES - 0 Success - 1 Error and send_error already commited - -1 error && send_error should be issued (normal case) + FALSE Success + TRUE Error and send_error already commited */ -int mysqld_help(THD *thd, const char *mask) +bool mysqld_help(THD *thd, const char *mask) { Protocol *protocol= thd->protocol; SQL_SELECT *select; @@ -640,8 +639,8 @@ int mysqld_help(THD *thd, const char *mask) uint mlen= strlen(mask); MEM_ROOT *mem_root= thd->mem_root; - if ((res= open_and_lock_tables(thd, tables))) - goto end; + if (open_and_lock_tables(thd, tables)) + goto error; /* Init tables and fields to be usable from items @@ -650,10 +649,7 @@ int mysqld_help(THD *thd, const char *mask) setup_tables(thd, tables, 0); memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields)); if (init_fields(thd, tables, used_fields, array_elements(used_fields))) - { - res= -1; - goto end; - } + goto error; size_t i; for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++) tables[i].table->file->init_table_handle_for_HANDLER(); @@ -661,12 +657,8 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[0].table, used_fields[help_topic_name].field,&error))) - { - res= -1; - goto end; - } + goto error; - res= 1; count_topics= search_topics(thd,tables[0].table,used_fields, select,&topics_list, &name, &description, &example); @@ -678,10 +670,8 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[3].table, used_fields[help_keyword_name].field,&error))) - { - res= -1; - goto end; - } + goto error; + count_topics=search_keyword(thd,tables[3].table,used_fields,select,&key_id); delete select; count_topics= (count_topics != 1) ? 0 : @@ -697,10 +687,7 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[1].table, used_fields[help_category_name].field,&error))) - { - res= -1; - goto end; - } + goto error; count_categories= search_categories(thd, tables[1].table, used_fields, select, @@ -709,13 +696,13 @@ int mysqld_help(THD *thd, const char *mask) if (!count_categories) { if (send_header_2(protocol,FALSE)) - goto end; + goto error; } else if (count_categories > 1) { if (send_header_2(protocol,FALSE) || send_variant_2_list(mem_root,protocol,&categories_list,"Y",0)) - goto end; + goto error; } else { @@ -728,20 +715,14 @@ int mysqld_help(THD *thd, const char *mask) new Item_int((int32)category_id)); if (!(select= prepare_simple_select(thd,cond_topic_by_cat, tables,tables[0].table,&error))) - { - res= -1; - goto end; - } + goto error; get_all_items_for_category(thd,tables[0].table, used_fields[help_topic_name].field, select,&topics_list); delete select; if (!(select= prepare_simple_select(thd,cond_cat_by_cat,tables, tables[1].table,&error))) - { - res= -1; - goto end; - } + goto error; get_all_items_for_category(thd,tables[1].table, used_fields[help_category_name].field, select,&subcategories_list); @@ -750,39 +731,36 @@ int mysqld_help(THD *thd, const char *mask) if (send_header_2(protocol, TRUE) || send_variant_2_list(mem_root,protocol,&topics_list, "N",cat) || send_variant_2_list(mem_root,protocol,&subcategories_list,"Y",cat)) - goto end; + goto error; } } else if (count_topics == 1) { if (send_answer_1(protocol,&name,&description,&example)) - goto end; + goto error; } else { /* First send header and functions */ if (send_header_2(protocol, FALSE) || send_variant_2_list(mem_root,protocol, &topics_list, "N", 0)) - goto end; + goto error; if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[1].table, used_fields[help_category_name].field,&error))) - { - res= -1; - goto end; - } + goto error; search_categories(thd, tables[1].table, used_fields, select,&categories_list, 0); delete select; /* Then send categories */ if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0)) - goto end; + goto error; } - res= 0; - send_eof(thd); end: - DBUG_RETURN(res); + DBUG_RETURN(FALSE); +error: + DBUG_RETURN(TRUE); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6e0260d1acb..2fddaed5f45 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -58,9 +58,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields, { if (values.elements != table->fields) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); return -1; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -82,9 +80,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields, int res; if (fields.elements != values.elements) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); return -1; } @@ -100,7 +96,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields, if (check_unique && thd->dupp_field) { - my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name); + my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); return -1; } if (table->timestamp_field && // Don't set timestamp if used @@ -115,12 +111,12 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields, } -int mysql_insert(THD *thd,TABLE_LIST *table_list, - List<Item> &fields, - List<List_item> &values_list, - List<Item> &update_fields, - List<Item> &update_values, - enum_duplicates duplic) +bool mysql_insert(THD *thd,TABLE_LIST *table_list, + List<Item> &fields, + List<List_item> &values_list, + List<Item> &update_fields, + List<Item> &update_values, + enum_duplicates duplic) { int error, res; /* @@ -171,10 +167,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, table_list->db ? table_list->db : thd->db, table_list->real_name)) { - my_printf_error(ER_DELAYED_INSERT_TABLE_LOCKED, - ER(ER_DELAYED_INSERT_TABLE_LOCKED), - MYF(0), table_list->real_name); - DBUG_RETURN(-1); + my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0), + table_list->real_name); + DBUG_RETURN(TRUE); } } if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error) @@ -200,7 +195,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, #endif /* EMBEDDED_LIBRARY */ res= open_and_lock_tables(thd, table_list); if (res || thd->is_fatal_error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); table= table_list->table; thd->proc_info="init"; @@ -227,9 +222,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, counter++; if (values->elements != value_count) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); goto abort; } if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) @@ -291,13 +284,18 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, if (fields.elements || !value_count) { restore_record(table,default_values); // Get empty record - if (fill_record(fields, *values, 0)|| thd->net.report_error) + if (fill_record(thd, fields, *values, 0)) { if (values_list.elements != 1 && !thd->net.report_error) { info.records++; continue; } + /* + TODO: set thd->abort_on_warning if values_list.elements == 1 + and check that all items return warning in case of problem with + storing field. + */ error=1; break; } @@ -308,7 +306,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, restore_record(table,default_values); // Get empty record else table->record[0][0]=table->default_values[0]; // Fix delete marker - if (fill_record(table->field,*values, 0) || thd->net.report_error) + if (fill_record(thd, table->field, *values, 0)) { if (values_list.elements != 1 && ! thd->net.report_error) { @@ -468,7 +466,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; thd->abort_on_warning= 0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); abort: #ifndef EMBEDDED_LIBRARY @@ -478,7 +476,7 @@ abort: free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; thd->abort_on_warning= 0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -612,11 +610,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, table_list Global/local table list RETURN VALUE - 0 OK - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, List<Item> &fields, List_item *values, List<Item> &update_fields, List<Item> &update_values, enum_duplicates duplic) @@ -624,7 +622,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, bool insert_into_view= (table_list->view != 0); /* TODO: use this condition for 'WITH CHECK OPTION' */ Item *unused_conds= 0; - int res; + bool res; DBUG_ENTER("mysql_prepare_insert"); if (mysql_prepare_insert_check_table(thd, table_list, fields, &unused_conds)) @@ -639,15 +637,15 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, thd->lex->select_lex.no_wrap_view_item= 0, res) || setup_fields(thd, 0, table_list, update_values, 0, 0, 0)))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (unique_table(table_list, table_list->next_global)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } thd->lex->select_lex.first_execution= 0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -739,7 +737,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) */ store_record(table,insert_values); restore_record(table,record[1]); - if (fill_record(*info->update_fields, *info->update_values, 0)) + if (fill_record(thd, *info->update_fields, *info->update_values, 0)) goto err; /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ @@ -823,9 +821,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry) if ((*field)->query_id != thd->query_id && ((*field)->flags & NO_DEFAULT_VALUE_FLAG)) { - my_printf_error(ER_NO_DEFAULT_FOR_FIELD, - ER(ER_NO_DEFAULT_FOR_FIELD),MYF(0), - (*field)->field_name); + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), (*field)->field_name); return 1; } } @@ -1001,7 +997,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) { delete tmp; thd->fatal_error(); - my_error(ER_OUT_OF_RESOURCES,MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); pthread_mutex_unlock(&LOCK_delayed_create); DBUG_RETURN(0); } @@ -1021,7 +1017,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) delete tmp; thd->fatal_error(); pthread_mutex_unlock(&LOCK_delayed_create); - net_printf(thd,ER_CANT_CREATE_THREAD,error); + my_error(ER_CANT_CREATE_THREAD, MYF(0), error); DBUG_RETURN(0); } @@ -1649,11 +1645,11 @@ bool delayed_insert::handle_inserts(void) thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_insert_select_prepare(THD *thd) +bool mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; DBUG_ENTER("mysql_insert_select_prepare"); @@ -1665,8 +1661,8 @@ int mysql_insert_select_prepare(THD *thd) if (mysql_prepare_insert_check_table(thd, lex->query_tables, lex->field_list, &lex->select_lex.where)) - DBUG_RETURN(-1); - DBUG_RETURN(0); + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); } @@ -1742,9 +1738,9 @@ bool select_insert::send_data(List<Item> &values) DBUG_RETURN(0); } if (fields->elements) - fill_record(*fields, values, 1); + fill_record(thd, *fields, values, 1); else - fill_record(table->field, values, 1); + fill_record(thd, table->field, values, 1); switch (table_list->view_check_option(thd, thd->lex->duplicates == DUP_IGNORE)) { @@ -1769,8 +1765,7 @@ void select_insert::send_error(uint errcode,const char *err) { DBUG_ENTER("select_insert::send_error"); - /* TODO error should be sent at the query processing end */ - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); if (!table) { @@ -1846,8 +1841,6 @@ bool select_insert::send_eof() if (error) { table->file->print_error(error,MYF(0)); - //TODO error should be sent at the query processing end - ::send_error(thd); DBUG_RETURN(1); } char buff[160]; @@ -1880,9 +1873,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (table->fields < values.elements) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),1); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); DBUG_RETURN(-1); } @@ -1918,7 +1909,7 @@ bool select_create::send_data(List<Item> &values) unit->offset_limit_cnt--; return 0; } - fill_record(field, values, 1); + fill_record(thd, field, values, 1); if (thd->net.report_error || write_record(thd, table, &info)) return 1; if (table->next_number_field) // Clear for next record diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 86219abc632..b65d9465b43 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1057,6 +1057,7 @@ void st_select_lex::init_query() first_cond_optimization= 1; parsing_place= NO_MATTER; no_wrap_view_item= 0; + link_next= 0; } void st_select_lex::init_select() @@ -1308,7 +1309,7 @@ bool st_select_lex::test_limit() if (select_limit != HA_POS_ERROR) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), - "LIMIT & IN/ALL/ANY/SOME subquery"); + "LIMIT & IN/ALL/ANY/SOME subquery"); return(1); } // We need only 1 row to determinate existence diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c8b4faa47c2..ce22caa13fc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -56,7 +56,7 @@ enum enum_sql_command { SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, - SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, @@ -342,8 +342,8 @@ protected: TABLE *table; /* temporary table using for appending UNION results */ select_result *result; - int res; ulong found_rows_for_union; + bool res; bool prepared, // prepare phase already performed for UNION (unit) optimized, // optimize phase already performed for UNION (unit) executed, // already executed @@ -403,9 +403,9 @@ public: void exclude_tree(); /* UNION methods */ - int prepare(THD *thd, select_result *result, ulong additional_options); - int exec(); - int cleanup(); + bool prepare(THD *thd, select_result *result, ulong additional_options); + bool exec(); + bool cleanup(); inline void unclean() { cleaned= 0; } void reinit_exec_mechanism(); @@ -413,7 +413,7 @@ public: void print(String *str); ulong init_prepare_fake_select_lex(THD *thd); - int change_result(select_subselect *result, select_subselect *old_result); + bool change_result(select_subselect *result, select_subselect *old_result); void set_limit(st_select_lex *values, st_select_lex *sl); friend void lex_start(THD *thd, uchar *buf, uint length); @@ -692,7 +692,7 @@ typedef struct st_lex LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; ulong thread_id,type; - enum_sql_command sql_command; + enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option, multi_lock_option; enum SSL_type ssl_type; /* defined in violite.h */ enum my_lex_states next_state; @@ -706,7 +706,7 @@ typedef struct st_lex uint uint_geom_type; uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; - uint slave_thd_opt; + uint slave_thd_opt, start_transaction_opt; uint8 describe; uint8 derived_tables; uint8 create_view_algorithm; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 9c2a025e089..d9e4943f322 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -80,7 +80,7 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, String &enclosed, ulong skip_lines, bool ignore_check_option_errors); -int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, +bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, List<Item> &fields, enum enum_duplicates handle_duplicates, bool read_file_from_client,thr_lock_type lock_type, bool ignore_check_option_errors) @@ -116,17 +116,17 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } table_list->lock_type= lock_type; - if ((res= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); if (setup_tables(thd, table_list, &unused_conds)) DBUG_RETURN(-1); if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } table= table_list->table; transactional_table= table->file->has_transactions(); @@ -145,14 +145,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, Item *unused_conds= 0; if (setup_tables(thd, table_list, &unused_conds) || setup_fields(thd, 0, table_list, fields, 1, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (thd->dupp_field) { my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (check_that_all_fields_are_given_values(thd, table)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } uint tot_length=0; @@ -178,7 +178,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { my_message(ER_BLOBS_AND_NO_TERMINATED,ER(ER_BLOBS_AND_NO_TERMINATED), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* We can't give an error in the middle when using LOCAL files */ @@ -210,7 +210,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, #if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__) MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(MY_WME))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); // if we are not in slave thread, the file must be: if (!thd->slave_thread && @@ -221,15 +221,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ((stat_info.st_mode & S_IFREG) == S_IFREG || (stat_info.st_mode & S_IFIFO) == S_IFIFO))) { - my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name); - DBUG_RETURN(-1); + my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name); + DBUG_RETURN(TRUE); } if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) is_fifo = 1; #endif } if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } COPY_INFO info; @@ -244,7 +244,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { if (file >= 0) my_close(file,MYF(0)); // no files in net reading - DBUG_RETURN(-1); // Can't allocate buffers + DBUG_RETURN(TRUE); // Can't allocate buffers } #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_map.cc b/sql/sql_map.cc index e7e24f957c6..687e60b7c72 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -47,13 +47,12 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt 0L))) { error=errno; - my_printf_error(0,"Can't map file: %s, errno: %d",MYF(0), - (my_string) name,error); + my_error(ER_NO_FILE_MAPPING, MYF(0), (my_string) name, error); } } if (map && memcmp(map,magic,magic_length)) { - my_printf_error(0,"Wrong magic in %s",MYF(0),name); + my_error(ER_WRONG_MAGIC, MYF(0), name); VOID(munmap(map,size)); map=0; } @@ -112,8 +111,7 @@ mapped_files *map_file(const my_string name,byte *magic,uint magic_length) { map->use_count++; if (!map->map) - my_printf_error(0,"Can't map file: %s, error: %d",MYF(0),path, - map->error); + my_error(ER_NO_FILE_MAPPING, MYF(0), path, map->error); } VOID(pthread_mutex_unlock(&LOCK_mapped_file)); return map; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a14a3da8391..11c02dacdad 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -166,7 +166,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, my_malloc(sizeof(struct user_conn) + temp_len+1, MYF(MY_WME))))) { - send_error(thd, 0, NullS); // Out of memory + net_send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -184,7 +184,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, if (my_hash_insert(&hash_user_connections, (byte*) uc)) { my_free((char*) uc,0); - send_error(thd, 0, NullS); // Out of memory + net_send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -259,7 +259,7 @@ int check_user(THD *thd, enum enum_server_command command, */ if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) { - net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE); + net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } @@ -291,8 +291,8 @@ int check_user(THD *thd, enum enum_server_command command, NET *net= &thd->net; if (opt_secure_auth_local) { - net_printf(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, - thd->user, thd->host_or_ip); + net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, + thd->user, thd->host_or_ip); mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), thd->user, thd->host_or_ip); DBUG_RETURN(-1); @@ -331,7 +331,7 @@ int check_user(THD *thd, enum enum_server_command command, VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (!count_ok) { // too many connections - send_error(thd, ER_CON_COUNT_ERROR); + net_send_error(thd, ER_CON_COUNT_ERROR); DBUG_RETURN(-1); } } @@ -381,14 +381,14 @@ int check_user(THD *thd, enum enum_server_command command, } else if (res == 2) // client gave short hash, server has long hash { - net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE); + net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } - net_printf(thd, ER_ACCESS_DENIED_ERROR, - thd->user, - thd->host_or_ip, - passwd_len ? ER(ER_YES) : ER(ER_NO)); + net_printf_error(thd, ER_ACCESS_DENIED_ERROR, + thd->user, + thd->host_or_ip, + passwd_len ? ER(ER_YES) : ER(ER_NO)); mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), thd->user, thd->host_or_ip, @@ -451,16 +451,16 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc) if (max_user_connections && max_user_connections < (uint) uc->connections) { - net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user); + net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user); error=1; goto end; } if (uc->user_resources.connections && uc->user_resources.connections <= uc->conn_per_hour) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, - "max_connections", - (long) uc->user_resources.connections); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, + "max_connections", + (long) uc->user_resources.connections); error=1; goto end; } @@ -592,8 +592,8 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.questions && uc->questions++ >= uc->user_resources.questions) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", - (long) uc->user_resources.questions); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", + (long) uc->user_resources.questions); error=1; goto end; } @@ -603,8 +603,8 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.updates && uc_update_queries[check_command] && uc->updates++ >= uc->user_resources.updates) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", - (long) uc->user_resources.updates); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", + (long) uc->user_resources.updates); error=1; goto end; } @@ -1010,7 +1010,7 @@ pthread_handler_decl(handle_one_connection,arg) if ((error=check_connection(thd))) { // Wrong permissions if (error > 0) - net_printf(thd,error,thd->host_or_ip); + net_printf_error(thd, error, thd->host_or_ip); #ifdef __NT__ if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE) my_sleep(1000); /* must wait after eof() */ @@ -1028,6 +1028,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->version= refresh_version; thd->proc_info= 0; + thd->command= COM_SLEEP; thd->set_time(); thd->init_for_queries(); @@ -1057,7 +1058,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->host_or_ip, (net->last_errno ? ER(net->last_errno) : ER(ER_UNKNOWN_ERROR))); - send_error(thd,net->last_errno,NullS); + net_send_error(thd, net->last_errno, NullS); statistic_increment(aborted_threads,&LOCK_status); } else if (thd->killed) @@ -1126,8 +1127,8 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) uint length=(uint) strlen(buff); if (buff[length-1]!='\n' && !feof(file)) { - send_error(thd,ER_NET_PACKET_TOO_LARGE, NullS); - thd->is_fatal_error= 1; + net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS); + thd->fatal_error(); break; } while (length && (my_isspace(thd->charset(), buff[length-1]) || @@ -1204,7 +1205,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1280,7 +1281,7 @@ bool do_command(THD *thd) statistic_increment(aborted_threads,&LOCK_status); DBUG_RETURN(TRUE); // We have to close it. } - send_error(thd,net->last_errno,NullS); + net_send_error(thd, net->last_errno, NullS); net->error= 0; DBUG_RETURN(FALSE); } @@ -1383,8 +1384,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, db= thd->alloc(db_len + tbl_len + 2); tbl_name= strmake(db, packet + 1, db_len)+1; strmake(tbl_name, packet + db_len + 2, tbl_len); - if (mysql_table_dump(thd, db, tbl_name, -1)) - send_error(thd); // dump to NET + mysql_table_dump(thd, db, tbl_name, -1); break; } case COM_CHANGE_USER: @@ -1409,7 +1409,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* Small check for incoming packet */ if ((uint) ((uchar*) db - net->read_pos) > packet_length) { - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } #endif @@ -1432,7 +1432,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(thd->user= my_strdup(user, MYF(0)))) { thd->user= save_user; - send_error(thd, ER_OUT_OF_RESOURCES); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); break; } @@ -1444,7 +1444,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { /* authentication failure, we shall restore old user */ if (res > 0) - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); x_free(thd->user); thd->user= save_user; thd->priv_user= save_priv_user; @@ -1502,7 +1502,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("query",("%-.4096s",thd->query)); mysql_parse(thd,thd->query, thd->query_length); - while (!thd->killed && !thd->is_fatal_error && thd->lex->found_colon) + while (!thd->killed && thd->lex->found_colon && !thd->net.report_error) { char *packet= thd->lex->found_colon; /* @@ -1552,7 +1552,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ break; #else { @@ -1565,7 +1566,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { - send_error(thd,ER_NO_DB_ERROR); + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); break; } pend= strend(packet); @@ -1619,7 +1620,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1628,7 +1629,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero(&create_info, sizeof(create_info)); if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), &create_info, 0) < 0) - send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); + error= TRUE; break; } case COM_DROP_DB: // QQ: To be removed @@ -1639,34 +1640,35 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* null test to handle EOM */ if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); break; } mysql_log.write(thd,command,db); if (mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0) < 0) - send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); + error= TRUE; break; } #ifndef EMBEDDED_LIBRARY case COM_BINLOG_DUMP: { + ulong pos; + ushort flags; + uint32 slave_server_id; + statistic_increment(thd->status_var.com_other,&LOCK_status); thd->slow_command = TRUE; if (check_global_access(thd, REPL_SLAVE_ACL)) break; - mysql_log.write(thd,command, 0); - ulong pos; - ushort flags; - uint32 slave_server_id; /* TODO: The following has to be changed to an 8 byte integer */ pos = uint4korr(packet); flags = uint2korr(packet + 4); @@ -1674,6 +1676,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0 kill_zombie_dump_threads(slave_server_id); thd->server_id = slave_server_id; + + mysql_log.write(thd, command, "Log: '%s' Pos: %ld", packet+10, + (long) pos); mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); unregister_slave(thd,1,1); /* fake COM_QUIT -- if we get here, the thread needs to terminate */ @@ -1690,9 +1695,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_global_access(thd,RELOAD_ACL)) break; mysql_log.write(thd,command,NullS); - if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, NULL)) - send_error(thd, 0); - else + if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, NULL)) send_ok(thd); break; } @@ -1716,7 +1719,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else if (level != SHUTDOWN_WAIT_ALL_BUFFERS) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level"); - send_error(thd); break; } DBUG_PRINT("quit",("Got shutdown command for level %u", level)); @@ -1800,7 +1802,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, send_eof(thd); break; default: - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } break; @@ -1819,7 +1821,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_DELAYED_INSERT: case COM_END: default: - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } if (thd->lock || thd->open_tables || thd->derived_tables) @@ -1828,8 +1830,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, close_thread_tables(thd); /* Free tables */ } - if (thd->is_fatal_error) - send_error(thd,0); // End of memory ? + /* report error issued during command execution */ + if (thd->killed_errno() && !thd->net.report_error) + thd->send_kill_message(); + if (thd->net.report_error) + net_send_error(thd); time_t start_of_query=thd->start_time; thd->end_time(); // Set start time @@ -1864,6 +1869,111 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } +int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, + enum enum_schema_tables schema_table_idx) +{ + DBUG_ENTER("prepare_schema_table"); + SELECT_LEX *sel= 0; + switch(schema_table_idx) { + case SCH_SCHEMATA: +#if defined(DONT_ALLOW_SHOW_COMMANDS) + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ + DBUG_RETURN(1); +#else + if ((specialflag & SPECIAL_SKIP_SHOW_DB) && + check_global_access(thd, SHOW_DB_ACL)) + DBUG_RETURN(1); + break; +#endif + case SCH_TABLE_NAMES: + case SCH_TABLES: + case SCH_VIEWS: +#ifdef DONT_ALLOW_SHOW_COMMANDS + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ + DBUG_RETURN(1); +#else + { + char *db= lex->select_lex.db ? lex->select_lex.db : thd->db; + if (!db) + { + my_message(ER_NO_DB_ERROR, + ER(ER_NO_DB_ERROR), MYF(0)); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ + } + remove_escape(db); // Fix escaped '_' + if (check_db_name(db)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), db); + DBUG_RETURN(1); + } + if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) + DBUG_RETURN(1); /* purecov: inspected */ + if (!thd->col_access && check_grant_db(thd,db)) + { + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, thd->priv_host, db); + DBUG_RETURN(1); + } + lex->select_lex.db= db; + break; + } +#endif + case SCH_COLUMNS: + case SCH_STATISTICS: +#ifdef DONT_ALLOW_SHOW_COMMANDS + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ + DBUG_RETURN(1); +#else + if (table_ident) + { + TABLE_LIST **query_tables_last= lex->query_tables_last; + sel= new SELECT_LEX(); + sel->init_query(); + if(!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, + (List<String> *) 0, (List<String> *) 0)) + DBUG_RETURN(1); + lex->query_tables_last= query_tables_last; + TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first; + char *db= table_list->db; + remove_escape(db); // Fix escaped '_' + remove_escape(table_list->real_name); + if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, + &table_list->grant.privilege, 0, 0)) + DBUG_RETURN(1); /* purecov: inspected */ + if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2, + UINT_MAX, 0)) + DBUG_RETURN(1); + break; + } +#endif + case SCH_PROCEDURES: + case SCH_CHARSETS: + case SCH_COLLATIONS: + case SCH_COLLATION_CHARACTER_SET_APPLICABILITY: + case SCH_USER_PRIVILEGES: + case SCH_SCHEMA_PRIVILEGES: + case SCH_TABLE_PRIVILEGES: + case SCH_COLUMN_PRIVILEGES: + case SCH_TABLE_CONSTRAINTS: + case SCH_KEY_COLUMN_USAGE: + default: + break; + } + + SELECT_LEX *select_lex= lex->current_select; + if (make_schema_select(thd, select_lex, schema_table_idx)) + { + DBUG_RETURN(1); + } + TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first; + table_list->schema_select_lex= sel; + DBUG_RETURN(0); +} + + /* Read query from packet and store in thd->query Used in COM_QUERY and COM_PREPARE @@ -1874,8 +1984,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, query_length RETURN VALUES - 0 ok - 1 error; In this case thd->fatal_error is set + FALSE ok + TRUE error; In this case thd->fatal_error is set */ bool alloc_query(THD *thd, char *packet, ulong packet_length) @@ -1900,7 +2010,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) packet_length, thd->db_length+ 1 + QUERY_CACHE_FLAGS_SIZE))) - return 1; + return TRUE; thd->query[packet_length]=0; thd->query_length= packet_length; @@ -1910,7 +2020,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); - return 0; + return FALSE; } /**************************************************************************** @@ -1918,10 +2028,10 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) ** Execute command saved in thd and current_lex->sql_command ****************************************************************************/ -int +bool mysql_execute_command(THD *thd) { - int res= 0; + bool res= FALSE; LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ SELECT_LEX *select_lex= &lex->select_lex; @@ -1978,7 +2088,7 @@ mysql_execute_command(THD *thd) if (all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); DBUG_RETURN(0); } #ifndef TO_BE_DELETED @@ -2002,7 +2112,6 @@ mysql_execute_command(THD *thd) if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) == &fake_time_zone_tables_list) { - send_error(thd, 0); DBUG_RETURN(-1); } lex->time_zone_tables_used= tmp; @@ -2018,7 +2127,7 @@ mysql_execute_command(THD *thd) !(thd->slave_thread || (thd->master_access & SUPER_ACL)) && (uc_update_queries[lex->sql_command] > 0)) { - net_printf(thd, ER_OPTION_PREVENTS_STATEMENT, "--read-only"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); DBUG_RETURN(-1); } @@ -2047,20 +2156,14 @@ mysql_execute_command(THD *thd) lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, any_db, 0, 0, 0); if (res) - { - res=0; - break; // Error message is given - } + goto error; if (!(res= open_and_lock_tables(thd, all_tables))) { if (lex->describe) { if (!(result= new select_send())) - { - send_error(thd, ER_OUT_OF_RESOURCES); goto error; - } else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); @@ -2080,10 +2183,7 @@ mysql_execute_command(THD *thd) else { if (!result && !(result= new select_send())) - { - res= -1; - break; - } + goto error; query_cache_store_query(thd, all_tables); res= handle_select(thd, lex, result); if (result != lex->result) @@ -2124,10 +2224,7 @@ mysql_execute_command(THD *thd) */ DBUG_ASSERT(!is_var_null); if (!pstr) - { - res= -1; - break; // EOM (error should be reported by allocator) - } + goto error; } else { @@ -2145,11 +2242,8 @@ mysql_execute_command(THD *thd) query_len= need_conversion? (pstr->length() * to_cs->mbmaxlen) : pstr->length(); if (!(query_str= alloc_root(thd->mem_root, query_len+1))) - { - res= -1; - break; // EOM (error should be reported by allocator) - } - + goto error; + if (need_conversion) { uint dummy_errors; @@ -2171,8 +2265,8 @@ mysql_execute_command(THD *thd) query_len, query_str)); } thd->command= COM_PREPARE; - if (!mysql_stmt_prepare(thd, query_str, query_len + 1, - &lex->prepared_stmt_name)) + if (!(res= mysql_stmt_prepare(thd, query_str, query_len + 1, + &lex->prepared_stmt_name))) send_ok(thd, 0L, 0L, "Statement prepared"); break; } @@ -2198,22 +2292,21 @@ mysql_execute_command(THD *thd) } else { - res= -1; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - lex->prepared_stmt_name.length, lex->prepared_stmt_name.str, + lex->prepared_stmt_name.length, + lex->prepared_stmt_name.str, "DEALLOCATE PREPARE"); + goto error; } break; } case SQLCOM_DO: if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - break; + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; res= mysql_do(thd, *lex->insert_list); - if (thd->net.report_error) - res= -1; break; case SQLCOM_EMPTY_QUERY: @@ -2263,12 +2356,12 @@ mysql_execute_command(THD *thd) goto error; /* This query don't work now. See comment in repl_failsafe.cc */ #ifndef WORKING_NEW_MASTER - net_printf(thd, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); - res= 1; + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER"); + goto error; #else res = show_new_master(thd); -#endif break; +#endif } #ifdef HAVE_REPLICATION @@ -2364,7 +2457,7 @@ mysql_execute_command(THD *thd) if (check_global_access(thd, SUPER_ACL)) goto error; if (end_active_trans(thd)) - res= -1; + goto error; else res = load_master_data(thd); break; @@ -2395,7 +2488,7 @@ mysql_execute_command(THD *thd) } if (strlen(first_table->real_name) > NAME_LEN) { - net_printf(thd, ER_WRONG_TABLE_NAME, first_table->real_name); + my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->real_name); break; } pthread_mutex_lock(&LOCK_active_mi); @@ -2422,7 +2515,7 @@ mysql_execute_command(THD *thd) TABLE_LIST *select_tables= lex->query_tables; if ((res= create_table_precheck(thd, select_tables, create_table))) - goto unsent_create_error; + goto create_error; #ifndef HAVE_READLINK lex->create_info.data_file_name=lex->create_info.index_file_name=0; @@ -2432,10 +2525,7 @@ mysql_execute_command(THD *thd) create_table->real_name) || append_file_to_dir(thd, &lex->create_info.index_file_name, create_table->real_name)) - { - res=-1; - goto unsent_create_error; - } + goto create_error; #endif /* If we are using SET CHARSET without DEFAULT, add an implicit @@ -2466,7 +2556,7 @@ mysql_execute_command(THD *thd) if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && unique_table(create_table, select_tables)) { - net_printf(thd, ER_UPDATE_TABLE_USED, create_table->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->real_name); goto create_error; } /* If we create merge table, we have to test tables in merge, too */ @@ -2479,7 +2569,7 @@ mysql_execute_command(THD *thd) { if (unique_table(tab, select_tables)) { - net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), tab->real_name); goto create_error; } } @@ -2526,11 +2616,9 @@ mysql_execute_command(THD *thd) break; create_error: - res= 1; //error reported -unsent_create_error: /* put tables back for PS rexecuting */ lex->link_first_table_back(create_table, link_to_local); - break; + goto error; } case SQLCOM_CREATE_INDEX: DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -2538,7 +2626,7 @@ unsent_create_error: goto error; /* purecov: inspected */ thd->slow_command=TRUE; if (end_active_trans(thd)) - res= -1; + goto error; else res = mysql_create_index(thd, first_table, lex->key_list); break; @@ -2567,7 +2655,8 @@ unsent_create_error: */ if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), + MYF(0)); goto error; } { @@ -2581,16 +2670,16 @@ unsent_create_error: case SQLCOM_ALTER_TABLE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - net_printf(thd, ER_WRONG_TABLE_NAME, lex->name); - res= 1; - break; + my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); + goto error; } if (!select_lex->db) select_lex->db= first_table->db; @@ -2621,7 +2710,7 @@ unsent_create_error: lex->create_info.data_file_name=lex->create_info.index_file_name=0; /* ALTER TABLE ends previous transaction */ if (end_active_trans(thd)) - res= -1; + goto error; else { thd->slow_command=TRUE; @@ -2666,16 +2755,15 @@ unsent_create_error: } } query_cache_invalidate3(thd, first_table, 0); - if (end_active_trans(thd)) - res= -1; - else if (mysql_rename_tables(thd, first_table)) - res= -1; + if (end_active_trans(thd) || mysql_rename_tables(thd, first_table)) + goto error; break; } #ifndef EMBEDDED_LIBRARY case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2689,7 +2777,8 @@ unsent_create_error: case SQLCOM_SHOW_CREATE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2795,8 +2884,6 @@ unsent_create_error: (ORDER *) select_lex->order_list.first, select_lex->select_limit, lex->duplicates); - if (thd->net.report_error) - res= -1; break; case SQLCOM_UPDATE_MULTI: { @@ -2821,8 +2908,6 @@ unsent_create_error: select_lex->item_list, lex->value_list, (lex->value_list.elements ? DUP_UPDATE : lex->duplicates)); - if (thd->net.report_error) - res= -1; if (first_table->view && !first_table->contain_auto_increment) thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it break; @@ -2875,11 +2960,9 @@ unsent_create_error: lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; delete result; } - if (thd->net.report_error) - res= -1; } else - res= -1; + res= TRUE; if (first_table->view && !first_table->contain_auto_increment) thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it @@ -2896,7 +2979,8 @@ unsent_create_error: */ if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } @@ -2910,8 +2994,6 @@ unsent_create_error: res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, select_lex->select_limit, select_lex->options); - if (thd->net.report_error) - res= -1; break; } case SQLCOM_DELETE_MULTI: @@ -2929,15 +3011,12 @@ unsent_create_error: if (select_lex->item_list.elements != 0) select_lex->item_list.empty(); if (add_item_to_list(thd, new Item_null())) - { - res= -1; - break; - } + goto error; thd->proc_info="init"; if ((res= open_and_lock_tables(thd, all_tables)) || (res= mysql_multi_delete_prepare(thd))) - break; + goto error; if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) @@ -2952,12 +3031,10 @@ unsent_create_error: select_lex->options | thd->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK, result, unit, select_lex); - if (thd->net.report_error) - res= -1; delete result; } else - res= -1; // Error is not sent + res= TRUE; close_thread_tables(thd); break; } @@ -2969,10 +3046,7 @@ unsent_create_error: if (check_table_access(thd, DROP_ACL, all_tables, 0)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) - { - res= -1; - break; - } + goto error; } else { @@ -2996,21 +3070,10 @@ unsent_create_error: if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) - res= -1; + goto error; else res = mysql_drop_index(thd, first_table, &lex->alter_info); break; - case SQLCOM_SHOW_DATABASES: -#if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - if ((specialflag & SPECIAL_SKIP_SHOW_DB) && - check_global_access(thd, SHOW_DB_ACL)) - goto error; - res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS)); - break; -#endif case SQLCOM_SHOW_PROCESSLIST: if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; @@ -3048,7 +3111,8 @@ unsent_create_error: break; case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3058,95 +3122,9 @@ unsent_create_error: break; } #endif - case SQLCOM_SHOW_TABLES: - /* FALL THROUGH */ -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db=select_lex->db ? select_lex->db : thd->db; - if (!db) - { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ - goto error; /* purecov: inspected */ - } - remove_escape(db); // Fix escaped '_' - if (check_db_name(db)) - { - net_printf(thd,ER_WRONG_DB_NAME, db); - goto error; - } - if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) - goto error; /* purecov: inspected */ - if (!thd->col_access && check_grant_db(thd,db)) - { - net_printf(thd, ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db); - goto error; - } - /* grant is checked in mysqld_show_tables */ - if (lex->describe) - res= mysqld_extend_show_tables(thd,db, - (lex->wild ? lex->wild->ptr() : NullS)); - else - res= mysqld_show_tables(thd, db, - (lex->wild ? lex->wild->ptr() : NullS), - lex->verbose); - break; - } -#endif case SQLCOM_SHOW_OPEN_TABLES: res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS)); break; - case SQLCOM_SHOW_CHARSETS: - res= mysqld_show_charsets(thd,(lex->wild ? lex->wild->ptr() : NullS)); - break; - case SQLCOM_SHOW_COLLATIONS: - res= mysqld_show_collations(thd,(lex->wild ? lex->wild->ptr() : NullS)); - break; - case SQLCOM_SHOW_FIELDS: - DBUG_ASSERT(first_table == all_tables && first_table != 0); -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db= first_table->db; - remove_escape(db); // Fix escaped '_' - remove_escape(first_table->real_name); - if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &first_table->grant.privilege, 0, 0)) - goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, first_table, 2, UINT_MAX, 0)) - goto error; - res= mysqld_show_fields(thd, first_table, - (lex->wild ? lex->wild->ptr() : NullS), - lex->verbose); - break; - } -#endif - case SQLCOM_SHOW_KEYS: - DBUG_ASSERT(first_table == all_tables && first_table != 0); -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db= first_table->db; - remove_escape(db); // Fix escaped '_' - remove_escape(first_table->real_name); - if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &first_table->grant.privilege, 0, 0)) - goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0)) - goto error; - res= mysqld_show_keys(thd, first_table); - break; - } -#endif case SQLCOM_CHANGE_DB: mysql_change_db(thd,select_lex->db); break; @@ -3167,7 +3145,7 @@ unsent_create_error: if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) || ! opt_local_infile) { - send_error(thd,ER_NOT_ALLOWED_COMMAND); + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); goto error; } if (check_one_table_access(thd, privilege, all_tables)) @@ -3183,15 +3161,13 @@ unsent_create_error: { List<set_var_base> *lex_var_list= &lex->var_list; if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - break; + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; if (lex->one_shot_set && not_all_support_one_shot(lex_var_list)) { - my_printf_error(0, "The SET ONE_SHOT syntax is reserved for \ -purposes internal to the MySQL server", MYF(0)); - res= -1; - break; + my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT"); + goto error; } if (!(res= sql_set_variables(thd, lex_var_list))) { @@ -3202,12 +3178,16 @@ purposes internal to the MySQL server", MYF(0)); thd->one_shot_set|= lex->one_shot_set; send_ok(thd); } - if (thd->net.report_error) - res= -1; break; } case SQLCOM_UNLOCK_TABLES: + /* + It is critical for mysqldump --single-transaction --master-data that + UNLOCK TABLES does not implicitely commit a connection which has only + done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes + false, mysqldump will not work. + */ unlock_locked_tables(thd); if (thd->options & OPTION_TABLE_LOCK) { @@ -3246,7 +3226,7 @@ purposes internal to the MySQL server", MYF(0)); char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3261,7 +3241,7 @@ purposes internal to the MySQL server", MYF(0)); (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3276,7 +3256,7 @@ purposes internal to the MySQL server", MYF(0)); char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3291,7 +3271,7 @@ purposes internal to the MySQL server", MYF(0)); (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3299,7 +3279,8 @@ purposes internal to the MySQL server", MYF(0)); break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : lex->name), @@ -3310,7 +3291,7 @@ purposes internal to the MySQL server", MYF(0)); { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3325,7 +3306,7 @@ purposes internal to the MySQL server", MYF(0)); (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3333,7 +3314,8 @@ purposes internal to the MySQL server", MYF(0)); break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysql_alter_db(thd,lex->name,&lex->create_info); @@ -3343,14 +3325,15 @@ purposes internal to the MySQL server", MYF(0)); { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } if (check_access(thd,SELECT_ACL,lex->name,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysqld_show_create_db(thd,lex->name,&lex->create_info); @@ -3364,13 +3347,13 @@ purposes internal to the MySQL server", MYF(0)); #ifdef HAVE_DLOPEN if ((sph= sp_find_function(thd, lex->spname))) { - net_printf(thd, ER_UDF_EXISTS, lex->spname->m_name.str); + my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str); goto error; } if (!(res = mysql_create_function(thd,&lex->udf))) send_ok(thd); #else - res= -1; + res= TRUE; #endif break; } @@ -3449,8 +3432,9 @@ purposes internal to the MySQL server", MYF(0)); { if (lex->columns.elements) { - send_error(thd,ER_ILLEGAL_GRANT_FOR_TABLE); - res=1; + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); + goto error; } else res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, @@ -3490,9 +3474,7 @@ purposes internal to the MySQL server", MYF(0)); binlog or not. */ bool write_to_binlog; - if (reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog)) - send_error(thd, 0); - else + if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog)) { /* We WANT to write and we CAN write. @@ -3515,7 +3497,6 @@ purposes internal to the MySQL server", MYF(0)); break; #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: - res=0; if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) || !check_access(thd, SELECT_ACL, "mysql",0,1,0)) @@ -3559,15 +3540,15 @@ purposes internal to the MySQL server", MYF(0)); close_thread_tables(thd); // Free tables } if (end_active_trans(thd)) - { - res= -1; - } + goto error; else { thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) | OPTION_BEGIN); thd->server_status|= SERVER_STATUS_IN_TRANS; - send_ok(thd); + if (!(lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT) || + !(res= ha_start_consistent_snapshot(thd))) + send_ok(thd); } break; case SQLCOM_COMMIT: @@ -3584,7 +3565,7 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + goto error; break; } case SQLCOM_ROLLBACK: @@ -3606,7 +3587,7 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + res= TRUE; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; case SQLCOM_ROLLBACK_TO_SAVEPOINT: @@ -3618,29 +3599,26 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + goto error; break; case SQLCOM_SAVEPOINT: if (!ha_savepoint(thd, lex->savepoint_name)) send_ok(thd); else - res= -1; + goto error; break; case SQLCOM_CREATE_PROCEDURE: case SQLCOM_CREATE_SPFUNCTION: { uint namelen; char *name; + int result; - if (!lex->sphead) - { - res= -1; // Shouldn't happen - break; - } + DBUG_ASSERT(lex->sphead); if (! lex->sphead->m_db.str) { - send_error(thd,ER_NO_DB_ERROR); + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); delete lex->sphead; lex->sphead= 0; goto error; @@ -3654,7 +3632,7 @@ purposes internal to the MySQL server", MYF(0)); if (udf) { - net_printf(thd, ER_UDF_EXISTS, name); + my_error(ER_UDF_EXISTS, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3664,14 +3642,14 @@ purposes internal to the MySQL server", MYF(0)); if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && !lex->sphead->m_has_return) { - net_printf(thd, ER_SP_NORETURN, name); + my_error(ER_SP_NORETURN, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; } - res= lex->sphead->create(thd); - switch (res) { + res= (result= lex->sphead->create(thd)); + switch (result) { case SP_OK: send_ok(thd); lex->unit.cleanup(); @@ -3679,19 +3657,19 @@ purposes internal to the MySQL server", MYF(0)); lex->sphead= 0; break; case SP_WRITE_ROW_FAILED: - net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); + my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; case SP_NO_DB_ERROR: - net_printf(thd, ER_BAD_DB_ERROR, lex->sphead->m_db.str); + my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; default: - net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); + my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; @@ -3705,8 +3683,8 @@ purposes internal to the MySQL server", MYF(0)); if (!(sp= sp_find_procedure(thd, lex->spname))) { - net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", - lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", + lex->spname->m_qname.str); goto error; } else @@ -3720,17 +3698,11 @@ purposes internal to the MySQL server", MYF(0)); /* In case the arguments are subselects... */ if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - { - break; - } + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; #ifndef EMBEDDED_LIBRARY - /* - When executing substatements, they're assumed to send_error when - it happens, but not to send_ok. - */ my_bool nsok= thd->net.no_send_ok; thd->net.no_send_ok= TRUE; #endif @@ -3738,7 +3710,7 @@ purposes internal to the MySQL server", MYF(0)); { if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) { - send_error(thd, ER_SP_BADSELECT); + my_message(ER_SP_BADSELECT, ER(ER_SP_BADSELECT), MYF(0)); #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif @@ -3771,7 +3743,7 @@ purposes internal to the MySQL server", MYF(0)); thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; } - if (res == 0) + if (!res) send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 : thd->row_count_func)); else goto error; // Substatement should already have sent error @@ -3781,6 +3753,7 @@ purposes internal to the MySQL server", MYF(0)); case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: { + int result; sp_head *sp; st_sp_chistics chistics; @@ -3791,32 +3764,29 @@ purposes internal to the MySQL server", MYF(0)); sp= sp_find_function(thd, lex->spname); mysql_reset_errors(thd); if (! sp) - res= SP_KEY_NOT_FOUND; + result= SP_KEY_NOT_FOUND; else { if (check_sp_definer_access(thd, sp)) - { - res= -1; - break; - } + goto error; memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) - res= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); + result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); else - res= sp_update_function(thd, lex->spname, &lex->sp_chistics); + result= sp_update_function(thd, lex->spname, &lex->sp_chistics); } - switch (res) + switch (result) { case SP_OK: send_ok(thd); break; case SP_KEY_NOT_FOUND: - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_CANT_ALTER, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; @@ -3825,6 +3795,7 @@ purposes internal to the MySQL server", MYF(0)); case SQLCOM_DROP_FUNCTION: { sp_head *sp; + int result; if (lex->sql_command == SQLCOM_DROP_PROCEDURE) sp= sp_find_procedure(thd, lex->spname); @@ -3832,21 +3803,18 @@ purposes internal to the MySQL server", MYF(0)); sp= sp_find_function(thd, lex->spname); mysql_reset_errors(thd); if (! sp) - res= SP_KEY_NOT_FOUND; + result= SP_KEY_NOT_FOUND; else { if (check_sp_definer_access(thd, sp)) - { - res= -1; - break; - } + goto error; if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - res= sp_drop_procedure(thd, lex->spname); + result= sp_drop_procedure(thd, lex->spname); else { - res= sp_drop_function(thd, lex->spname); + result= sp_drop_function(thd, lex->spname); #ifdef HAVE_DLOPEN - if (res == SP_KEY_NOT_FOUND) + if (result == SP_KEY_NOT_FOUND) { udf_func *udf = find_udf(lex->spname->m_name.str, lex->spname->m_name.length); @@ -3864,7 +3832,8 @@ purposes internal to the MySQL server", MYF(0)); #endif } } - switch (res) + res= result; + switch (result) { case SP_OK: send_ok(thd); @@ -3875,34 +3844,31 @@ purposes internal to the MySQL server", MYF(0)); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + res= FALSE; send_ok(thd); break; } - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_DROP_FAILED, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; } case SQLCOM_SHOW_CREATE_PROC: { - res= -1; if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } - res= sp_show_create_procedure(thd, lex->spname); - if (res != SP_OK) + if (sp_show_create_procedure(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -3911,18 +3877,15 @@ purposes internal to the MySQL server", MYF(0)); { if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } - res= sp_show_create_function(thd, lex->spname); - if (res != SP_OK) + if (sp_show_create_function(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } - res= 0; break; } case SQLCOM_SHOW_STATUS_PROC: @@ -3944,13 +3907,9 @@ purposes internal to the MySQL server", MYF(0)); } case SQLCOM_DROP_VIEW: { - if (check_table_access(thd, DROP_ACL, all_tables, 0)) - goto error; - if (end_active_trans(thd)) - { - res= -1; - break; - } + if (check_table_access(thd, DROP_ACL, all_tables, 0) || + end_active_trans(thd)) + goto error; res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); break; } @@ -4018,17 +3977,10 @@ purposes internal to the MySQL server", MYF(0)); thd->row_count_func= -1; } - /* - We end up here if res == 0 and send_ok() has been done, - or res != 0 and no send_error() has yet been done. - */ - if (res < 0) - send_error(thd,thd->killed_errno()); - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); error: - /* We end up here if send_error() has already been done. */ - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -4107,7 +4059,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { DBUG_PRINT("error",("No database")); if (!no_errors) - send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4134,10 +4087,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) - net_printf(thd,ER_ACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ + my_error(ER_ACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + (thd->password ? + ER(ER_YES) : + ER(ER_NO))); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4164,10 +4119,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("error",("Access denied")); if (!no_errors) - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + (db ? db : (thd->db ? + thd->db : + "unknown"))); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4201,8 +4158,7 @@ bool check_global_access(THD *thd, ulong want_access) if ((thd->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); - net_printf(thd,ER_SPECIFIC_ACCESS_DENIED_ERROR, - command); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); return 1; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4222,7 +4178,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, TABLE_LIST *org_tables=tables; for (; tables; tables= tables->next_global) { - if (tables->derived || + if (tables->derived || tables->schema_table || (tables->table && (int)tables->table->tmp_table) || my_tz_check_n_skip_implicit_tables(&tables, thd->lex->time_zone_tables_used)) @@ -4317,7 +4273,8 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) { if (!(tables->db=thd->db)) { - send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: tested */ return TRUE; /* purecov: tested */ } } @@ -4478,6 +4435,8 @@ mysql_init_select(LEX *lex) SELECT_LEX *select_lex= lex->current_select; select_lex->init_select(); select_lex->select_limit= HA_POS_ERROR; + lex->orig_sql_command= SQLCOM_END; + lex->wild= 0; if (select_lex == &lex->select_lex) { DBUG_ASSERT(lex->result == 0); @@ -4517,7 +4476,7 @@ mysql_new_select(LEX *lex, bool move_down) { if (lex->current_select->order_list.first && !lex->current_select->braces) { - net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "ORDER BY"); + my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); return 1; } select_lex->include_neighbour(lex->current_select); @@ -4618,7 +4577,6 @@ void mysql_parse(THD *thd, char *inBuf, uint length) { if (thd->net.report_error) { - send_error(thd, 0, NullS); if (thd->lex->sphead) { if (lex != thd->lex) @@ -4734,7 +4692,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (strlen(field_name) > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, field_name); /* purecov: inspected */ + my_error(ER_TOO_LONG_IDENT, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (type_modifier & PRI_KEY_FLAG) @@ -4765,7 +4723,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC && type == FIELD_TYPE_TIMESTAMP)) { - net_printf(thd, ER_INVALID_DEFAULT, field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } else if (default_value->type() == Item::NULL_ITEM) @@ -4774,20 +4732,20 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } else if (type_modifier & AUTO_INCREMENT_FLAG) { - net_printf(thd, ER_INVALID_DEFAULT, field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } if (on_update_value && type != FIELD_TYPE_TIMESTAMP) { - net_printf(thd, ER_INVALID_ON_UPDATE, field_name); + my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name); DBUG_RETURN(1); } @@ -4913,7 +4871,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res=default_value->val_str(&str); if (res->length()) { - net_printf(thd,ER_BLOB_CANT_HAVE_DEFAULT,field_name); /* purecov: inspected */ + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->def=0; @@ -4933,7 +4892,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint tmp_length=new_field->length; if (tmp_length > PRECISION_FOR_DOUBLE) { - net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } else if (tmp_length > PRECISION_FOR_FLOAT) @@ -5030,7 +4989,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { if (interval->count > sizeof(longlong)*8) { - net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ + my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->pack_length=(interval->count+7)/8; @@ -5056,7 +5015,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ¬_used, ¬_used2, ¬_used3); if (thd->cuted_fields) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -5078,7 +5037,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res->strip_sp(); if (!find_type(interval, res->ptr(), res->length(), 0)) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -5092,14 +5051,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY)) { - net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name, - MAX_FIELD_CHARLENGTH); /* purecov: inspected */ + my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), + field_name, MAX_FIELD_CHARLENGTH);/* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; if ((~allowed_type_modifier) & type_modifier) { - net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } if (!new_field->pack_length) @@ -5229,7 +5188,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - net_printf(thd, ER_WRONG_TABLE_NAME, table->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); } @@ -5237,7 +5196,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { if (table->sel) { - net_printf(thd,ER_DERIVED_MUST_HAVE_ALIAS); + my_message(ER_DERIVED_MUST_HAVE_ALIAS, + ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0)); DBUG_RETURN(0); } if (!(alias_str=thd->memdup(alias_str,table->table.length+1))) @@ -5274,6 +5234,18 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->derived= table->sel; + if (!my_strcasecmp(system_charset_info, ptr->db, + information_schema_name.str)) + { + ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->real_name); + if (!schema_table) + { + my_error(ER_UNKNOWN_TABLE, MYF(0), + ptr->real_name, information_schema_name.str); + DBUG_RETURN(0); + } + ptr->schema_table= schema_table; + } ptr->select_lex= lex->current_select; ptr->cacheable_table= 1; if (use_index_arg) @@ -5293,7 +5265,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && !strcmp(ptr->db, tables->db)) { - net_printf(thd,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ + my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ } } @@ -5789,7 +5761,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) if (!error) send_ok(thd); else - net_printf(thd,error,id); + my_error(error, MYF(0), id); } /* Clear most status variables */ @@ -5865,12 +5837,13 @@ static bool append_file_to_dir(THD *thd, const char **filename_ptr, bool check_simple_select() { THD *thd= current_thd; - if (thd->lex->current_select != &thd->lex->select_lex) + LEX *lex= thd->lex; + if (lex->current_select != &lex->select_lex) { char command[80]; - strmake(command, thd->lex->yylval->symbol.str, - min(thd->lex->yylval->symbol.length, sizeof(command)-1)); - net_printf(thd, ER_CANT_USE_OPTION_HERE, command); + strmake(command, lex->yylval->symbol.str, + min(lex->yylval->symbol.length, sizeof(command)-1)); + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); return 1; } return 0; @@ -5958,7 +5931,7 @@ Item * all_any_subquery_creator(Item *left_expr, One should normally create all indexes with CREATE TABLE or ALTER TABLE. */ -int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) +bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) { List<create_field> fields; ALTER_INFO alter_info; @@ -5975,7 +5948,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) } -int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) +bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) { List<create_field> fields; List<Key> keys; @@ -6002,12 +5975,11 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) tables Global/local table list (have to be the same) RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int multi_update_precheck(THD *thd, TABLE_LIST *tables) +bool multi_update_precheck(THD *thd, TABLE_LIST *tables) { const char *msg= 0; TABLE_LIST *table; @@ -6017,8 +5989,8 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (select_lex->item_list.elements != lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); + DBUG_RETURN(TRUE); } /* Ensure that we have UPDATE or SELECT privilege for each table @@ -6035,7 +6007,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table->table_in_first_from_clause= 1; } @@ -6052,7 +6024,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } } @@ -6065,9 +6037,9 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (msg) { my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /* @@ -6080,11 +6052,11 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) table_count Pointer to table counter RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) + +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) { SELECT_LEX *select_lex= &thd->lex->select_lex; TABLE_LIST *aux_tables= @@ -6099,11 +6071,12 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) || check_table_access(thd,SELECT_ACL, tables,0) || check_table_access(thd,DELETE_ACL, aux_tables,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); - DBUG_RETURN(-1); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); + DBUG_RETURN(TRUE); } for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local) { @@ -6119,14 +6092,14 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) } if (!walk) { - my_error(ER_UNKNOWN_TABLE, MYF(0), target_tbl->real_name, - "MULTI DELETE"); - DBUG_RETURN(-1); + my_error(ER_UNKNOWN_TABLE, MYF(0), + target_tbl->real_name, "MULTI DELETE"); + DBUG_RETURN(TRUE); } walk->lock_type= target_tbl->lock_type; target_tbl->correspondent_table= walk; // Remember corresponding table } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6139,12 +6112,11 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) tables Global table list RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int insert_select_precheck(THD *thd, TABLE_LIST *tables) +bool insert_select_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("insert_select_precheck"); /* @@ -6153,7 +6125,7 @@ int insert_select_precheck(THD *thd, TABLE_LIST *tables) */ ulong privilege= (thd->lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL); - DBUG_RETURN(check_one_table_access(thd, privilege, tables) ? 1 : 0); + DBUG_RETURN(check_one_table_access(thd, privilege, tables)); } @@ -6166,21 +6138,20 @@ int insert_select_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int update_precheck(THD *thd, TABLE_LIST *tables) +bool update_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("update_precheck"); if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); + DBUG_RETURN(TRUE); } - DBUG_RETURN((check_db_used(thd, tables) || - check_one_table_access(thd, UPDATE_ACL, tables)) ? 1 : 0); + DBUG_RETURN(check_db_used(thd, tables) || + check_one_table_access(thd, UPDATE_ACL, tables)); } @@ -6193,19 +6164,18 @@ int update_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int delete_precheck(THD *thd, TABLE_LIST *tables) +bool delete_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("delete_precheck"); if (check_one_table_access(thd, DELETE_ACL, tables)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* Set privilege for the WHERE clause */ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6218,12 +6188,11 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int insert_precheck(THD *thd, TABLE_LIST *tables) +bool insert_precheck(THD *thd, TABLE_LIST *tables) { LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); @@ -6233,14 +6202,14 @@ int insert_precheck(THD *thd, TABLE_LIST *tables) (lex->value_list.elements ? UPDATE_ACL : 0)); if (check_one_table_access(thd, privilege, tables)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (lex->select_lex.item_list.elements != lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6254,17 +6223,17 @@ int insert_precheck(THD *thd, TABLE_LIST *tables) create_table Table which will be created RETURN VALUE - 0 OK - 1 Error (message is sent to user) + FALSE OK + TRUE Error */ -int create_table_precheck(THD *thd, TABLE_LIST *tables, - TABLE_LIST *create_table) +bool create_table_precheck(THD *thd, TABLE_LIST *tables, + TABLE_LIST *create_table) { LEX *lex= thd->lex; SELECT_LEX *select_lex= &lex->select_lex; ulong want_priv; - int error= 1; // Error message is given + bool error= TRUE; // Error message is given DBUG_ENTER("create_table_precheck"); want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? @@ -6298,15 +6267,14 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, find_table_in_global_list(tables, create_table->db, create_table->real_name)) { - net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); - + error= FALSE; goto err; } } if (tables && check_table_access(thd, SELECT_ACL, tables,0)) goto err; } - error= 0; + error= FALSE; err: DBUG_RETURN(error); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1c23162b212..9e3395cf893 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -123,16 +123,13 @@ inline bool is_param_null(const uchar *pos, ulong param_no) enum { STMT_QUERY_LOG_LENGTH= 8192 }; -enum enum_send_error { DONT_SEND_ERROR= 0, SEND_ERROR }; - /* Seek prepared statement in statement map by id: returns zero if statement was not found, pointer otherwise. */ static Prepared_statement * -find_prepared_statement(THD *thd, ulong id, const char *where, - enum enum_send_error se) +find_prepared_statement(THD *thd, ulong id, const char *where) { Statement *stmt= thd->stmt_map.find(id); @@ -140,8 +137,6 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); - if (se == SEND_ERROR) - send_error(thd); return 0; } return (Prepared_statement *) stmt; @@ -181,7 +176,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, thd->client_stmt_id= stmt->id; thd->client_param_count= stmt->param_count; - thd->net.last_errno= 0; + thd->clear_error(); return 0; } @@ -882,24 +877,23 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, tables global/local table list RETURN VALUE - 0 ok - 1 error, sent to the client - -1 error, not sent to client + FALSE OK + TRUE error */ -static int mysql_test_insert(Prepared_statement *stmt, - TABLE_LIST *table_list, - List<Item> &fields, - List<List_item> &values_list, - List<Item> &update_fields, - List<Item> &update_values, - enum_duplicates duplic) +static bool mysql_test_insert(Prepared_statement *stmt, + TABLE_LIST *table_list, + List<Item> &fields, + List<List_item> &values_list, + List<Item> &update_fields, + List<Item> &update_values, + enum_duplicates duplic) { THD *thd= stmt->thd; LEX *lex= stmt->lex; List_iterator_fast<List_item> its(values_list); List_item *values; - int res; + bool res; DBUG_ENTER("mysql_test_insert"); if ((res= insert_precheck(thd, table_list))) @@ -909,9 +903,9 @@ static int mysql_test_insert(Prepared_statement *stmt, open temporary memory pool for temporary data allocated by derived tables & preparation procedure */ - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } if ((values= its++)) @@ -932,9 +926,7 @@ static int mysql_test_insert(Prepared_statement *stmt, counter++; if (values->elements != value_count) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0), counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); goto error; } if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) @@ -958,14 +950,13 @@ error: tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_update(Prepared_statement *stmt, - TABLE_LIST *table_list) +static bool mysql_test_update(Prepared_statement *stmt, + TABLE_LIST *table_list) { - int res; + bool res; THD *thd= stmt->thd; SELECT_LEX *select= &stmt->lex->select_lex; DBUG_ENTER("mysql_test_update"); @@ -1010,28 +1001,27 @@ static int mysql_test_update(Prepared_statement *stmt, tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ static int mysql_test_delete(Prepared_statement *stmt, TABLE_LIST *table_list) { - int res; THD *thd= stmt->thd; LEX *lex= stmt->lex; DBUG_ENTER("mysql_test_delete"); - if ((res= delete_precheck(thd, table_list))) - DBUG_RETURN(res); + if (delete_precheck(thd, table_list)) + DBUG_RETURN(TRUE); - if (!(res=open_and_lock_tables(thd, table_list))) + if (!open_and_lock_tables(thd, table_list)) { - res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where); + mysql_prepare_delete(thd, table_list, &lex->select_lex.where); lex->unit.cleanup(); + DBUG_RETURN(FALSE) } /* TODO: here we should send types of placeholders to the client. */ - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -1046,9 +1036,8 @@ static int mysql_test_delete(Prepared_statement *stmt, tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error, sent to client */ static int mysql_test_select(Prepared_statement *stmt, @@ -1057,7 +1046,7 @@ static int mysql_test_select(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; - int result; + bool result; DBUG_ENTER("mysql_test_select"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1065,32 +1054,25 @@ static int mysql_test_select(Prepared_statement *stmt, if (tables) { if (check_table_access(thd, privilege, tables,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } else if (check_access(thd, privilege, any_db,0,0,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); #endif + result= TRUE; if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) - { - send_error(thd); goto err; - } - if ((result= open_and_lock_tables(thd, tables))) - { - result= 1; // Error sent - send_error(thd); + if (open_and_lock_tables(thd, tables)) goto err; - } - result= 1; + thd->used_tables= 0; // Updated by setup_fields // JOIN::prepare calls if (unit->prepare(thd, 0, 0)) { - send_error(thd); goto err_prep; } if (!text_protocol) @@ -1120,7 +1102,7 @@ static int mysql_test_select(Prepared_statement *stmt, goto err_prep; } } - result= 0; // ok + result= FALSE; // ok err_prep: unit->cleanup(); @@ -1139,30 +1121,27 @@ err: values list of expressions RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error, sent to client */ -static int mysql_test_do_fields(Prepared_statement *stmt, +static bool mysql_test_do_fields(Prepared_statement *stmt, TABLE_LIST *tables, List<Item> *values) { DBUG_ENTER("mysql_test_do_fields"); THD *thd= stmt->thd; - int res= 0; - if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) - DBUG_RETURN(res); + bool res; + if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + DBUG_RETURN(TRUE); - if (tables && (res= open_and_lock_tables(thd, tables))) + if (tables && open_and_lock_tables(thd, tables)) { - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } res= setup_fields(thd, 0, 0, *values, 0, 0, 0); stmt->lex->unit.cleanup(); - if (res) - DBUG_RETURN(-1); - DBUG_RETURN(0); + DBUG_RETURN(res); } @@ -1176,22 +1155,21 @@ static int mysql_test_do_fields(Prepared_statement *stmt, values list of expressions RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_set_fields(Prepared_statement *stmt, - TABLE_LIST *tables, - List<set_var_base> *var_list) +static bool mysql_test_set_fields(Prepared_statement *stmt, + TABLE_LIST *tables, + List<set_var_base> *var_list) { DBUG_ENTER("mysql_test_set_fields"); List_iterator_fast<set_var_base> it(*var_list); THD *thd= stmt->thd; set_var_base *var; - int res= 0; + bool res= 0; - if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) - DBUG_RETURN(res); + if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + DBUG_RETURN(TRUE); if (tables && (res= open_and_lock_tables(thd, tables))) goto error; @@ -1200,7 +1178,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt, if (var->light_check(thd)) { stmt->lex->unit.cleanup(); - res= -1; + res= TRUE; goto error; } } @@ -1220,18 +1198,17 @@ error: specific_prepare - function of command specific prepare RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int select_like_statement_test(Prepared_statement *stmt, - TABLE_LIST *tables, - int (*specific_prepare)(THD *thd)) +static bool select_like_statement_test(Prepared_statement *stmt, + TABLE_LIST *tables, + bool (*specific_prepare)(THD *thd)) { DBUG_ENTER("select_like_statement_test"); THD *thd= stmt->thd; LEX *lex= stmt->lex; - int res= 0; + bool res= 0; if (tables && (res= open_and_lock_tables(thd, tables))) goto end; @@ -1244,7 +1221,7 @@ static int select_like_statement_test(Prepared_statement *stmt, // JOIN::prepare calls if (lex->unit.prepare(thd, 0, 0)) { - res= thd->net.report_error ? -1 : 1; + res= TRUE; } end: lex->unit.cleanup(); @@ -1301,16 +1278,15 @@ static int mysql_test_create_table(Prepared_statement *stmt) tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_multiupdate(Prepared_statement *stmt, + +static bool mysql_test_multiupdate(Prepared_statement *stmt, TABLE_LIST *tables) { - int res; - if ((res= multi_update_precheck(stmt->thd, tables))) - return res; + if (multi_update_precheck(stmt->thd, tables)) + return TRUE; /* here we do not pass tables for opening, tables will be opened and locked by mysql_multi_update_prepare @@ -1386,23 +1362,34 @@ static int mysql_test_insert_select(Prepared_statement *stmt, /* - Send the prepare query results back to client + Perform semantic analysis of the parsed tree and send a response packet + to the client. + SYNOPSIS - send_prepare_results() - stmt prepared statement + check_prepared_statement() + stmt prepared statement + + DESCRIPTION + This function + - opens all tables and checks access rights + - validates semantics of statement columns and SQL functions + by calling fix_fields. + RETURN VALUE 0 success 1 error, sent to client */ -static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) -{ + +static int check_prepared_statement(Prepared_statement *stmt, + bool text_protocol) +{ THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX *select_lex= &lex->select_lex; TABLE_LIST *tables; enum enum_sql_command sql_command= lex->sql_command; int res= 0; - DBUG_ENTER("send_prepare_results"); + DBUG_ENTER("check_prepared_statement"); DBUG_PRINT("enter",("command: %d, param_count: %ld", sql_command, stmt->param_count)); @@ -1502,15 +1489,13 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) All other is not supported yet */ res= -1; - my_error(ER_UNSUPPORTED_PS, MYF(0)); + my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0)); goto error; } if (res == 0) DBUG_RETURN(text_protocol? 0 : (send_prep_stmt(stmt, 0) || thd->protocol->flush())); error: - if (res < 0) - send_error(thd,thd->killed_errno()); DBUG_RETURN(1); } @@ -1529,9 +1514,8 @@ static bool init_param_array(Prepared_statement *stmt) if (stmt->param_count > (uint) UINT_MAX16) { /* Error code to be defined in 5.0 */ - send_error(thd, ER_UNKNOWN_ERROR, - "Prepared statement contains too many placeholders."); - return 1; + my_message(ER_PS_MANY_PARAM, ER(ER_PS_MANY_PARAM), MYF(0)); + return TRUE; } Item_param **to; List_iterator<Item_param> param_iterator(lex->param_list); @@ -1540,10 +1524,7 @@ static bool init_param_array(Prepared_statement *stmt) alloc_root(stmt->thd->mem_root, sizeof(Item_param*) * stmt->param_count); if (!stmt->param_array) - { - send_error(thd, ER_OUT_OF_RESOURCES); - return 1; - } + return TRUE; for (to= stmt->param_array; to < stmt->param_array + stmt->param_count; ++to) @@ -1551,7 +1532,7 @@ static bool init_param_array(Prepared_statement *stmt) *to= param_iterator++; } } - return 0; + return FALSE; } @@ -1567,10 +1548,10 @@ static bool init_param_array(Prepared_statement *stmt) name NULL or statement name. For unnamed statements binary PS protocol is used, for named statements text protocol is used. - RETURN - 0 OK, statement prepared successfully - other Error - + RETURN + FALSE OK, statement prepared successfully + TRUE Error + NOTES This function parses the query and sends the total number of parameters and resultset metadata information back to client (if any), without @@ -1584,21 +1565,18 @@ static bool init_param_array(Prepared_statement *stmt) */ -int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, - LEX_STRING *name) +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, + LEX_STRING *name) { LEX *lex; Prepared_statement *stmt= new Prepared_statement(thd); - int error; + bool error; DBUG_ENTER("mysql_stmt_prepare"); DBUG_PRINT("prep_query", ("%s", packet)); if (stmt == 0) - { - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); - } + DBUG_RETURN(TRUE); if (name) { @@ -1607,16 +1585,14 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, name->length))) { delete stmt; - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } if (thd->stmt_map.insert(stmt)) { delete stmt; - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } thd->set_n_backup_statement(stmt, &thd->stmt_backup); @@ -1628,8 +1604,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, thd->restore_backup_item_arena(stmt, &thd->stmt_backup); /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } mysql_log.write(thd, COM_PREPARE, "%s", packet); @@ -1644,8 +1619,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, error= yyparse((void *)thd) || thd->is_fatal_error || thd->net.report_error || init_param_array(stmt); /* - While doing context analysis of the query (in send_prepare_results) we - allocate a lot of additional memory: for open tables, JOINs, derived + While doing context analysis of the query (in check_prepared_statement) + we allocate a lot of additional memory: for open tables, JOINs, derived tables, etc. Let's save a snapshot of current parse tree to the statement and restore original THD. In cases when some tree transformation can be reused on execute, we set again thd->mem_root from @@ -1654,7 +1629,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, thd->restore_backup_item_arena(stmt, &thd->stmt_backup); if (!error) - error= send_prepare_results(stmt, test(name)); + error= check_prepared_statement(stmt, test(name)); /* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */ if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1679,9 +1654,6 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); stmt= NULL; - if (thd->net.report_error) - send_error(thd); - /* otherwise the error is sent inside yyparse/send_prepare_results */ } else { @@ -1817,8 +1789,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) packet+= 9; /* stmt_id + 5 bytes of flags */ - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute", - SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute"))) DBUG_VOID_RETURN; DBUG_PRINT("exec_query:", ("%s", stmt->query)); @@ -1826,7 +1797,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) /* Check if we got an error when sending long data */ if (stmt->state == Item_arena::ERROR) { - send_error(thd, stmt->last_errno, stmt->last_error); + my_message(stmt->last_errno, stmt->last_error, MYF(0)); DBUG_VOID_RETURN; } @@ -1848,10 +1819,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) DBUG_PRINT("info",("Using READ_ONLY cursor")); if (!stmt->cursor && !(stmt->cursor= new (&stmt->main_mem_root) Cursor())) - { - send_error(thd, ER_OUT_OF_RESOURCES); DBUG_VOID_RETURN; - } /* If lex->result is set, mysql_execute_command will use it */ stmt->lex->result= &stmt->cursor->result; } @@ -1919,7 +1887,6 @@ set_params_data_err: reset_stmt_params(stmt); my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute"); err: - send_error(thd); DBUG_VOID_RETURN; } @@ -1945,14 +1912,12 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_name->length, stmt_name->str, "EXECUTE"); - send_error(thd); DBUG_VOID_RETURN; } if (stmt->param_count != thd->lex->prepared_stmt_params.elements) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); - send_error(thd); DBUG_VOID_RETURN; } @@ -1965,7 +1930,6 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) &expanded_query)) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); - send_error(thd); } execute_stmt(thd, stmt, &expanded_query); DBUG_VOID_RETURN; @@ -1996,7 +1960,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, alloc_query(thd, (char *)expanded_query->ptr(), expanded_query->length()+1)) { - my_error(ER_OUTOFMEMORY, 0, expanded_query->length()); + my_error(ER_OUTOFMEMORY, MYF(0), expanded_query->length()); DBUG_VOID_RETURN; } /* @@ -2055,7 +2019,6 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) !stmt->cursor->is_open()) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_id, "fetch"); - send_error(thd); DBUG_VOID_RETURN; } @@ -2106,8 +2069,7 @@ void mysql_stmt_reset(THD *thd, char *packet) DBUG_ENTER("mysql_stmt_reset"); - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset", - SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset"))) DBUG_VOID_RETURN; stmt->state= Item_arena::PREPARED; @@ -2138,8 +2100,7 @@ void mysql_stmt_free(THD *thd, char *packet) DBUG_ENTER("mysql_stmt_free"); - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close", - DONT_SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close"))) DBUG_VOID_RETURN; /* Statement map deletes statement on erase */ @@ -2189,8 +2150,8 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) stmt_id= uint4korr(packet); packet+= 4; - if (!(stmt=find_prepared_statement(thd, stmt_id, "mysql_stmt_send_long_data", - DONT_SEND_ERROR))) + if (!(stmt=find_prepared_statement(thd, stmt_id, + "mysql_stmt_send_long_data"))) DBUG_VOID_RETURN; param_number= uint2korr(packet); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 3298eb68a91..9f29a975441 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -44,7 +44,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); DBUG_RETURN(1); } @@ -156,7 +157,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) unpack_filename(name, name); if (!access(name,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_alias); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 10f0c23f54d..d2e3e72618d 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -276,41 +276,39 @@ bool log_in_use(const char* log_name) return result; } -int purge_error_message(THD* thd, int res) +bool purge_error_message(THD* thd, int res) { - const char *errmsg= 0; + uint errmsg= 0; switch (res) { case 0: break; - case LOG_INFO_EOF: errmsg= "Target log not found in binlog index"; break; - case LOG_INFO_IO: errmsg= "I/O error reading log index file"; break; - case LOG_INFO_INVALID: - errmsg= "Server configuration does not permit binlog purge"; break; - case LOG_INFO_SEEK: errmsg= "Failed on fseek()"; break; - case LOG_INFO_MEM: errmsg= "Out of memory"; break; - case LOG_INFO_FATAL: errmsg= "Fatal error during purge"; break; - case LOG_INFO_IN_USE: errmsg= "A purgeable log is in use, will not purge"; - break; - default: errmsg= "Unknown error during purge"; break; + case LOG_INFO_EOF: errmsg= ER_UNKNOWN_TARGET_BINLOG; break; + case LOG_INFO_IO: errmsg= ER_IO_ERR_LOG_INDEX_READ; break; + case LOG_INFO_INVALID:errmsg= ER_BINLOG_PURGE_PROHIBITED; break; + case LOG_INFO_SEEK: errmsg= ER_FSEEK_FAIL; break; + case LOG_INFO_MEM: errmsg= ER_OUT_OF_RESOURCES; break; + case LOG_INFO_FATAL: errmsg= ER_BINLOG_PURGE_FATAL_ERR; break; + case LOG_INFO_IN_USE: errmsg= ER_LOG_IN_USE; break; + default: errmsg= ER_LOG_PURGE_UNKNOWN_ERR; break; } if (errmsg) { - send_error(thd, 0, errmsg); - return 1; + my_message(errmsg, ER(errmsg), MYF(0)); + return TRUE; } send_ok(thd); - return 0; + return FALSE; } -int purge_master_logs(THD* thd, const char* to_log) +bool purge_master_logs(THD* thd, const char* to_log) { char search_file_name[FN_REFLEN]; if (!mysql_bin_log.is_open()) { send_ok(thd); - return 0; + return FALSE; } mysql_bin_log.make_log_name(search_file_name, to_log); @@ -320,7 +318,7 @@ int purge_master_logs(THD* thd, const char* to_log) } -int purge_master_logs_before_date(THD* thd, time_t purge_time) +bool purge_master_logs_before_date(THD* thd, time_t purge_time) { if (!mysql_bin_log.is_open()) { @@ -756,7 +754,7 @@ err: pthread_mutex_unlock(&LOCK_thread_count); if (file >= 0) (void) my_close(file, MYF(MY_WME)); - send_error(thd, my_errno, errmsg); + my_message(my_errno, errmsg, MYF(0)); DBUG_VOID_RETURN; } @@ -872,7 +870,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (slave_errno) { if (net_report) - send_error(thd, slave_errno); + my_message(slave_errno, ER(slave_errno), MYF(0)); DBUG_RETURN(1); } else if (net_report) @@ -922,7 +920,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) if (slave_errno) { if (net_report) - send_error(thd, slave_errno); + my_message(slave_errno, ER(slave_errno), MYF(0)); return 1; } else if (net_report) @@ -1003,7 +1001,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi) err: unlock_slave_threads(mi); - if (error) + if (error) my_error(sql_errno, MYF(0), errmsg); DBUG_RETURN(error); } @@ -1057,7 +1055,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) } -int change_master(THD* thd, MASTER_INFO* mi) +bool change_master(THD* thd, MASTER_INFO* mi) { int thread_mask; const char* errmsg= 0; @@ -1068,9 +1066,9 @@ int change_master(THD* thd, MASTER_INFO* mi) init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { - net_printf(thd,ER_SLAVE_MUST_STOP); + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } thd->proc_info = "Changing master"; @@ -1078,9 +1076,9 @@ int change_master(THD* thd, MASTER_INFO* mi) // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { - send_error(thd, ER_MASTER_INFO); + my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } /* @@ -1197,9 +1195,9 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - net_printf(thd, 0, "Failed purging old relay logs: %s",errmsg); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } else @@ -1213,9 +1211,9 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /*no data lock*/, &msg, 0)) { - net_printf(thd,0,"Failed initializing relay log position: %s",msg); + my_error(ER_RELAY_LOG_INIT, MYF(0), msg); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } mi->rli.group_master_log_pos = mi->master_log_pos; @@ -1257,14 +1255,15 @@ int change_master(THD* thd, MASTER_INFO* mi) unlock_slave_threads(mi); thd->proc_info = 0; send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } int reset_master(THD* thd) { if (!mysql_bin_log.is_open()) { - my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG)); + my_message(ER_FLUSH_MASTER_BINLOG_CLOSED, + ER(ER_FLUSH_MASTER_BINLOG_CLOSED), MYF(ME_BELL+ME_WAITTANG)); return 1; } return mysql_bin_log.reset_logs(thd); @@ -1288,7 +1287,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, } -int show_binlog_events(THD* thd) +bool show_binlog_events(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_binlog_events"); @@ -1302,7 +1301,7 @@ int show_binlog_events(THD* thd) Log_event::init_show_field_list(&field_list); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (mysql_bin_log.is_open()) { @@ -1407,19 +1406,19 @@ err: if (errmsg) { my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), - "SHOW BINLOG EVENTS", errmsg); - DBUG_RETURN(-1); + "SHOW BINLOG EVENTS", errmsg); + DBUG_RETURN(TRUE); } send_eof(thd); pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; pthread_mutex_unlock(&LOCK_thread_count); - DBUG_RETURN(0); + DBUG_RETURN(TRUE); } -int show_binlog_info(THD* thd) +bool show_binlog_info(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_binlog_info"); @@ -1432,7 +1431,7 @@ int show_binlog_info(THD* thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); if (mysql_bin_log.is_open()) @@ -1445,10 +1444,10 @@ int show_binlog_info(THD* thd) protocol->store(&binlog_do_db); protocol->store(&binlog_ignore_db); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1460,11 +1459,11 @@ int show_binlog_info(THD* thd) thd Thread specific variable RETURN VALUES - 0 ok - 1 error (Error message sent to client) + FALSE OK + TRUE error */ -int show_binlogs(THD* thd) +bool show_binlogs(THD* thd) { IO_CACHE *index_file; char fname[FN_REFLEN]; @@ -1475,15 +1474,14 @@ int show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { - //TODO: Replace with ER() error message - send_error(thd, 0, "You are not using binary logging"); + my_message(ER_NO_BINARY_LOGGING, ER(ER_NO_BINARY_LOGGING), MYF(0)); return 1; } field_list.push_back(new Item_empty_string("Log_name", 255)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); mysql_bin_log.lock_index(); index_file=mysql_bin_log.get_index_file(); @@ -1501,11 +1499,11 @@ int show_binlogs(THD* thd) } mysql_bin_log.unlock_index(); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: mysql_bin_log.unlock_index(); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 66fdfb4c022..71b25548da4 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -43,17 +43,17 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, int start_slave(THD* thd, MASTER_INFO* mi, bool net_report); int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report); -int change_master(THD* thd, MASTER_INFO* mi); -int show_binlog_events(THD* thd); +bool change_master(THD* thd, MASTER_INFO* mi); +bool show_binlog_events(THD* thd); int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, const char* log_file_name2, ulonglong log_pos2); int reset_slave(THD *thd, MASTER_INFO* mi); int reset_master(THD* thd); -int purge_master_logs(THD* thd, const char* to_log); -int purge_master_logs_before_date(THD* thd, time_t purge_time); +bool purge_master_logs(THD* thd, const char* to_log); +bool purge_master_logs_before_date(THD* thd, time_t purge_time); bool log_in_use(const char* log_name); void adjust_linfo_offsets(my_off_t purge_offset); -int show_binlogs(THD* thd); +bool show_binlogs(THD* thd); extern int init_master_info(MASTER_INFO* mi); void kill_zombie_dump_threads(uint32 slave_server_id); int check_binlog_magic(IO_CACHE* log, const char** errmsg); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 92cf499eb2b..80c1c8a697f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -205,9 +205,9 @@ static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab); This handles SELECT with and without UNION */ -int handle_select(THD *thd, LEX *lex, select_result *result) +bool handle_select(THD *thd, LEX *lex, select_result *result) { - int res; + bool res; register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); @@ -232,11 +232,14 @@ int handle_select(THD *thd, LEX *lex, select_result *result) } DBUG_PRINT("info",("res: %d report_error: %d", res, thd->net.report_error)); - if (thd->net.report_error || res < 0) + res|= thd->net.report_error; + if (unlikely(res)) { - result->send_error(0, NullS); + /* + If we have real error reported erly then this will be ignored + */ + result->send_error(ER_UNKNOWN_ERROR, NullS); result->abort(); - res= 1; // Error sent to client } DBUG_RETURN(res); } @@ -374,7 +377,8 @@ JOIN::prepare(Item ***rref_pointer_array, } if (flag == 3) { - my_error(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,MYF(0)); + my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS, + ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0)); DBUG_RETURN(-1); } } @@ -401,21 +405,22 @@ JOIN::prepare(Item ***rref_pointer_array, { if (!test_if_subpart(procedure->group,group_list)) { /* purecov: inspected */ - my_message(0,"Can't handle procedures with differents groups yet", - MYF(0)); /* purecov: inspected */ + my_message(ER_DIFF_GROUPS_PROC, ER(ER_DIFF_GROUPS_PROC), + MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } #ifdef NOT_NEEDED else if (!group_list && procedure->flags & PROC_GROUP) { - my_message(0,"Select must have a group with this procedure",MYF(0)); + my_message(ER_NO_GROUP_FOR_PROC, MYF(0)); goto err; } #endif if (order && (procedure->flags & PROC_NO_SORT)) { /* purecov: inspected */ - my_message(0,"Can't use order with this procedure",MYF(0)); /* purecov: inspected */ + my_message(ER_ORDER_WITH_PROC, ER(ER_ORDER_WITH_PROC), + MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } @@ -1221,6 +1226,12 @@ JOIN::exec() List<Item> *curr_fields_list= &fields_list; TABLE *curr_tmp_table= 0; + if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) && + get_schema_tables_result(curr_join)) + { + DBUG_VOID_RETURN; + } + /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) { @@ -1803,7 +1814,7 @@ Cursor::fetch(ulong num_rows) if (thd->killed) /* Aborted by user */ { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_message(ER_SERVER_SHUTDOWN, ER(ER_SERVER_SHUTDOWN), MYF(0)); return -1; } @@ -1877,7 +1888,7 @@ Cursor::fetch(ulong num_rows) thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; } else - send_error(thd, ER_OUT_OF_RESOURCES); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); /* free cursor memory */ free_items(free_list); free_list= 0; @@ -1939,7 +1950,7 @@ Cursor::~Cursor() /*********************************************************************/ -int +bool mysql_select(THD *thd, Item ***rref_pointer_array, TABLE_LIST *tables, uint wild_num, List<Item> &fields, COND *conds, uint og_num, ORDER *order, ORDER *group, @@ -1947,7 +1958,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, select_result *result, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) { - int err; + bool err; bool free_join= 1; DBUG_ENTER("mysql_select"); @@ -1955,7 +1966,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, if (select_lex->join != 0) { join= select_lex->join; - // is it single SELECT in derived table, called in derived table creation + /* + is it single SELECT in derived table, called in derived table + creation + */ if (select_lex->linkage != DERIVED_TABLE_TYPE || (select_options & SELECT_DESCRIBE)) { @@ -1964,7 +1978,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, //here is EXPLAIN of subselect or derived table if (join->change_result(result)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } else @@ -1983,7 +1997,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, else { if (!(join= new JOIN(thd, fields, select_options, result))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); thd->proc_info="init"; thd->used_tables=0; // Updated by setup_fields if (join->prepare(rref_pointer_array, tables, wild_num, @@ -2031,10 +2045,8 @@ err: { thd->proc_info="end"; err= join->cleanup(); - if (thd->net.report_error) - err= -1; delete join; - DBUG_RETURN(err); + DBUG_RETURN(err || thd->net.report_error); } DBUG_RETURN(join->error); } @@ -2128,6 +2140,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, s->dependent= tables->dep_tables; s->key_dependent= 0; + if (tables->schema_table) + table->file->records= 2; s->on_expr_ref= &tables->on_expr; if (*s->on_expr_ref) @@ -2191,7 +2205,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (s->dependent & s->table->map) { join->tables=0; // Don't use join->table - my_error(ER_WRONG_OUTER_JOIN,MYF(0)); + my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); DBUG_RETURN(1); } s->key_dependent= s->dependent; @@ -2935,14 +2949,14 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, Item_func *arg0=(Item_func *)(func->arguments()[0]), *arg1=(Item_func *)(func->arguments()[1]); if (arg1->const_item() && - ((functype == Item_func::GE_FUNC && arg1->val()> 0) || - (functype == Item_func::GT_FUNC && arg1->val()>=0)) && + ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) || + (functype == Item_func::GT_FUNC && arg1->val_real() >=0)) && arg0->type() == Item::FUNC_ITEM && arg0->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg0; else if (arg0->const_item() && - ((functype == Item_func::LE_FUNC && arg0->val()> 0) || - (functype == Item_func::LT_FUNC && arg0->val()>=0)) && + ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) || + (functype == Item_func::LT_FUNC && arg0->val_real() >=0)) && arg1->type() == Item::FUNC_ITEM && arg1->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg1; @@ -5613,7 +5627,8 @@ bool error_if_full_join(JOIN *join) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0)); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); return(1); } } @@ -7723,7 +7738,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, blob_count,group_null_items; bool using_unique_constraint=0; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); - char *tmpname,path[FN_REFLEN]; + char *tmpname,path[FN_REFLEN], filename[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; Field **reg_field, **from_field, **blob_field; @@ -7745,14 +7760,15 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, temp_pool_slot = bitmap_set_next(&temp_pool); if (temp_pool_slot != MY_BIT_NONE) // we got a slot - sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix, - current_pid, temp_pool_slot); + sprintf(filename, "%s_%lx_%i", tmp_file_prefix, + current_pid, temp_pool_slot); else // if we run out of slots or we are not using tempool - sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid, + sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); if (lower_case_table_names) my_casedn_str(files_charset_info, path); + sprintf(path, "%s%s", mysql_tmpdir, filename); if (group) { @@ -9753,9 +9769,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { Item *item= *group->item; item->save_org_in_field(group->field); -#ifdef EMBEDDED_LIBRARY - join->thd->net.last_errno= 0; -#endif /* Store in the used key if the field was 0 */ if (item->maybe_null) group->buff[-1]=item->null_value ? 1 : 0; @@ -10716,7 +10729,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (copy_blobs(first_field)) { - my_error(ER_OUTOFMEMORY,MYF(0)); + my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0)); error=0; goto err; } @@ -11167,24 +11180,53 @@ cp_buffer_from_ref(TABLE_REF *ref) *****************************************************************************/ /* - Find order/group item in requested columns and change the item to point at - it. If item doesn't exists, add it first in the field list - Return 0 if ok. + Resolve an ORDER BY or GROUP BY column reference. + + SYNOPSIS + find_order_in_list() + thd [in] Pointer to current thread structure + ref_pointer_array [in/out] All select, group and order by fields + tables [in] List of tables to search in (usually FROM clause) + order [in] Column reference to be resolved + fields [in] List of fields to search in (usually SELECT list) + all_fields [in/out] All select, group and order by fields + is_group_field [in] True if order is a GROUP field, false if + ORDER by field + + DESCRIPTION + Given a column reference (represented by 'order') from a GROUP BY or ORDER + BY clause, find the actual column it represents. If the column being + resolved is from the GROUP BY clause, the procedure searches the SELECT + list 'fields' and the columns in the FROM list 'tables'. If 'order' is from + the ORDER BY clause, only the SELECT list is being searched. + + If 'order' is resolved to an Item, then order->item is set to the found + Item. If there is no item for the found column (that is, it was resolved + into a table field), order->item is 'fixed' and is added to all_fields and + ref_pointer_array. + + RETURN + 0 if OK + 1 if error occurred */ static int -find_order_in_list(THD *thd, Item **ref_pointer_array, - TABLE_LIST *tables,ORDER *order, List<Item> &fields, - List<Item> &all_fields) +find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, + ORDER *order, List<Item> &fields, List<Item> &all_fields, + bool is_group_field) { - Item *it= *order->item; - if (it->type() == Item::INT_ITEM) + Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */ + Item::Type order_item_type; + Item **select_item; /* The corresponding item from the SELECT clause. */ + Field *from_field; /* The corresponding field from the FROM clause. */ + + if (order_item->type() == Item::INT_ITEM) { /* Order by position */ - uint count= (uint) it->val_int(); + uint count= (uint) order_item->val_int(); if (!count || count > fields.elements) { - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0), it->full_name(), thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + order_item->full_name(), thd->where); return 1; } order->item= ref_pointer_array + count - 1; @@ -11193,47 +11235,78 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, order->counter_used= 1; return 0; } + /* Lookup the current GROUP/ORDER field in the SELECT clause. */ uint counter; bool unaliased; - Item **item= find_item_in_list(it, fields, &counter, + select_item= find_item_in_list(order_item, fields, &counter, REPORT_EXCEPT_NOT_FOUND, &unaliased); - if (!item) - return 1; + if (!select_item) + return 1; /* Some error occured. */ - if (item != (Item **)not_found_item) + + /* Check whether the resolved field is not ambiguos. */ + if (select_item != not_found_item) { /* If we have found field not by its alias in select list but by its original field name, we should additionaly check if we have conflict for this name (in case if we would perform lookup in all tables). */ - if (unaliased && !it->fixed && it->fix_fields(thd, tables, order->item)) + if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables, order->item)) return 1; - order->item= ref_pointer_array + counter; - order->in_field_list=1; - return 0; + /* Lookup the current GROUP field in the FROM clause. */ + order_item_type= order_item->type(); + if (is_group_field && + order_item_type == Item::FIELD_ITEM || order_item_type == Item::REF_ITEM) + { + Item **view_ref= NULL; + from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables, + view_ref, IGNORE_ERRORS, TRUE); + if(!from_field) + from_field= (Field*) not_found_field; + } + else + from_field= (Field*) not_found_field; + + if (from_field == not_found_field || + from_field && from_field != view_ref_found && + (*select_item)->type() == Item::FIELD_ITEM && + ((Item_field*) (*select_item))->field->eq(from_field)) + /* + If there is no such field in the FROM clause, or it is the same field as + the one found in the SELECT clause, then use the Item created for the + SELECT field. As a result if there was a derived field that 'shadowed' + a table field with the same name, the table field will be chosen over + the derived field. + */ + { + order->item= ref_pointer_array + counter; + order->in_field_list=1; + return 0; + } } order->in_field_list=0; /* - We check it->fixed because Item_func_group_concat can put + We check order_item->fixed because Item_func_group_concat can put arguments for which fix_fields already was called. 'it' reassigned in if condition because fix_field can change it. */ - if (!it->fixed && - (it->fix_fields(thd, tables, order->item) || - (it= *order->item)->check_cols(1) || + if (!order_item->fixed && + (order_item->fix_fields(thd, tables, order->item) || + (order_item= *order->item)->check_cols(1) || thd->is_fatal_error)) return 1; // Wrong field uint el= all_fields.elements; - all_fields.push_front(it); // Add new field to field list - ref_pointer_array[el]= it; + all_fields.push_front(order_item); // Add new field to field list + ref_pointer_array[el]= order_item; order->item= ref_pointer_array + el; return 0; } + /* Change order to point at item in select list. If item isn't a number and doesn't exits in the select list, add it the the field list. @@ -11246,7 +11319,7 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, - all_fields)) + all_fields, FALSE)) return 1; } return 0; @@ -11298,13 +11371,12 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, - all_fields)) + all_fields, TRUE)) return 1; (*order->item)->marker=1; /* Mark found */ if ((*order->item)->with_sum_func) { - my_printf_error(ER_WRONG_GROUP_FIELD, ER(ER_WRONG_GROUP_FIELD),MYF(0), - (*order->item)->full_name()); + my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*order->item)->full_name()); return 1; } } @@ -11319,9 +11391,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, if (item->type() != Item::SUM_FUNC_ITEM && !item->marker && !item->const_item()) { - my_printf_error(ER_WRONG_FIELD_WITH_GROUP, - ER(ER_WRONG_FIELD_WITH_GROUP), - MYF(0),item->full_name()); + my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name()); return 1; } } @@ -12675,10 +12745,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } -int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) +bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) { DBUG_ENTER("mysql_explain_union"); - int res= 0; + bool res= 0; SELECT_LEX *first= unit->first_select(); for (SELECT_LEX *sl= first; @@ -12729,9 +12799,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) first->options | thd->options | SELECT_DESCRIBE, result, unit, first); } - if (res > 0 || thd->net.report_error) - res= -1; // mysql_explain_select do not report error - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); } @@ -12818,8 +12886,16 @@ void st_table_list::print(THD *thd, String *str) { append_identifier(thd, str, db, db_length); str->append('.'); - append_identifier(thd, str, real_name, real_name_length); - cmp_name= real_name; + if (schema_table) + { + append_identifier(thd, str, alias, strlen(alias)); + cmp_name= alias; + } + else + { + append_identifier(thd, str, real_name, real_name_length); + cmp_name= real_name; + } } if (my_strcasecmp(table_alias_charset, cmp_name, alias)) { @@ -12942,17 +13018,17 @@ void st_select_lex::print(THD *thd, String *str) res new select_result object RETURN - 0 - OK - -1 - error + FALSE - OK + TRUE - error */ -int JOIN::change_result(select_result *res) +bool JOIN::change_result(select_result *res) { DBUG_ENTER("JOIN::change_result"); result= res; if (!procedure && result->prepare(fields_list, select_lex->master_unit())) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_select.h b/sql/sql_select.h index e1bf60f6896..7fd9bf48b0b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -333,7 +333,7 @@ class JOIN :public Sql_alloc return (do_send_rows && tmp_table_param.sum_func_count != 0 && !group_list); } - int change_result(select_result *result); + bool change_result(select_result *result); }; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 557ec1bd5d2..17e6866f565 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -21,6 +21,7 @@ #include "sql_select.h" // For select_describe #include "sql_acl.h" #include "repl_failsafe.h" +#include "sp_head.h" #include <my_dir.h> #ifdef HAVE_BERKELEY_DB @@ -43,60 +44,11 @@ static int view_store_create_info(THD *thd, TABLE_LIST *table, String *packet); -/* - Report list of databases - A database is a directory in the mysql_data_home directory -*/ - -int -mysqld_show_dbs(THD *thd,const char *wild) -{ - Item_string *field=new Item_string("",0,thd->charset()); - List<Item> field_list; - char *end; - List<char> files; - char *file_name; - Protocol *protocol= thd->protocol; - DBUG_ENTER("mysqld_show_dbs"); - - field->name=(char*) thd->alloc(20+ (wild ? (uint) strlen(wild)+4: 0)); - field->max_length=NAME_LEN; - end=strmov(field->name,"Database"); - if (wild && wild[0]) - strxmov(end," (",wild,")",NullS); - field_list.push_back(field); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1)) - DBUG_RETURN(1); - List_iterator_fast<char> it(files); - - while ((file_name=it++)) - { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) || - (grant_option && !check_grant_db(thd, file_name))) -#endif - { - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - if (protocol->write()) - DBUG_RETURN(-1); - } - } - send_eof(thd); - DBUG_RETURN(0); -} - - /*************************************************************************** List all open tables in a database ***************************************************************************/ -int mysqld_show_open_tables(THD *thd,const char *wild) +bool mysqld_show_open_tables(THD *thd,const char *wild) { List<Item> field_list; OPEN_TABLE_LIST *open_list; @@ -110,10 +62,10 @@ int mysqld_show_open_tables(THD *thd,const char *wild) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (!(open_list=list_open_tables(thd,wild)) && thd->is_fatal_error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (; open_list ; open_list=open_list->next) { @@ -124,83 +76,19 @@ int mysqld_show_open_tables(THD *thd,const char *wild) protocol->store_tiny((longlong) open_list->locked); if (protocol->write()) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /*************************************************************************** -** List all tables in a database (fast version) -** A table is a .frm file in the current databasedir -***************************************************************************/ - -int mysqld_show_tables(THD *thd, const char *db, const char *wild, - bool show_type) -{ - Item_string *field=new Item_string("",0,thd->charset()); - List<Item> field_list; - char path[FN_LEN],*end; - List<char> files; - char *file_name; - Protocol *protocol= thd->protocol; - uint len; - DBUG_ENTER("mysqld_show_tables"); - - field->name=(char*) thd->alloc(20+(uint) strlen(db)+ - (wild ? (uint) strlen(wild)+4:0)); - end=strxmov(field->name,"Tables_in_",db,NullS); - if (wild && wild[0]) - strxmov(end," (",wild,")",NullS); - field->max_length=NAME_LEN; - (void) my_snprintf(path, FN_LEN, "%s/%s", mysql_data_home, db); - end= path + (len= unpack_dirname(path,path)); - len= FN_LEN - len; - field_list.push_back(field); - if (show_type) - field_list.push_back(new Item_empty_string("Table_type", 10)); - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); - List_iterator_fast<char> it(files); - while ((file_name=it++)) - { - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - if (show_type) - { - my_snprintf(end, len, "/%s%s", file_name, reg_ext); - switch (mysql_frm_type(path)) - { - case FRMTYPE_ERROR: - protocol->store("ERROR", system_charset_info); - break; - case FRMTYPE_TABLE: - protocol->store("BASE TABLE", system_charset_info); - break; - case FRMTYPE_VIEW: - protocol->store("VIEW", system_charset_info); - break; - default: - DBUG_ASSERT(0); // this should be impossible - } - } - if (protocol->write()) - DBUG_RETURN(-1); - } - send_eof(thd); - DBUG_RETURN(0); -} - -/*************************************************************************** ** List all table types supported ***************************************************************************/ -int mysqld_show_storage_engines(THD *thd) +bool mysqld_show_storage_engines(THD *thd) { List<Item> field_list; Protocol *protocol= thd->protocol; @@ -212,7 +100,7 @@ int mysqld_show_storage_engines(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); const char *default_type_name= ha_get_storage_engine((enum db_type)thd->variables.table_type); @@ -230,10 +118,10 @@ int mysqld_show_storage_engines(THD *thd) protocol->store(option_name, system_charset_info); protocol->store(types->comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -275,7 +163,7 @@ static struct show_privileges_st sys_privileges[]= {NullS, NullS, NullS} }; -int mysqld_show_privileges(THD *thd) +bool mysqld_show_privileges(THD *thd) { List<Item> field_list; Protocol *protocol= thd->protocol; @@ -287,7 +175,7 @@ int mysqld_show_privileges(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); show_privileges_st *privilege= sys_privileges; for (privilege= sys_privileges; privilege->privilege ; privilege++) @@ -297,10 +185,10 @@ int mysqld_show_privileges(THD *thd) protocol->store(privilege->context, system_charset_info); protocol->store(privilege->comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -340,7 +228,7 @@ static struct show_column_type_st sys_column_types[]= "A very small integer"}, }; -int mysqld_show_column_types(THD *thd) +bool mysqld_show_column_types(THD *thd) { List<Item> field_list; Protocol *protocol= thd->protocol; @@ -363,7 +251,7 @@ int mysqld_show_column_types(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* TODO: Change the loop to not use 'i' */ for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++) @@ -384,10 +272,10 @@ int mysqld_show_column_types(THD *thd) protocol->store(sys_column_types[i].default_value, system_charset_info); protocol->store(sys_column_types[i].comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -483,215 +371,10 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, /*************************************************************************** - Extended version of mysqld_show_tables -***************************************************************************/ - -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) -{ - Item *item; - List<char> files; - List<Item> field_list; - char path[FN_LEN]; - char *file_name; - TABLE *table; - Protocol *protocol= thd->protocol; - TIME time; - int res; - DBUG_ENTER("mysqld_extend_show_tables"); - - (void) sprintf(path,"%s/%s",mysql_data_home,db); - (void) unpack_dirname(path,path); - field_list.push_back(item=new Item_empty_string("Name",NAME_LEN)); - field_list.push_back(item=new Item_empty_string("Engine",10)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Version", (longlong) 0, 21)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Row_format",10)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Rows",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Avg_row_length",(int32) 0,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Data_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Max_data_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Index_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Data_free",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Auto_increment",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Create_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Update_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Check_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Collation",32)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Checksum",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Create_options",255)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Comment",80)); - item->maybe_null=1; - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); - List_iterator_fast<char> it(files); - while ((file_name=it++)) - { - TABLE_LIST table_list; - bzero((char*) &table_list,sizeof(table_list)); - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - table_list.db=(char*) db; - table_list.real_name= table_list.alias= file_name; - table_list.select_lex= &thd->lex->select_lex; - if (lower_case_table_names) - my_casedn_str(files_charset_info, file_name); - if ((res= open_and_lock_tables(thd, &table_list))) - { - for (uint i=2 ; i < field_list.elements ; i++) - protocol->store_null(); - // Send error to Comment field if possible - if (res < 0) - { - protocol->store(thd->net.last_error, system_charset_info); - thd->clear_error(); - } - else - DBUG_RETURN(1); - } - else if (table_list.view) - { - for (uint i= 2; i < field_list.elements; i++) - protocol->store_null(); - protocol->store("view", system_charset_info); - } - else - { - const char *str; - handler *file= (table= table_list.table)->file; - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); - protocol->store(file->table_type(), system_charset_info); - protocol->store((ulonglong) table->frm_version); - str= ((table->db_options_in_use & HA_OPTION_COMPRESS_RECORD) ? - "Compressed" : - (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - "Dynamic" : "Fixed"); - protocol->store(str, system_charset_info); - protocol->store((ulonglong) file->records); - protocol->store((ulonglong) file->mean_rec_length); - protocol->store((ulonglong) file->data_file_length); - if (file->max_data_file_length) - protocol->store((ulonglong) file->max_data_file_length); - else - protocol->store_null(); - protocol->store((ulonglong) file->index_file_length); - protocol->store((ulonglong) file->delete_length); - if (table->found_next_number_field) - { - table->next_number_field=table->found_next_number_field; - table->next_number_field->reset(); - file->update_auto_increment(); - protocol->store(table->next_number_field->val_int()); - table->next_number_field=0; - } - else - protocol->store_null(); - if (!file->create_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->create_time); - protocol->store(&time); - } - if (!file->update_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->update_time); - protocol->store(&time); - } - if (!file->check_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time); - protocol->store(&time); - } - str= (table->table_charset ? table->table_charset->name : "default"); - protocol->store(str, system_charset_info); - if (file->table_flags() & HA_HAS_CHECKSUM) - protocol->store((ulonglong)file->checksum()); - else - protocol->store_null(); // Checksum - { - char option_buff[350],*ptr; - ptr=option_buff; - if (table->min_rows) - { - ptr=strmov(ptr," min_rows="); - ptr=longlong10_to_str(table->min_rows,ptr,10); - } - if (table->max_rows) - { - ptr=strmov(ptr," max_rows="); - ptr=longlong10_to_str(table->max_rows,ptr,10); - } - if (table->avg_row_length) - { - ptr=strmov(ptr," avg_row_length="); - ptr=longlong10_to_str(table->avg_row_length,ptr,10); - } - if (table->db_create_options & HA_OPTION_PACK_KEYS) - ptr=strmov(ptr," pack_keys=1"); - if (table->db_create_options & HA_OPTION_NO_PACK_KEYS) - ptr=strmov(ptr," pack_keys=0"); - if (table->db_create_options & HA_OPTION_CHECKSUM) - ptr=strmov(ptr," checksum=1"); - if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) - ptr=strmov(ptr," delay_key_write=1"); - if (table->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) table->row_type], - NullS); - if (file->raid_type) - { - char buff[100]; - sprintf(buff," raid_type=%s raid_chunks=%d raid_chunksize=%ld", - my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE); - ptr=strmov(ptr,buff); - } - protocol->store(option_buff+1, - (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1) - , system_charset_info); - } - { - char *comment=table->file->update_table_comment(table->comment); - protocol->store(comment, system_charset_info); - if (comment != table->comment) - my_free(comment,MYF(0)); - } - } - close_thread_tables(thd, 0); - if (protocol->write()) - DBUG_RETURN(-1); - } - send_eof(thd); - DBUG_RETURN(0); -} - - -/*************************************************************************** ** List all columns in a table_list->real_name ***************************************************************************/ -int +bool mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, bool verbose) { @@ -707,11 +390,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, table_list->real_name)); table_list->lock_type= TL_UNLOCK; - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - if (res < 0) - send_error(thd); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } table= table_list->table; file=table->file; @@ -737,7 +418,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, // Send first number of fields and records if (protocol->send_records_num(&field_list, (ulonglong)file->records) || protocol->send_fields(&field_list, Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); restore_record(table,default_values); // Get empty record Field **ptr,*field; @@ -846,16 +527,16 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, system_charset_info); } if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int +bool mysqld_show_create(THD *thd, TABLE_LIST *table_list) { TABLE *table; @@ -868,18 +549,16 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) table_list->real_name)); /* Only one table for now, but VIEW can involve several tables */ - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - if (res < 0) - send_error(thd); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } /* TODO: add environment variables show when it become possible */ if (thd->lex->only_view && !table_list->view) { - my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, - table_list->real_name, "VIEW"); - DBUG_RETURN(-1); + my_error(ER_WRONG_OBJECT, MYF(0), + table_list->db, table_list->real_name, "VIEW"); + DBUG_RETURN(TRUE); } table= table_list->table; @@ -887,7 +566,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if ((table_list->view ? view_store_create_info(thd, table_list, &buffer) : store_create_info(thd, table, &buffer))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); List<Item> field_list; if (table_list->view) @@ -906,31 +585,31 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); buffer.length(0); if (table_list->view) { protocol->store(table_list->view_name.str, system_charset_info); if (view_store_create_info(thd, table_list, &buffer)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } else { protocol->store(table->table_name, system_charset_info); if (store_create_info(thd, table, &buffer)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int mysqld_show_create_db(THD *thd, char *dbname, - HA_CREATE_INFO *create_info) +bool mysqld_show_create_db(THD *thd, char *dbname, + HA_CREATE_INFO *create_info) { int length; char path[FN_REFLEN]; @@ -947,8 +626,8 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - net_printf(thd,ER_WRONG_DB_NAME, dbname); - DBUG_RETURN(1); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); + DBUG_RETURN(TRUE); } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -959,11 +638,11 @@ int mysqld_show_create_db(THD *thd, char *dbname, thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, thd->host_or_ip, dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, thd->host_or_ip, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->host_or_ip, dbname); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } #endif @@ -977,8 +656,8 @@ int mysqld_show_create_db(THD *thd, char *dbname, } if (access(path,F_OK)) { - net_printf(thd,ER_BAD_DB_ERROR,dbname); - DBUG_RETURN(1); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); + DBUG_RETURN(TRUE); } if (found_libchar) path[length-1]= FN_LIBCHAR; @@ -991,7 +670,7 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); protocol->store(dbname, strlen(dbname), system_charset_info); @@ -1016,12 +695,12 @@ int mysqld_show_create_db(THD *thd, char *dbname, protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int +bool mysqld_show_logs(THD *thd) { List<Item> field_list; @@ -1034,112 +713,15 @@ mysqld_show_logs(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); #ifdef HAVE_BERKELEY_DB if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_show_logs(protocol)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); #endif send_eof(thd); - DBUG_RETURN(0); -} - - -int -mysqld_show_keys(THD *thd, TABLE_LIST *table_list) -{ - TABLE *table; - Protocol *protocol= thd->protocol; - DBUG_ENTER("mysqld_show_keys"); - DBUG_PRINT("enter",("db: %s table: %s",table_list->db, - table_list->real_name)); - - if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) - { - send_error(thd); - DBUG_RETURN(1); - } - - List<Item> field_list; - Item *item; - field_list.push_back(new Item_empty_string("Table",NAME_LEN)); - field_list.push_back(new Item_return_int("Non_unique",1, MYSQL_TYPE_TINY)); - field_list.push_back(new Item_empty_string("Key_name",NAME_LEN)); - field_list.push_back(new Item_return_int("Seq_in_index",2, MYSQL_TYPE_TINY)); - field_list.push_back(new Item_empty_string("Column_name",NAME_LEN)); - field_list.push_back(item=new Item_empty_string("Collation",1)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Cardinality",0,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_return_int("Sub_part",3, - MYSQL_TYPE_TINY)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Packed",10)); - item->maybe_null=1; - field_list.push_back(new Item_empty_string("Null",3)); - field_list.push_back(new Item_empty_string("Index_type",16)); - field_list.push_back(new Item_empty_string("Comment",255)); - item->maybe_null=1; - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - KEY *key_info=table->key_info; - table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); - for (uint i=0 ; i < table->keys ; i++,key_info++) - { - KEY_PART_INFO *key_part= key_info->key_part; - const char *str; - for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) - { - protocol->prepare_for_resend(); - protocol->store(table->table_name, system_charset_info); - protocol->store_tiny((longlong) ((key_info->flags & HA_NOSAME) ? 0 :1)); - protocol->store(key_info->name, system_charset_info); - protocol->store_tiny((longlong) (j+1)); - str=(key_part->field ? key_part->field->field_name : - "?unknown field?"); - protocol->store(str, system_charset_info); - if (table->file->index_flags(i, j, 0) & HA_READ_ORDER) - protocol->store(((key_part->key_part_flag & HA_REVERSE_SORT) ? - "D" : "A"), 1, system_charset_info); - else - protocol->store_null(); /* purecov: inspected */ - KEY *key=table->key_info+i; - if (key->rec_per_key[j]) - { - ha_rows records=(table->file->records / key->rec_per_key[j]); - protocol->store((ulonglong) records); - } - else - protocol->store_null(); - - /* Check if we have a key part that only uses part of the field */ - if (!(key_info->flags & HA_FULLTEXT) && (!key_part->field || - key_part->length != table->field[key_part->fieldnr-1]->key_length())) - protocol->store_tiny((longlong) key_part->length); - else - protocol->store_null(); - protocol->store_null(); // No pack_information yet - - /* Null flag */ - uint flags= key_part->field ? key_part->field->flags : 0; - char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); - protocol->store((const char*) pos, system_charset_info); - protocol->store(table->file->index_type(i), system_charset_info); - /* Comment */ - if (!table->keys_in_use.is_set(i)) - protocol->store("disabled",8, system_charset_info); - else - protocol->store("", 0, system_charset_info); - if (protocol->write()) - DBUG_RETURN(1); /* purecov: inspected */ - } - } - send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1157,12 +739,8 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) DBUG_PRINT("enter",("table: %s",table_list->real_name)); table_list->lock_type= TL_UNLOCK; - if ((res= open_and_lock_tables(thd, table_list))) - { - if (res < 0) - send_error(thd); + if (open_and_lock_tables(thd, table_list)) DBUG_VOID_RETURN; - } table= table_list->table; List<Item> field_list; @@ -1816,116 +1394,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) Status functions *****************************************************************************/ -static bool write_collation(Protocol *protocol, CHARSET_INFO *cs) -{ - protocol->prepare_for_resend(); - protocol->store(cs->name, system_charset_info); - protocol->store(cs->csname, system_charset_info); - protocol->store_short((longlong) cs->number); - protocol->store((cs->state & MY_CS_PRIMARY) ? "Yes" : "",system_charset_info); - protocol->store((cs->state & MY_CS_COMPILED)? "Yes" : "",system_charset_info); - protocol->store_short((longlong) cs->strxfrm_multiply); - return protocol->write(); -} - -int mysqld_show_collations(THD *thd, const char *wild) -{ - char buff[8192]; - String packet2(buff,sizeof(buff),thd->charset()); - List<Item> field_list; - CHARSET_INFO **cs; - Protocol *protocol= thd->protocol; - - DBUG_ENTER("mysqld_show_charsets"); - - field_list.push_back(new Item_empty_string("Collation",30)); - field_list.push_back(new Item_empty_string("Charset",30)); - field_list.push_back(new Item_return_int("Id",11, FIELD_TYPE_SHORT)); - field_list.push_back(new Item_empty_string("Default",30)); - field_list.push_back(new Item_empty_string("Compiled",30)); - field_list.push_back(new Item_return_int("Sortlen",3, FIELD_TYPE_SHORT)); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) - { - CHARSET_INFO **cl; - if (!cs[0] || !(cs[0]->state & MY_CS_AVAILABLE) || - !(cs[0]->state & MY_CS_PRIMARY)) - continue; - for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) - { - if (!cl[0] || !(cl[0]->state & MY_CS_AVAILABLE) || - !my_charset_same(cs[0],cl[0])) - continue; - if (!(wild && wild[0] && - wild_case_compare(system_charset_info,cl[0]->name,wild))) - { - if (write_collation(protocol, cl[0])) - goto err; - } - } - } - send_eof(thd); - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - -static bool write_charset(Protocol *protocol, CHARSET_INFO *cs) -{ - protocol->prepare_for_resend(); - protocol->store(cs->csname, system_charset_info); - protocol->store(cs->comment ? cs->comment : "", system_charset_info); - protocol->store(cs->name, system_charset_info); - protocol->store_short((longlong) cs->mbmaxlen); - return protocol->write(); -} - -int mysqld_show_charsets(THD *thd, const char *wild) -{ - char buff[8192]; - String packet2(buff,sizeof(buff),thd->charset()); - List<Item> field_list; - CHARSET_INFO **cs; - Protocol *protocol= thd->protocol; - - DBUG_ENTER("mysqld_show_charsets"); - - field_list.push_back(new Item_empty_string("Charset",30)); - field_list.push_back(new Item_empty_string("Description",60)); - field_list.push_back(new Item_empty_string("Default collation",60)); - field_list.push_back(new Item_return_int("Maxlen",3, FIELD_TYPE_SHORT)); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) - { - if (cs[0] && (cs[0]->state & MY_CS_PRIMARY) && - (cs[0]->state & MY_CS_AVAILABLE) && - !(wild && wild[0] && - wild_case_compare(system_charset_info,cs[0]->csname,wild))) - { - if (write_charset(protocol, cs[0])) - goto err; - } - } - send_eof(thd); - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - - - -int mysqld_show(THD *thd, const char *wild, show_var_st *variables, - enum enum_var_type value_type, - pthread_mutex_t *mutex, - struct system_status_var *status_var) +bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, + enum enum_var_type value_type, + pthread_mutex_t *mutex, + struct system_status_var *status_var) { char buff[1024]; List<Item> field_list; @@ -1937,7 +1409,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, field_list.push_back(new Item_empty_string("Value",256)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ null_lex_str.str= 0; // For sys_var->value_ptr() null_lex_str.length= 0; @@ -1965,7 +1437,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, switch (show_type) { case SHOW_LONG_STATUS: case SHOW_LONG_CONST_STATUS: - value= ((char *) status_var + (uint) value); + value= ((char *) status_var + (ulong) value); /* fall through */ case SHOW_LONG: case SHOW_LONG_CONST: @@ -2229,11 +1701,11 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, } pthread_mutex_unlock(mutex); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: pthread_mutex_unlock(mutex); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } @@ -2261,6 +1733,1686 @@ void calc_sum_of_all_status(STATUS_VAR *to) } +LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, + const char* str, uint length, + bool allocate_lex_string) +{ + MEM_ROOT *mem= thd->mem_root; + if (allocate_lex_string) + lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING)); + lex_str->str= strmake_root(mem, str, length); + lex_str->length= length; + return lex_str; +} + + +/* INFORMATION_SCHEMA name */ +LEX_STRING information_schema_name= {(char*)"information_schema", 18}; +extern ST_SCHEMA_TABLE schema_tables[]; + +typedef struct st_index_field_values +{ + const char *db_value, *table_value; +} INDEX_FIELD_VALUES; + + +void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values) +{ + const char *wild= lex->wild ? lex->wild->ptr() : NullS; + switch (lex->orig_sql_command) { + case SQLCOM_SHOW_DATABASES: + index_field_values->db_value= wild; + break; + case SQLCOM_SHOW_TABLES: + case SQLCOM_SHOW_TABLE_STATUS: + index_field_values->db_value= lex->current_select->db; + index_field_values->table_value= wild; + break; + default: + index_field_values->db_value= NullS; + index_field_values->table_value= NullS; + break; + } +} + + +int make_table_list(THD *thd, SELECT_LEX *sel, + char *db, char *table) +{ + Table_ident *table_ident; + LEX_STRING ident_db, ident_table; + ident_db.str= db; + ident_db.length= strlen(db); + ident_table.str= table; + ident_table.length= strlen(table); + table_ident= new Table_ident(thd, ident_db, ident_table, 1); + sel->init_query(); + if(!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, + (List<String> *) 0, (List<String> *) 0)) + return 1; + return 0; +} + + +bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) +{ + if (item->type() == Item::FUNC_ITEM) + { + Item_func *item_func= (Item_func*)item; + Item **child; + Item **item_end= (item_func->arguments()) + item_func->argument_count(); + for (child= item_func->arguments(); child != item_end; child++) + if (!uses_only_table_name_fields(*child, table)) + return 0; + return 1; + } + else if (item->type() == Item::FIELD_ITEM) + { + Item_field *item_field= (Item_field*)item; + CHARSET_INFO *cs= system_charset_info; + ST_SCHEMA_TABLE *schema_table= table->schema_table; + ST_FIELD_INFO *field_info= schema_table->fields_info; + const char *field_name1= field_info[schema_table->idx_field1].field_name; + const char *field_name2= field_info[schema_table->idx_field2].field_name; + if(table->table != item_field->field->table || + (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1), + (uchar *) item_field->field_name, + strlen(item_field->field_name)) && + cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2), + (uchar *) item_field->field_name, + strlen(item_field->field_name)))) + return 0; + else + return 1; + } + else + return 1; +} + + +static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table) +{ + if (!cond) + return (COND*) 0; + if (cond->type() == Item::COND_ITEM) + { + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + /* Create new top level AND item */ + Item_cond_and *new_cond=new Item_cond_and; + if (!new_cond) + return (COND*) 0; + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + Item *fix= make_cond_for_info_schema(item, table); + if (fix) + new_cond->argument_list()->push_back(fix); + } + switch (new_cond->argument_list()->elements) { + case 0: + return (COND*) 0; + case 1: + return new_cond->argument_list()->head(); + default: + new_cond->quick_fix_field(); + return new_cond; + } + } + else + { // Or list + Item_cond_or *new_cond=new Item_cond_or; + if (!new_cond) + return (COND*) 0; + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + Item *fix=make_cond_for_info_schema(item, table); + if (!fix) + return (COND*) 0; + new_cond->argument_list()->push_back(fix); + } + new_cond->quick_fix_field(); + new_cond->top_level_item(); + return new_cond; + } + } + + if (!uses_only_table_name_fields(cond, table)) + return (COND*) 0; + return cond; +} + + +int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + LEX *lex= thd->lex; + TABLE *table= tables->table; + SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *lsel= tables->schema_select_lex; + ST_SCHEMA_TABLE *schema_table= tables->schema_table; + DBUG_ENTER("fill_schema_tables"); + + if (lsel) + { + TABLE *old_open_tables= thd->open_tables; + TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first; + lex->all_selects_list= lsel; + bool res= open_and_lock_tables(thd, show_table_list); + if (schema_table->process_table(thd, show_table_list, + table, res, show_table_list->db, + show_table_list->real_name)) + { + DBUG_RETURN(1); + } + close_thread_tables(thd, 0, 0, old_open_tables); + show_table_list->table= 0; + lex->all_selects_list= select_lex; + DBUG_RETURN(0); + } + + SELECT_LEX sel; + INDEX_FIELD_VALUES idx_field_vals; + char path[FN_REFLEN], *end, *base_name, *file_name; + uint len; + List<char> bases; + lex->all_selects_list= &sel; + enum enum_schema_tables schema_table_idx= + (enum enum_schema_tables) (schema_table - &schema_tables[0]); + thr_lock_type lock_type= TL_UNLOCK; + if (schema_table_idx == SCH_TABLES) + lock_type= TL_READ; + get_index_field_values(lex, &idx_field_vals); + if (mysql_find_files(thd, &bases, NullS, mysql_data_home, + idx_field_vals.db_value, 1)) + return 1; + List_iterator_fast<char> it(bases); + COND *partial_cond= make_cond_for_info_schema(cond, tables); + while ((base_name=it++) || + /* + generate error for non existing database. + (to save old behaviour for SHOW TABLES FROM db) + */ + ((lex->orig_sql_command == SQLCOM_SHOW_TABLES || + lex->orig_sql_command == SQLCOM_SHOW_TABLE_STATUS) && + (base_name= select_lex->db) && !bases.elements)) + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!check_access(thd,SELECT_ACL, base_name, &thd->col_access,0,1) || + thd->master_access & (DB_ACLS | SHOW_DB_ACL) || + acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) || + (grant_option && !check_grant_db(thd, base_name))) +#endif + { + List<char> files; + strxmov(path, mysql_data_home, "/", base_name, NullS); + end= path + (len= unpack_dirname(path,path)); + len= FN_LEN - len; + if (mysql_find_files(thd, &files, base_name, + path, idx_field_vals.table_value, 0)) + DBUG_RETURN(1); + + List_iterator_fast<char> it(files); + while ((file_name=it++)) + { + restore_record(table, default_values); + table->field[schema_table->idx_field1]-> + store(base_name, strlen(base_name), system_charset_info); + table->field[schema_table->idx_field2]-> + store(file_name, strlen(file_name),system_charset_info); + if (!partial_cond || partial_cond->val_int()) + { + if (schema_table_idx == SCH_TABLE_NAMES) + { + if (lex->verbose || lex->orig_sql_command == SQLCOM_END) + { + my_snprintf(end, len, "/%s%s", file_name, reg_ext); + switch (mysql_frm_type(path)) + { + case FRMTYPE_ERROR: + table->field[3]->store("ERROR", 5, system_charset_info); + break; + case FRMTYPE_TABLE: + table->field[3]->store("BASE TABLE", 10, system_charset_info); + break; + case FRMTYPE_VIEW: + table->field[3]->store("VIEW", 4, system_charset_info); + break; + default: + DBUG_ASSERT(0); + } + } + table->file->write_row(table->record[0]); + } + else + { + int res; + TABLE *old_open_tables= thd->open_tables; + if (make_table_list(thd, &sel, base_name, file_name)) + DBUG_RETURN(1); + TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first; + show_table_list->lock_type= lock_type; + res= open_and_lock_tables(thd, show_table_list); + if (schema_table->process_table(thd, show_table_list, table, + res, base_name, file_name)) + { + DBUG_RETURN(1); + } + close_thread_tables(thd, 0, 0, old_open_tables); + } + } + } + } + } + lex->all_selects_list= select_lex; + DBUG_RETURN(0); +} + + +int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) +{ + char path[FN_REFLEN],*end; + bool found_libchar; + INDEX_FIELD_VALUES idx_field_vals; + List<char> files; + char *file_name; + uint length; + HA_CREATE_INFO create; + TABLE *table= tables->table; + + get_index_field_values(thd->lex, &idx_field_vals); + if (mysql_find_files(thd, &files, NullS, mysql_data_home, + idx_field_vals.db_value, 1)) + return 1; + List_iterator_fast<char> it(files); + while ((file_name=it++)) + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || + acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) || + (grant_option && !check_grant_db(thd, file_name))) +#endif + { + strxmov(path, mysql_data_home, "/", file_name, NullS); + length=unpack_dirname(path,path); // Convert if not unix + found_libchar= 0; + if (length && path[length-1] == FN_LIBCHAR) + { + found_libchar= 1; + path[length-1]=0; // remove ending '\' + } + + if (found_libchar) + path[length-1]= FN_LIBCHAR; + strmov(path+length, MY_DB_OPT_FILE); + load_db_opt(thd, path, &create); + restore_record(table, default_values); + table->field[1]->store(file_name, strlen(file_name), system_charset_info); + table->field[2]->store(create.default_table_charset->csname, + strlen(create.default_table_charset->csname), + system_charset_info); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +static int get_schema_tables_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + const char *tmp_buff; + TIME time; + CHARSET_INFO *cs= system_charset_info; + + DBUG_ENTER("get_schema_tables_record"); + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + if (res) + { + /* + there was errors during opening tables + */ + const char *error= thd->net.last_error; + table->field[20]->store(error, strlen(error), cs); + thd->clear_error(); + } + else if (tables->view) + { + table->field[3]->store("VIEW", 4, cs); + table->field[20]->store("view", 4, cs); + } + else + { + TABLE *show_table= tables->table; + handler *file= show_table->file; + file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); + table->field[3]->store("BASE TABLE", 10, cs); + for (int i= 4; i < 20; i++) + { + if ((i > 12 && i < 17) || i == 18) + continue; + table->field[i]->set_notnull(); + } + tmp_buff= file->table_type(); + table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[5]->store((longlong) show_table->frm_version); + tmp_buff= ((show_table->db_options_in_use & + HA_OPTION_COMPRESS_RECORD) ? "Compressed" : + (show_table->db_options_in_use & HA_OPTION_PACK_RECORD) ? + "Dynamic" : "Fixed"); + table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[7]->store((longlong) file->records); + table->field[8]->store((longlong) file->mean_rec_length); + table->field[9]->store((longlong) file->data_file_length); + if (file->max_data_file_length) + { + table->field[10]->store((longlong) file->max_data_file_length); + } + table->field[11]->store((longlong) file->index_file_length); + table->field[12]->store((longlong) file->delete_length); + if (table->found_next_number_field) + { + show_table->next_number_field=show_table->found_next_number_field; + show_table->next_number_field->reset(); + file->update_auto_increment(); + table->field[13]->store((longlong) show_table-> + next_number_field->val_int()); + table->field[13]->set_notnull(); + show_table->next_number_field=0; + } + if (file->create_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + file->create_time); + table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[14]->set_notnull(); + } + if (file->update_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + file->update_time); + table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[15]->set_notnull(); + } + if (file->check_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time); + table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[16]->set_notnull(); + } + tmp_buff= (show_table->table_charset ? show_table-> + table_charset->name : "default"); + table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); + if (file->table_flags() & HA_HAS_CHECKSUM) + { + table->field[18]->store((longlong) file->checksum()); + table->field[18]->set_notnull(); + } + + char option_buff[350],*ptr; + ptr=option_buff; + if (show_table->min_rows) + { + ptr=strmov(ptr," min_rows="); + ptr=longlong10_to_str(show_table->min_rows,ptr,10); + } + if (show_table->max_rows) + { + ptr=strmov(ptr," max_rows="); + ptr=longlong10_to_str(show_table->max_rows,ptr,10); + } + if (show_table->avg_row_length) + { + ptr=strmov(ptr," avg_row_length="); + ptr=longlong10_to_str(show_table->avg_row_length,ptr,10); + } + if (show_table->db_create_options & HA_OPTION_PACK_KEYS) + ptr=strmov(ptr," pack_keys=1"); + if (show_table->db_create_options & HA_OPTION_NO_PACK_KEYS) + ptr=strmov(ptr," pack_keys=0"); + if (show_table->db_create_options & HA_OPTION_CHECKSUM) + ptr=strmov(ptr," checksum=1"); + if (show_table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) + ptr=strmov(ptr," delay_key_write=1"); + if (show_table->row_type != ROW_TYPE_DEFAULT) + ptr=strxmov(ptr, " row_format=", + ha_row_type[(uint) show_table->row_type], + NullS); + if (file->raid_type) + { + char buff[100]; + my_snprintf(buff,sizeof(buff), + " raid_type=%s raid_chunks=%d raid_chunksize=%ld", + my_raid_type(file->raid_type), file->raid_chunks, + file->raid_chunksize/RAID_BLOCK_SIZE); + ptr=strmov(ptr,buff); + } + table->field[19]->store(option_buff+1, + (ptr == option_buff ? 0 : + (uint) (ptr-option_buff)-1), cs); + + char *comment= show_table->file-> + update_table_comment(show_table->comment); + table->field[20]->store(comment, strlen(comment), cs); + if (comment != show_table->comment) + my_free(comment,MYF(0)); + } + table->file->write_row(table->record[0]); + DBUG_RETURN(0); +} + + +static int get_schema_column_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + TIME time; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_column_record"); + if (res) + { + DBUG_RETURN(1); + } + + TABLE *show_table= tables->table; + handler *file= show_table->file; + file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); + restore_record(show_table, default_values); + Field **ptr,*field; + int count= 0; + for (ptr=show_table->field; (field= *ptr) ; ptr++) + { + if (!wild || !wild[0] || + !wild_case_compare(system_charset_info, field->field_name,wild)) + { + uint tmp_length; + char *tmp_buff; + byte *pos; + uint flags=field->flags; + char tmp[MAX_FIELD_WIDTH]; + char tmp1[MAX_FIELD_WIDTH]; + String type(tmp,sizeof(tmp), system_charset_info); + char tmp_buffer[128]; + count++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + table->field[3]->store(field->field_name, strlen(field->field_name), + cs); + table->field[4]->store((longlong) count); + field->sql_type(type); + table->field[11]->store(type.ptr(), type.length(), cs); + tmp_buff= strchr(type.ptr(),'('); + table->field[5]->store(type.ptr(), + (tmp_buff ? tmp_buff - type.ptr() : + type.length()), cs); + + if (show_table->timestamp_field == field && + field->unireg_check != Field::TIMESTAMP_UN_FIELD) + { + table->field[15]->store("CURRENT_TIMESTAMP", 17, cs); + table->field[15]->set_notnull(); + } + else if (field->unireg_check != Field::NEXT_NUMBER && + !field->is_null() && + !(field->flags & NO_DEFAULT_VALUE_FLAG)) + { + String def(tmp1,sizeof(tmp1), cs); + type.set(tmp, sizeof(tmp), field->charset()); + field->val_str(&type); + uint dummy_errors; + def.copy(type.ptr(), type.length(), type.charset(), cs, &dummy_errors); + table->field[15]->store(def.ptr(), def.length(), def.charset()); + table->field[15]->set_notnull(); + } + else if (field->unireg_check == Field::NEXT_NUMBER || + field->maybe_null()) + table->field[15]->set_null(); // Null as default + else + { + table->field[15]->store("",0, cs); + table->field[15]->set_notnull(); + } + + pos=(byte*) ((flags & NOT_NULL_FLAG) && + field->type() != FIELD_TYPE_TIMESTAMP ? + "" : "YES"); + table->field[13]->store((const char*) pos, + strlen((const char*) pos), cs); + if (field->has_charset()) + { + table->field[6]->store((longlong) field->field_length/ + field->charset()->mbmaxlen); + } + table->field[7]->store((longlong) field->field_length); + table->field[8]->store((longlong) field->pack_length()); + table->field[9]->store((longlong) field->decimals()); + if (field->has_charset()) + { + pos=(byte*) field->charset()->csname; + table->field[10]->store((const char*) pos, + strlen((const char*) pos), cs); + table->field[10]->set_notnull(); + pos=(byte*) field->charset()->name; + table->field[12]->store((const char*) pos, + strlen((const char*) pos), cs); + table->field[12]->set_notnull(); + } + pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : + (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : + (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); + table->field[14]->store((const char*) pos, + strlen((const char*) pos), cs); + char *end=tmp; + if (field->unireg_check == Field::NEXT_NUMBER) + end=strmov(tmp,"auto_increment"); + table->field[16]->store(tmp, (uint) (end-tmp), cs); + if (thd->lex->verbose) + { + end=tmp; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint col_access; + check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, + &tables->grant.privilege, 0, 0); + col_access= get_column_grant(thd, &tables->grant, tables->db, + tables->real_name, + field->field_name) & COL_ACLS; + for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) + { + if (col_access & 1) + { + *end++=','; + end=strmov(end,grant_types.type_names[bitnr]); + } + } +#else + end=strmov(end,""); +#endif + table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); + table->field[18]->store(field->comment.str, field->comment.length, cs); + } + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(0); +} + + + +int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO *tmp_cs= cs[0]; + if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && + (tmp_cs->state & MY_CS_AVAILABLE) && + !(wild && wild[0] && + wild_case_compare(scs, tmp_cs->csname,wild))) + { + restore_record(table, default_values); + table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs); + table->field[1]->store(tmp_cs->comment ? tmp_cs->comment : "", + strlen(tmp_cs->comment ? tmp_cs->comment : ""), + scs); + table->field[2]->store(tmp_cs->name, strlen(tmp_cs->name), scs); + table->field[3]->store((longlong) tmp_cs->mbmaxlen); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO **cl; + CHARSET_INFO *tmp_cs= cs[0]; + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + !(tmp_cs->state & MY_CS_PRIMARY)) + continue; + for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) + { + CHARSET_INFO *tmp_cl= cl[0]; + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + !my_charset_same(tmp_cs, tmp_cl)) + continue; + if (!(wild && wild[0] && + wild_case_compare(scs, tmp_cl->name,wild))) + { + const char *tmp_buff; + restore_record(table, default_values); + table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs); + table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs); + table->field[2]->store((longlong) tmp_cl->number); + tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : ""; + table->field[3]->store(tmp_buff, strlen(tmp_buff), scs); + tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : ""; + table->field[4]->store(tmp_buff, strlen(tmp_buff), scs); + table->field[5]->store((longlong) tmp_cl->strxfrm_multiply); + table->file->write_row(table->record[0]); + } + } + } + return 0; +} + + +int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO **cl; + CHARSET_INFO *tmp_cs= cs[0]; + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + !(tmp_cs->state & MY_CS_PRIMARY)) + continue; + for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) + { + CHARSET_INFO *tmp_cl= cl[0]; + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + !my_charset_same(tmp_cs,tmp_cl)) + continue; + restore_record(table, default_values); + table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs); + table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +void store_schema_proc(THD *thd, TABLE *table, + TABLE *proc_table, + const char *wild) +{ + String tmp_string; + TIME time; + LEX *lex= thd->lex; + CHARSET_INFO *cs= system_charset_info; + restore_record(table, default_values); + if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && + proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE || + lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && + proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION || + lex->orig_sql_command == SQLCOM_END) + { + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[1], &tmp_string); + if (!wild || !wild[0] || !wild_compare(tmp_string.ptr(), wild, 0)) + { + table->field[3]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[0], &tmp_string); + table->field[2]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[2], &tmp_string); + table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[3], &tmp_string); + table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[5], &tmp_string); + table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[6], &tmp_string); + table->field[10]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[7], &tmp_string); + table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[9], &tmp_string); + table->field[6]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[10], &tmp_string); + table->field[8]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[11], &tmp_string); + table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); + bzero((char *)&time, sizeof(time)); + ((Field_timestamp *) proc_table->field[12])->get_time(&time); + table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + bzero((char *)&time, sizeof(time)); + ((Field_timestamp *) proc_table->field[13])->get_time(&time); + table->field[13]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + get_field(thd->mem_root, proc_table->field[14], &tmp_string); + table->field[16]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[15], &tmp_string); + table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[7]->store("SQL", 3, cs); + table->field[9]->store("SQL", 3, cs); + table->file->write_row(table->record[0]); + } + } +} + + +int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *proc_table; + TABLE_LIST proc_tables; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + int res= 0; + TABLE *table= tables->table, *old_open_tables= thd->open_tables; + DBUG_ENTER("fill_schema_proc"); + + bzero((char*) &proc_tables,sizeof(proc_tables)); + proc_tables.db= (char*) "mysql"; + proc_tables.real_name= proc_tables.alias= (char*) "proc"; + proc_tables.lock_type= TL_READ; + if (!(proc_table= open_ltable(thd, &proc_tables, TL_READ))) + { + DBUG_RETURN(1); + } + proc_table->file->ha_index_init(0); + if ((res= proc_table->file->index_first(proc_table->record[0]))) + { + res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; + goto err; + } + store_schema_proc(thd, table, proc_table, wild); + while (!proc_table->file->index_next(proc_table->record[0])) + store_schema_proc(thd, table, proc_table, wild); + +err: + proc_table->file->ha_index_end(); + close_thread_tables(thd, 0, 0, old_open_tables); + DBUG_RETURN(res); +} + + +static int get_schema_stat_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_stat_record"); + if (!res) + { + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++,key_info++) + { + KEY_PART_INFO *key_part= key_info->key_part; + const char *str; + for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) + { + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + table->field[3]->store((longlong) ((key_info->flags & + HA_NOSAME) ? 0 :1)); + table->field[4]->store(base_name, strlen(base_name), cs); + table->field[5]->store(key_info->name, strlen(key_info->name), cs); + table->field[6]->store((longlong) (j+1)); + str=(key_part->field ? key_part->field->field_name : + "?unknown field?"); + table->field[7]->store(str, strlen(str), cs); + if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER) + { + table->field[8]->store(((key_part->key_part_flag & + HA_REVERSE_SORT) ? + "D" : "A"), 1, cs); + table->field[8]->set_notnull(); + } + KEY *key=show_table->key_info+i; + if (key->rec_per_key[j]) + { + ha_rows records=(show_table->file->records / + key->rec_per_key[j]); + table->field[9]->store((longlong) records); + table->field[9]->set_notnull(); + } + if (!(key_info->flags & HA_FULLTEXT) && + (!key_part->field || + key_part->length != + show_table->field[key_part->fieldnr-1]->key_length())) + { + table->field[10]->store((longlong) key_part->length); + table->field[10]->set_notnull(); + } + uint flags= key_part->field ? key_part->field->flags : 0; + const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); + table->field[12]->store(pos, strlen(pos), cs); + pos= show_table->file->index_type(i); + table->field[13]->store(pos, strlen(pos), cs); + if (!show_table->keys_in_use.is_set(i)) + table->field[14]->store("disabled", 8, cs); + else + table->field[14]->store("", 0, cs); + table->field[14]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + } + DBUG_RETURN(res); +} + + +static int get_schema_views_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_views_record"); + if (!res) + { + if (tables->view) + { + restore_record(table, default_values); + table->field[1]->store(tables->view_db.str, tables->view_db.length, cs); + table->field[2]->store(tables->view_name.str,tables->view_name.length,cs); + table->field[3]->store(tables->query.str, tables->query.length, cs); + + if (tables->with_check != VIEW_CHECK_NONE) + { + if (tables->with_check == VIEW_CHECK_LOCAL) + table->field[4]->store("WITH LOCAL CHECK OPTION", 23, cs); + else + table->field[4]->store("WITH CASCADED CHECK OPTION", 26, cs); + } + else + table->field[4]->store("NONE", 4, cs); + + if (tables->updatable_view) + table->field[5]->store("YES", 3, cs); + else + table->field[5]->store("NO", 2, cs); + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(res); +} + + +static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_constarints_record"); + if (!res) + { + List<FOREIGN_KEY_INFO> f_key_list; + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + uint primary_key= show_table->primary_key; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++, key_info++) + { + if (i != primary_key && !(key_info->flags & HA_NOSAME)) + continue; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(key_info->name, strlen(key_info->name), cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + if (i == primary_key && !strcmp(key_info->name, primary_key_name)) + table->field[5]->store("PRIMARY KEY", 11, cs); + else if (key_info->flags & HA_NOSAME) + table->field[5]->store("UNIQUE", 6, cs); + table->file->write_row(table->record[0]); + } + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list); + while ((f_key_info=it++)) + { + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store("FOREIGN KEY", 11, system_charset_info); + table->field[6]->store(f_key_info->constraint_method->str, + f_key_info->constraint_method->length, cs); + table->field[6]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(res); +} + + +static int get_schema_key_column_usage_record(THD *thd, + struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) +{ + DBUG_ENTER("get_schema_key_column_usage_record"); + CHARSET_INFO *cs= system_charset_info; + if (!res) + { + List<FOREIGN_KEY_INFO> f_key_list; + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + uint primary_key= show_table->primary_key; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++, key_info++) + { + if (i != primary_key && !(key_info->flags & HA_NOSAME)) + continue; + uint f_idx= 0; + KEY_PART_INFO *key_part= key_info->key_part; + for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) + { + uint f_idx= 0; + if (key_part->field) + { + f_idx++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(key_info->name, strlen(key_info->name), cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store(key_part->field->field_name, + strlen(key_part->field->field_name), cs); + table->field[6]->store((longlong) f_idx); + table->file->write_row(table->record[0]); + } + } + } + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list); + while ((f_key_info= it++)) + { + LEX_STRING *f_info, *r_info; + List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields), + it1(f_key_info->referenced_fields); + uint f_idx= 0; + while ((f_info= it++)) + { + r_info= it1++; + f_idx++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store(f_info->str, f_info->length, cs); + table->field[6]->store((longlong) f_idx); + table->field[7]->store(f_key_info->referenced_db->str, + f_key_info->referenced_db->length, cs); + table->field[7]->set_notnull(); + table->field[8]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + table->field[8]->set_notnull(); + table->field[9]->store(r_info->str, r_info->length, cs); + table->field[9]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + } + DBUG_RETURN(res); +} + + +/* + Find schema_tables elment by name + + SYNOPSIS + find_schema_table() + thd thread handler + table_name table name + + RETURN + 0 table not found + # pointer to 'shema_tables' element +*/ + +ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name) +{ + ST_SCHEMA_TABLE *schema_table= schema_tables; + for ( ; schema_table->table_name; schema_table++) + { + if (!my_strcasecmp(system_charset_info, + schema_table->table_name, + table_name)) + return schema_table; + } + return 0; +} + + +ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx) +{ + return &schema_tables[schema_table_idx]; +} + + +/* + Create information_schema table using schema_table data + + SYNOPSIS + create_schema_table() + thd thread handler + schema_table pointer to 'shema_tables' element + + RETURN + # Pointer to created table + 0 Can't create table +*/ + +TABLE *create_schema_table(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + int field_count= 0; + Item *item; + TABLE *table; + List<Item> field_list; + ST_FIELD_INFO *fields_info= schema_table->fields_info; + DBUG_ENTER("create_schema_table"); + + for ( ; fields_info->field_name; fields_info++) + { + switch (fields_info->field_type) { + case MYSQL_TYPE_LONG: + if (!(item= new Item_int(fields_info->field_name, + fields_info->value, + fields_info->field_length))) + { + DBUG_RETURN(0); + } + break; + case MYSQL_TYPE_TIMESTAMP: + if (!(item=new Item_datetime(fields_info->field_name))) + { + DBUG_RETURN(0); + } + break; + default: + CHARSET_INFO *cs= system_charset_info; + if (fields_info->utf8) + cs= thd->charset(); + if (!(item= new Item_string("", fields_info->field_length, cs))) + { + DBUG_RETURN(0); + } + item->set_name(fields_info->field_name, + strlen(fields_info->field_name), cs); + break; + } + field_list.push_back(item); + item->maybe_null= fields_info->maybe_null; + field_count++; + } + TMP_TABLE_PARAM *tmp_table_param = + (TMP_TABLE_PARAM*) (thd->calloc(sizeof(TMP_TABLE_PARAM))); + tmp_table_param->init(); + tmp_table_param->field_count= field_count; + SELECT_LEX *select_lex= thd->lex->current_select; + if (!(table= create_tmp_table(thd, tmp_table_param, + field_list, (ORDER*) 0, 0, 0, + (select_lex->options | thd->options | + TMP_TABLE_ALL_COLUMNS), + HA_POS_ERROR, + (char *) schema_table->table_name))) + DBUG_RETURN(0); + DBUG_RETURN(table); +} + + +/* + For old SHOW compatibility. It is used when + old SHOW doesn't have generated column names + Make list of fields for SHOW + + SYNOPSIS + make_old_format() + thd thread handler + schema_table pointer to 'schema_tables' element + + RETURN + -1 errror + 0 success +*/ + +int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + ST_FIELD_INFO *field_info= schema_table->fields_info; + for ( ; field_info->field_name; field_info++) + { + if (field_info->old_name) + { + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) + { + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; + } + } + } + return 0; +} + + +int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + char tmp[128]; + LEX *lex= thd->lex; + SELECT_LEX *sel= lex->current_select; + + if (!sel->item_list.elements) + { + ST_FIELD_INFO *field_info= &schema_table->fields_info[1]; + String buffer(tmp,sizeof(tmp), system_charset_info); + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (!field || add_item_to_list(thd, field)) + return 1; + buffer.length(0); + buffer.append(field_info->old_name); + if (lex->wild && lex->wild->ptr()) + { + buffer.append(" ("); + buffer.append(lex->wild->ptr()); + buffer.append(")"); + } + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + } + return 0; +} + + +int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + char tmp[128]; + String buffer(tmp,sizeof(tmp), thd->charset()); + LEX *lex= thd->lex; + + ST_FIELD_INFO *field_info= &schema_table->fields_info[2]; + buffer.length(0); + buffer.append(field_info->old_name); + buffer.append(lex->select_lex.db); + if (lex->wild && lex->wild->ptr()) + { + buffer.append(" ("); + buffer.append(lex->wild->ptr()); + buffer.append(")"); + } + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (add_item_to_list(thd, field)) + return 1; + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + if (thd->lex->verbose) + { + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field_info= &schema_table->fields_info[3]; + field= new Item_field(NullS, NullS, field_info->field_name); + if (add_item_to_list(thd, field)) + return 1; + field->set_name(field_info->old_name, strlen(field_info->old_name), + system_charset_info); + } + return 0; +} + + +int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + ST_FIELD_INFO *field_info= &schema_table->fields_info[3]; + int count= 2; + for ( ; field_info->field_name; field_info++) + { + count++; + if (field_info->old_name) + { + if (!thd->lex->verbose && (count == 12 ||count == 17 || count == 18)) + continue; + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) + { + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; + } + } + } + return 0; +} + + +/* + Create information_schema table + + SYNOPSIS + mysql_schema_table() + thd thread handler + lex pointer to LEX + table_list pointer to table_list + + RETURN + 0 success + 1 error +*/ + +int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) +{ + TABLE *table; + DBUG_ENTER("mysql_schema_table"); + if (!(table= table_list->schema_table-> + create_table(thd, table_list->schema_table))) + { + DBUG_RETURN(1); + } + table->tmp_table= TMP_TABLE; + table->grant.privilege= SELECT_ACL; + table_list->real_name= table->real_name; + table_list->table= table; + table->next= thd->derived_tables; + thd->derived_tables= table; + table_list->select_lex->options |= OPTION_SCHEMA_TABLE; + DBUG_RETURN(0); +} + + +/* + Generate select from information_schema table + + SYNOPSIS + make_schema_select() + thd thread handler + sel pointer to SELECT_LEX + schema_table_idx index of 'schema_tables' element + + RETURN + 0 success + 1 error +*/ + +int make_schema_select(THD *thd, SELECT_LEX *sel, + enum enum_schema_tables schema_table_idx) +{ + ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx); + LEX_STRING db, table; + DBUG_ENTER("mysql_schema_select"); + /* + We have to make non const db_name & table_name + because of lower_case_table_names + */ + make_lex_string(thd, &db, information_schema_name.str, + information_schema_name.length, 0); + make_lex_string(thd, &table, schema_table->table_name, + strlen(schema_table->table_name), 0); + if (!sel->item_list.elements && /* Handle old syntax */ + schema_table->old_format(thd, schema_table) || + !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0), + 0, 0, TL_READ, (List<String> *) 0, + (List<String> *) 0)) + { + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + +/* + Fill temporaty schema tables before SELECT + + SYNOPSIS + get_schema_tables_result() + join join which use schema tables + + RETURN + FALSE success + TRUE error +*/ + +bool get_schema_tables_result(JOIN *join) +{ + DBUG_ENTER("get_schema_tables_result"); + JOIN_TAB *tmp_join_tab= join->join_tab+join->tables; + THD *thd= join->thd; + for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++) + { + if (!tab->table || !tab->table->pos_in_table_list) + break; + TABLE_LIST *table_list= tab->table->pos_in_table_list; + TABLE_LIST *save_next_global= table_list->next_global; + + if (table_list->schema_table && thd->fill_derived_tables()) + { + TABLE *old_derived_tables= thd->derived_tables; + thd->derived_tables= 0; + thd->lex->sql_command= SQLCOM_SHOW_FIELDS; + table_list->table->file->records= 0; + MYSQL_LOCK *sql_lock= thd->lock; + thd->lock=0; + if (table_list->schema_table->fill_table(thd, table_list, + tab->select_cond)) + { + thd->derived_tables= old_derived_tables; + thd->lock= sql_lock; + table_list->next_global= save_next_global; + DBUG_RETURN(TRUE); + } + thd->lock= sql_lock; + thd->lex->sql_command= SQLCOM_SELECT; + thd->derived_tables= old_derived_tables; + table_list->next_global= save_next_global; + } + } + DBUG_RETURN(FALSE); +} + + +ST_FIELD_INFO schema_fields_info[]= +{ + {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Database"}, + {"DEFAULT_CHARACTER_SET_NAME", 60, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO tables_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Name"}, + {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, "Engine"}, + {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Version"}, + {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, 1, "Row_format"}, + {"ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Rows"}, + {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Avg_row_length"}, + {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Data_length"}, + {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Max_data_length"}, + {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Index_length"}, + {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Data_free"}, + {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Auto_increment"}, + {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Create_time"}, + {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Update_time"}, + {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Check_time"}, + {"COLLATION", 60, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Checksum"}, + {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, 1, "Create_options"}, + {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO columns_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Field"}, + {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"DATA_TYPE", 40, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"CHARACTER_SET_NAME", 40, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TYPE", 40, MYSQL_TYPE_STRING, 0, 0, 1, "Type"}, + {"COLLATION_NAME", 40, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Null"}, + {"KEY", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Key"}, + {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, "Default"}, + {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, 1, "Extra"}, + {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Privileges"}, + {"COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO charsets_fields_info[]= +{ + {"CHARACTER_SET_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Charset"}, + {"Description", 60, MYSQL_TYPE_STRING, 0, 0, 1, "Description"}, + {"DEFAULT_COLLATE_NAME", 60, MYSQL_TYPE_STRING, 0, 0, 1, "Default collation"}, + {"Maxlen", 3 ,MYSQL_TYPE_LONG, 0, 0, 0, "Maxlen"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO collation_fields_info[]= +{ + {"COLLATION_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Collation"}, + {"Charset", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Charset"}, + {"Id", 11, MYSQL_TYPE_LONG, 0, 0, 0, "Id"}, + {"Default", 30 ,MYSQL_TYPE_STRING, 0, 0, 1, "Default"}, + {"Compiled", 30 ,MYSQL_TYPE_STRING, 0, 0, 1, "Compiled"}, + {"Sortlen", 3 ,MYSQL_TYPE_LONG, 0, 0, 0, "Sortlen"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO coll_charset_app_fields_info[]= +{ + {"COLLATION_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHARACTER_SET_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO proc_fields_info[]= +{ + {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Db"}, + {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Name"}, + {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 1, "Type"}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 1, "Definer"}, + {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_BODY", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PARAMETER_STYLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0, "Modified"}, + {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 1, "Created"}, + {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 1, "Security_type"}, + {"SQL_MODE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO stat_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Table"}, + {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, 0, "Non_unique"}, + {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Key_name"}, + {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, 0, "Seq_in_index"}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Column_name"}, + {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, 0, "Cardinality"}, + {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, 0, "Sub_part"}, + {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, 1, "Packed"}, + {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Null"}, + {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, 1, "Index_type"}, + {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO view_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHECK_OPTION", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO user_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO schema_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO column_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_constraints_fields_info[]= +{ + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_METHOD", 20, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO key_column_usage_fields_info[]= +{ + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_names_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Tables_in_"}, + {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Table_type"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +/* + Description of ST_FIELD_INFO in table.h +*/ + +ST_SCHEMA_TABLE schema_tables[]= +{ + {"SCHEMATA", schema_fields_info, create_schema_table, + fill_schema_shemata, make_schemata_old_format, 0, 1, -1}, + {"TABLES", tables_fields_info, create_schema_table, + get_all_tables, make_old_format, get_schema_tables_record, 1, 2}, + {"COLUMNS", columns_fields_info, create_schema_table, + get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2}, + {"CHARACTER_SETS", charsets_fields_info, create_schema_table, + fill_schema_charsets, make_old_format, 0, -1, -1}, + {"COLLATIONS", collation_fields_info, create_schema_table, + fill_schema_collation, make_old_format, 0, -1, -1}, + {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, + create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1}, + {"ROUTINES", proc_fields_info, create_schema_table, + fill_schema_proc, make_old_format, 0, -1, -1}, + {"STATISTICS", stat_fields_info, create_schema_table, + get_all_tables, make_old_format, get_schema_stat_record, 1, 2}, + {"VIEWS", view_fields_info, create_schema_table, + get_all_tables, 0, get_schema_views_record, 1, 2}, + {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, + fill_schema_user_privileges, 0, 0, -1, -1}, + {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, + fill_schema_schema_privileges, 0, 0, -1, -1}, + {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, + fill_schema_table_privileges, 0, 0, -1, -1}, + {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, + fill_schema_column_privileges, 0, 0, -1, -1}, + {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, + get_all_tables, 0, get_schema_constarints_record, 3, 4}, + {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, + get_all_tables, 0, get_schema_key_column_usage_record, 3, 4}, + {"TABLE_NAMES", table_names_fields_info, create_schema_table, + get_all_tables, make_table_names_old_format, 0, 1, 2}, + {0, 0, 0, 0, 0, 0, 0, 0} +}; + + #ifdef __GNUC__ template class List_iterator_fast<char>; template class List<char>; diff --git a/sql/sql_string.h b/sql/sql_string.h index cb5b1fb25fd..2101db40f92 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -141,6 +141,34 @@ public: bool set(longlong num, CHARSET_INFO *cs); bool set(ulonglong num, CHARSET_INFO *cs); bool set(double num,uint decimals, CHARSET_INFO *cs); + + /* + PMG 2004.11.12 + This is a method that works the same as perl's "chop". It simply + drops the last character of a string. This is useful in the case + of the federated storage handler where I'm building a unknown + number, list of values and fields to be used in a sql insert + statement to be run on the remote server, and have a comma after each. + When the list is complete, I "chop" off the trailing comma + + ex. + String stringobj; + stringobj.append("VALUES ('foo', 'fi', 'fo',"); + stringobj.chop(); + stringobj.append(")"); + + In this case, the value of string was: + + VALUES ('foo', 'fi', 'fo', + VALUES ('foo', 'fi', 'fo' + VALUES ('foo', 'fi', 'fo') + + */ + inline void chop() + { + Ptr[str_length--]= '\0'; + } + inline void free() { if (alloced) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e73bf81eb74..8ff2fa5faa8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -63,15 +63,15 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set. RETURN - 0 ok. In this case ok packet is sent to user - -1 Error (Error message given but not sent to user) + FALSE OK. In this case ok packet is sent to user + TRUE Error */ -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary) +bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary) { - int error= 0; + bool error= FALSE; DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ @@ -84,9 +84,8 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, { if (thd->global_read_lock) { - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), - tables->real_name); - error= 1; + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->real_name); + error= TRUE; goto err; } while (global_read_lock && ! thd->killed) @@ -106,9 +105,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, pthread_mutex_unlock(&thd->mysys_var->mutex); if (error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -268,9 +267,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (wrong_tables.length()) { if (!foreign_key_error) - my_error(ER_BAD_TABLE_ERROR,MYF(0), wrong_tables.c_ptr()); + my_error(ER_BAD_TABLE_ERROR, MYF(0), wrong_tables.c_ptr()); else - my_error(ER_ROW_IS_REFERENCED, MYF(0)); + my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; } @@ -485,7 +484,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (field_no < select_field_pos || dup_no >= select_field_pos) { - my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); + my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name); DBUG_RETURN(-1); } else @@ -537,8 +536,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_SPATIAL if (!(file->table_flags() & HA_CAN_GEOMETRY)) { - my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), - MYF(0), "GEOMETRY"); + my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY"); DBUG_RETURN(-1); } sql_field->pack_flag=FIELDFLAG_GEOM | @@ -551,8 +549,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, blob_columns++; break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif /*HAVE_SPATIAL*/ case FIELD_TYPE_VAR_STRING: @@ -626,24 +624,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (timestamps_with_niladic > 1) { - my_error(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,MYF(0)); + my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS, + ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0)); DBUG_RETURN(-1); } if (auto_increment > 1) { - my_error(ER_WRONG_AUTO_KEY,MYF(0)); + my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); DBUG_RETURN(-1); } if (auto_increment && (file->table_flags() & HA_NO_AUTO_INCREMENT)) { - my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, + ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); DBUG_RETURN(-1); } if (blob_columns && (file->table_flags() & HA_NO_BLOBS)) { - my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), + MYF(0)); DBUG_RETURN(-1); } @@ -669,9 +670,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (fk_key->ref_columns.elements && fk_key->ref_columns.elements != fk_key->columns.elements) { - my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : - "foreign key without name", - ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + my_error(ER_WRONG_FK_DEF, MYF(0), + (fk_key->name ? fk_key->name : "foreign key without name"), + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); DBUG_RETURN(-1); } continue; @@ -770,8 +771,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info->flags= HA_SPATIAL; break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif case Key::FOREIGN_KEY: @@ -793,7 +794,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT), + MYF(0)); DBUG_RETURN(-1); } } @@ -810,8 +812,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (key_info->key_parts != 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX"); DBUG_RETURN(-1); } } @@ -821,17 +822,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); } /* TODO: To be deleted */ - my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET), - MYF(0), "RTREE INDEX"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_rtree.name, sym_group_rtree.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_rtree.name, sym_group_rtree.needed_define); DBUG_RETURN(-1); #endif } @@ -849,9 +848,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, field++; if (!sql_field) { - my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, - ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), - column->field_name); + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name); DBUG_RETURN(-1); } /* for fulltext keys keyseg length is 1 for blobs (it's ignored in @@ -869,8 +866,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet (ft_key_charset && sql_field->charset != ft_key_charset)) { - my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), - column->field_name); + my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name); DBUG_RETURN(-1); } ft_key_charset=sql_field->charset; @@ -891,15 +887,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_INDEX_BLOBS)) { - my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), - column->field_name); + my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name); DBUG_RETURN(-1); } if (!column->length) { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); + my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name); DBUG_RETURN(-1); } } @@ -928,13 +921,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info->flags|= HA_NULL_PART_KEY; if (!(file->table_flags() & HA_NULL_IN_KEY)) { - my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), - MYF(0),column->field_name); + my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name); DBUG_RETURN(-1); } if (key->type == Key::SPATIAL) { - my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); + my_message(ER_SPATIAL_CANT_HAVE_NULL, + ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); DBUG_RETURN(-1); } } @@ -980,7 +973,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, (key_info->flags & HA_NOSAME))) && column->length != length))) { - my_error(ER_WRONG_SUB_KEY,MYF(0)); + my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0)); DBUG_RETURN(-1); } else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) @@ -988,8 +981,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0) { - my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), - column->field_name); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); DBUG_RETURN(-1); } if (length > file->max_key_part_length()) @@ -1033,7 +1025,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (primary_key) { - my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); + my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY), + MYF(0)); DBUG_RETURN(-1); } key_name=primary_key_name; @@ -1044,7 +1037,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info_buffer,key_info); if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) { - my_error(ER_DUP_KEYNAME,MYF(0),key_name); + my_error(ER_DUP_KEYNAME, MYF(0), key_name); DBUG_RETURN(-1); } key_info->name=(char*) key_name; @@ -1069,12 +1062,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!unique_key && !primary_key && (file->table_flags() & HA_REQUIRE_PRIMARY_KEY)) { - my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0)); + my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0)); DBUG_RETURN(-1); } if (auto_increment > 0) { - my_error(ER_WRONG_AUTO_KEY,MYF(0)); + my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); DBUG_RETURN(-1); } /* Sort keys in optimized order */ @@ -1108,30 +1101,31 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, and must be zero for standard create of table. RETURN VALUES - 0 ok - -1 error + FALSE OK + TRUE error */ -int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List<create_field> &fields, - List<Key> &keys,bool tmp_table, - uint select_field_count) +bool mysql_create_table(THD *thd,const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + List<create_field> &fields, + List<Key> &keys,bool tmp_table, + uint select_field_count) { char path[FN_REFLEN]; const char *alias; - int error= -1; uint db_options, key_count; KEY *key_info_buffer; handler *file; + bool error= TRUE; enum db_type new_db_type; DBUG_ENTER("mysql_create_table"); /* Check for duplicate fields and check type of table to create */ if (!fields.elements) { - my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); - DBUG_RETURN(-1); + my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS), + MYF(0)); + DBUG_RETURN(TRUE); } if ((new_db_type= ha_checktype(create_info->db_type)) != create_info->db_type) @@ -1160,8 +1154,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && (file->table_flags() & HA_NO_TEMP_TABLES)) { - my_error(ER_ILLEGAL_HA,MYF(0),table_name); - DBUG_RETURN(-1); + my_error(ER_ILLEGAL_HA, MYF(0), table_name); + DBUG_RETURN(TRUE); } #endif @@ -1186,7 +1180,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, keys, tmp_table, db_options, file, key_info_buffer, &key_count, select_field_count)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check if table exists */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) @@ -1209,10 +1203,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { create_info->table_existed= 1; // Mark that table existed - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd, 0, 1)) DBUG_RETURN(error); @@ -1224,10 +1218,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { create_info->table_existed= 1; // Mark that table existed - error= 0; + error= FALSE; } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto end; } } @@ -1253,10 +1247,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_if_not_exists) { create_info->table_existed= 1; // Mark that table existed - error= 0; + error= FALSE; } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto end; } } @@ -1292,7 +1286,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } - error=0; + error= FALSE; end: VOID(pthread_mutex_unlock(&LOCK_open)); start_waiting_global_read_lock(thd); @@ -1422,7 +1416,6 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } table->file->extra(HA_EXTRA_WRITE_CACHE); DBUG_RETURN(table); - /* Note that leaving the function resets binlogging properties */ } @@ -1565,7 +1558,7 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, protocol->store((char*) operator_name, system_charset_info); protocol->store("error", 5, system_charset_info); protocol->store(errmsg, system_charset_info); - thd->net.last_error[0]=0; + thd->clear_error(); if (protocol->write()) return -1; return 1; @@ -1742,20 +1735,20 @@ end: /* RETURN VALUES - 0 Message sent to net (admin operation went ok) - -1 Message should be sent by caller - (admin operation or network communication failed) + FALSE Message sent to net (admin operation went ok) + TRUE Message should be sent by caller + (admin operation or network communication failed) */ -static int mysql_admin_table(THD* thd, TABLE_LIST* tables, - HA_CHECK_OPT* check_opt, - const char *operator_name, - thr_lock_type lock_type, - bool open_for_modify, - uint extra_open_options, - int (*prepare_func)(THD *, TABLE_LIST *, - HA_CHECK_OPT *), - int (handler::*operator_func) - (THD *, HA_CHECK_OPT *)) +static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, + HA_CHECK_OPT* check_opt, + const char *operator_name, + thr_lock_type lock_type, + bool open_for_modify, + uint extra_open_options, + int (*prepare_func)(THD *, TABLE_LIST *, + HA_CHECK_OPT *), + int (handler::*operator_func) + (THD *, HA_CHECK_OPT *)) { TABLE_LIST *table; List<Item> field_list; @@ -1773,7 +1766,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, item->maybe_null = 1; if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL); for (table= tables; table; table= table->next_local) @@ -1785,9 +1778,6 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, thd->open_options|= extra_open_options; table->table = open_ltable(thd, table, lock_type); -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; // these errors shouldn't get client -#endif thd->open_options&= ~extra_open_options; if (prepare_func) @@ -1813,7 +1803,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (!(err_msg=thd->net.last_error)) err_msg=ER(ER_CHECK_NO_SUCH_TABLE); protocol->store(err_msg, system_charset_info); - thd->net.last_error[0]=0; + thd->clear_error(); if (protocol->write()) goto err; continue; @@ -1857,9 +1847,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, } int result_code = (table->table->file->*operator_func)(thd, check_opt); -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; // these errors shouldn't get client -#endif + thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); @@ -1960,16 +1948,16 @@ send_result_message: } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } -int mysql_backup_table(THD* thd, TABLE_LIST* table_list) +bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_backup_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, @@ -1978,7 +1966,7 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list) } -int mysql_restore_table(THD* thd, TABLE_LIST* table_list) +bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, @@ -1988,7 +1976,7 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list) } -int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, @@ -1998,7 +1986,7 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) } -int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, @@ -2016,11 +2004,11 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + FALSE ok + TRUE error */ -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, +bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, LEX_STRING *key_cache_name) { HA_CHECK_OPT check_opt; @@ -2033,7 +2021,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, { pthread_mutex_unlock(&LOCK_global_system_variables); my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } pthread_mutex_unlock(&LOCK_global_system_variables); check_opt.key_cache= key_cache; @@ -2091,11 +2079,11 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + FALSE ok + TRUE error */ -int mysql_preload_keys(THD* thd, TABLE_LIST* tables) +bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) { DBUG_ENTER("mysql_preload_keys"); DBUG_RETURN(mysql_admin_table(thd, tables, 0, @@ -2115,13 +2103,13 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) table_ident Src table_ident RETURN VALUES - 0 ok - -1 error + FALSE OK + TRUE error */ -int mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *create_info, - Table_ident *table_ident) +bool mysql_create_like_table(THD* thd, TABLE_LIST* table, + HA_CREATE_INFO *create_info, + Table_ident *table_ident) { TABLE **tmp_table; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; @@ -2129,7 +2117,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, char *table_name= table->real_name; char *src_db= thd->db; char *src_table= table_ident->table.str; - int err, res= -1; + int err; + bool res= TRUE; TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); @@ -2142,7 +2131,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } bzero((gptr)&src_tables_list, sizeof(src_tables_list)); @@ -2229,7 +2218,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } - res= 0; + res= FALSE; goto err; table_exists: @@ -2240,7 +2229,7 @@ table_exists: ER(ER_TABLE_EXISTS_ERROR), table_name); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_TABLE_EXISTS_ERROR,warn_buff); - res= 0; + res= FALSE; } else my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); @@ -2253,7 +2242,7 @@ err: } -int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { #ifdef OS2 thr_lock_type lock_type = TL_WRITE; @@ -2268,7 +2257,7 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) } -int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) +bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) { #ifdef OS2 thr_lock_type lock_type = TL_WRITE; @@ -2559,13 +2548,13 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, Alter table */ -int mysql_alter_table(THD *thd,char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - List<create_field> &fields, List<Key> &keys, - uint order_num, ORDER *order, - enum enum_duplicates handle_duplicates, - ALTER_INFO *alter_info, bool do_send_ok) +bool mysql_alter_table(THD *thd,char *new_db, char *new_name, + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List<create_field> &fields, List<Key> &keys, + uint order_num, ORDER *order, + enum enum_duplicates handle_duplicates, + ALTER_INFO *alter_info, bool do_send_ok) { TABLE *table,*new_table=0; int error; @@ -2594,7 +2583,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check that we are not trying to rename to an existing table */ if (new_name) @@ -2625,8 +2614,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (find_temporary_table(thd,new_db,new_name_buff)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); - DBUG_RETURN(-1); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); + DBUG_RETURN(TRUE); } } else @@ -2637,8 +2626,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, F_OK)) { /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); - DBUG_RETURN(-1); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); + DBUG_RETURN(TRUE); } } } @@ -2678,7 +2667,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, error=0; if (!access(new_name_buff,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name); error= -1; } else @@ -2822,8 +2811,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->sql_type == FIELD_TYPE_BLOB) { - my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); - DBUG_RETURN(-1); + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change); + DBUG_RETURN(TRUE); } def->def=alter->def; // Use new default alter_it.remove(); @@ -2836,8 +2825,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->change && ! def->field) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name); - DBUG_RETURN(-1); + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table_name); + DBUG_RETURN(TRUE); } if (!def->after) create_list.push_back(def); @@ -2854,22 +2843,23 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (!find) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); - DBUG_RETURN(-1); + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table_name); + DBUG_RETURN(TRUE); } find_it.after(def); // Put element after this } } if (alter_info->alter_list.elements) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),alter_info->alter_list.head()->name, - table_name); - DBUG_RETURN(-1); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + alter_info->alter_list.head()->name, table_name); + DBUG_RETURN(TRUE); } if (!create_list.elements) { - my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0)); - DBUG_RETURN(-1); + my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), + MYF(0)); + DBUG_RETURN(TRUE); } /* @@ -2958,21 +2948,21 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } if (alter_info->drop_list.elements) { - my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0), - alter_info->drop_list.head()->name); + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->drop_list.head()->name); goto err; } if (alter_info->alter_list.elements) { - my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0), - alter_info->alter_list.head()->name); + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->alter_list.head()->name); goto err; } @@ -3175,7 +3165,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!access(new_name_buff,F_OK)) { error=1; - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; @@ -3313,10 +3303,10 @@ end_temporary: if (do_send_ok) send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -3502,8 +3492,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, RETURN Like mysql_alter_table(). */ -int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, - bool do_send_ok) +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, + bool do_send_ok) { DBUG_ENTER("mysql_recreate_table"); LEX *lex= thd->lex; @@ -3525,7 +3515,7 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, } -int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) +bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { TABLE_LIST *table; List<Item> field_list; @@ -3539,7 +3529,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) item->maybe_null= 1; if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (table= tables; table; table= table->next_local) { @@ -3558,7 +3548,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { /* Table didn't exist */ protocol->store_null(); - thd->net.last_error[0]=0; + thd->clear_error(); } else { @@ -3620,11 +3610,11 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 5d175be74e1..7637679430f 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -38,12 +38,13 @@ static File_option triggers_file_parameters[]= methods. RETURN VALUE - 0 - Success, non-0 in case of error. + FALSE Success + TRUE error */ -int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) +bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { TABLE *table; - int result= 0; + bool result= 0; DBUG_ENTER("mysql_create_or_drop_trigger"); @@ -53,7 +54,7 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) */ if (open_and_lock_tables(thd, tables)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* TODO: We should check if user has TRIGGER privilege for table here. @@ -61,7 +62,7 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) we don't have proper privilege checking for triggers in place yet. */ if (check_global_access(thd, SUPER_ACL)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table= tables->table; @@ -74,19 +75,19 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (tables->view || table->tmp_table != NO_TMP_TABLE) { my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!table->triggers) { if (!create) { - my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); - DBUG_RETURN(-1); + my_message(ER_TRG_DOES_NOT_EXIST, ER(ER_TRG_DOES_NOT_EXIST), MYF(0)); + DBUG_RETURN(TRUE); } if (!(table->triggers= new (&table->mem_root) Table_triggers_list())) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -96,12 +97,12 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) global read lock is held without helding LOCK_open). */ if (wait_if_global_read_lock(thd, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); VOID(pthread_mutex_lock(&LOCK_open)); - if ((create ? table->triggers->create_trigger(thd, tables): - table->triggers->drop_trigger(thd, tables))) - result= -1; + result= (create ? + table->triggers->create_trigger(thd, tables): + table->triggers->drop_trigger(thd, tables)); /* It is sensible to invalidate table in any case */ close_cached_table(thd, table); @@ -140,7 +141,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) /* We don't allow creation of several triggers of the same type yet */ if (bodies[lex->trg_chistics.event][lex->trg_chistics.action_time]) { - my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); + my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0)); return 1; } @@ -150,7 +151,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) if (my_strcasecmp(system_charset_info, lex->name_and_length.str, name->str) == 0) { - my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); + my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0)); return 1; } } @@ -256,7 +257,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) } } - my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); + my_message(ER_TRG_DOES_NOT_EXIST, ER(ER_TRG_DOES_NOT_EXIST), MYF(0)); return 1; } @@ -416,8 +417,8 @@ err_with_lex_cleanup: We don't care about this error message much because .TRG files will be merged into .FRM anyway. */ - my_error(ER_WRONG_OBJECT, MYF(0), table_name, triggers_file_ext, - "TRIGGER"); + my_error(ER_WRONG_OBJECT, MYF(0), + table_name, triggers_file_ext, "TRIGGER"); DBUG_RETURN(1); } diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 8ab2ab003f8..d0376f056d9 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -58,5 +58,11 @@ public: static bool check_n_load(THD *thd, const char *db, const char *table_name, TABLE *table); + bool has_delete_triggers() + { + return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || + bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); + } + friend class Item_trigger_field; }; diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 0bb8ac8a28b..7fd81f22e66 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -368,7 +368,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!initialized) { - send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); DBUG_RETURN(1); } @@ -379,19 +379,19 @@ int mysql_create_function(THD *thd,udf_func *udf) */ if (strchr(udf->dl, '/')) { - send_error(thd, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS)); + my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0)); DBUG_RETURN(1); } if (udf->name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT,udf->name); + my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length))) { - net_printf(thd, ER_UDF_EXISTS, udf->name); + my_error(ER_UDF_EXISTS, MYF(0), udf->name); goto err; } if (!(dl = find_udf_dl(udf->dl))) @@ -400,7 +400,8 @@ int mysql_create_function(THD *thd,udf_func *udf) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); - net_printf(thd, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror()); + my_error(ER_CANT_OPEN_LIBRARY, MYF(0), + udf->dl, errno, dlerror()); goto err; } new_dl=1; @@ -410,16 +411,13 @@ int mysql_create_function(THD *thd,udf_func *udf) if (udf->func == NULL) { - net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name); + my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), udf->name); goto err; } udf->name.str=strdup_root(&mem,udf->name.str); udf->dl=strdup_root(&mem,udf->dl); if (!(u_d=add_udf(&udf->name,udf->returns,udf->dl,udf->type))) - { - send_error(thd,0); // End of memory goto err; - } u_d->dlhandle = dl; u_d->func=udf->func; u_d->func_init=udf->func_init; @@ -447,7 +445,7 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - net_printf(thd, ER_ERROR_ON_WRITE, "func@mysql",error); + my_error(ER_ERROR_ON_WRITE, MYF(0), "func@mysql", error); del_udf(u_d); goto err; } @@ -470,14 +468,14 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) DBUG_ENTER("mysql_drop_function"); if (!initialized) { - send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str, (uint) udf_name->length))) { - net_printf(thd, ER_FUNCTION_NOT_DEFINED, udf_name->str); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str); goto err; } del_udf(udf); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 792e2cdf775..815e04c0111 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -24,21 +24,20 @@ #include "mysql_priv.h" #include "sql_select.h" -int mysql_union(THD *thd, LEX *lex, select_result *result, - SELECT_LEX_UNIT *unit) +bool mysql_union(THD *thd, LEX *lex, select_result *result, + SELECT_LEX_UNIT *unit) { DBUG_ENTER("mysql_union"); - int res, res_cln; + bool res; if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK))) res= unit->exec(); - if (res == 0 && thd->cursor && thd->cursor->is_open()) + if (!res && thd->cursor && thd->cursor->is_open()) { thd->cursor->set_unit(unit); - res_cln= 0; } else - res_cln= unit->cleanup(); - DBUG_RETURN(res?res:res_cln); + res|= unit->cleanup(); + DBUG_RETURN(res); } @@ -76,7 +75,7 @@ bool select_union::send_data(List<Item> &values) unit->offset_limit_cnt--; return 0; } - fill_record(table->field, values, 1); + fill_record(thd, table->field, values, 1); if (thd->net.report_error || write_record(thd, table,&info)) { if (thd->net.last_errno == ER_RECORD_FILE_FULL) @@ -104,8 +103,7 @@ bool select_union::flush() int error; if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { - table->file->print_error(error,MYF(0)); - ::send_error(thd); + table->file->print_error(error, MYF(0)); return 1; } return 0; @@ -147,8 +145,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) } -int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, - ulong additional_options) +bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, + ulong additional_options) { SELECT_LEX *lex_select_save= thd_arg->lex->current_select; SELECT_LEX *sl, *first_select; @@ -177,16 +175,16 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (!sl->join->procedure && result->prepare(sl->join->fields_list, this)) { - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } sl->join->select_options|= SELECT_DESCRIBE; sl->join->reinit(); } } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } prepared= 1; - res= 0; + res= FALSE; thd_arg->lex->current_select= sl= first_select= first_select_in_union(); found_rows_for_union= first_select->options & OPTION_FOUND_ROWS; @@ -239,7 +237,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, sl->with_wild= 0; last_procedure= join->procedure; - if (res || thd_arg->is_fatal_error) + if ((res= (res || thd_arg->is_fatal_error))) goto err; if (sl == first_select) { @@ -269,7 +267,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, while ((type= tp++, item_tmp= it++)) { if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -325,7 +323,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (tmp_arena) thd->restore_backup_item_arena(tmp_arena, &backup); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } if (tmp_arena) @@ -343,7 +341,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, result))) { fake_select_lex->table_list.empty(); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } fake_select_lex->item_list= item_list; @@ -378,15 +376,15 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= lex_select_save; - DBUG_RETURN(res || thd_arg->is_fatal_error ? 1 : 0); + DBUG_RETURN(res || thd_arg->is_fatal_error); err: thd_arg->lex->current_select= lex_select_save; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } -int st_select_lex_unit::exec() +bool st_select_lex_unit::exec() { SELECT_LEX *lex_select_save= thd->lex->current_select; SELECT_LEX *select_cursor=first_select_in_union(); @@ -395,7 +393,7 @@ int st_select_lex_unit::exec() DBUG_ENTER("st_select_lex_unit::exec"); if (executed && !uncacheable && !describe) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); executed= 1; if (uncacheable || !item || !item->assigned() || describe) @@ -410,7 +408,7 @@ int st_select_lex_unit::exec() } /* re-enabling indexes for next subselect iteration */ if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL)) - DBUG_ASSERT(1); + DBUG_ASSERT(TRUE); } for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { @@ -465,7 +463,7 @@ int st_select_lex_unit::exec() if (sl == union_distinct) { if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table->no_keyread=1; } res= sl->join->error; @@ -474,7 +472,7 @@ int st_select_lex_unit::exec() { examined_rows+= thd->examined_row_count; thd->lex->current_select= lex_select_save; - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } if (res) @@ -500,7 +498,7 @@ int st_select_lex_unit::exec() optimized= 1; /* Send result to 'result' */ - res= -1; + res= TRUE; { List<Item_func_match> empty_list; empty_list.empty(); @@ -519,7 +517,7 @@ int st_select_lex_unit::exec() fake_select_lex->options, result))) { fake_select_lex->table_list.empty(); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -566,7 +564,7 @@ int st_select_lex_unit::exec() } -int st_select_lex_unit::cleanup() +bool st_select_lex_unit::cleanup() { int error= 0; JOIN *join; @@ -574,7 +572,7 @@ int st_select_lex_unit::cleanup() if (cleaned) { - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } cleaned= 1; @@ -648,19 +646,19 @@ void st_select_lex_unit::reinit_exec_mechanism() old_result old select_result object RETURN - 0 - OK - -1 - error + FALSE - OK + TRUE - error */ -int st_select_lex_unit::change_result(select_subselect *result, - select_subselect *old_result) +bool st_select_lex_unit::change_result(select_subselect *result, + select_subselect *old_result) { - int res= 0; + bool res= FALSE; for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) { if (sl->join && sl->join->result == old_result) - if ((res= sl->join->change_result(result))) - return (res); + if (sl->join->change_result(result)) + return TRUE; } if (fake_select_lex && fake_select_lex->join) res= fake_select_lex->join->change_result(result); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 561480bd289..c5167018701 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -38,15 +38,15 @@ static bool compare_record(TABLE *table, ulong query_id) if (memcmp(table->null_flags, table->null_flags+table->rec_buff_length, table->null_bytes)) - return 1; // Diff in NULL value + return TRUE; // Diff in NULL value /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { if ((*ptr)->query_id == query_id && (*ptr)->cmp_binary_offset(table->rec_buff_length)) - return 1; + return TRUE; } - return 0; + return FALSE; } @@ -86,21 +86,21 @@ static bool check_fields(THD *thd, List<Item> &items) } -int mysql_update(THD *thd, - TABLE_LIST *table_list, - List<Item> &fields, - List<Item> &values, - COND *conds, - uint order_num, ORDER *order, - ha_rows limit, - enum enum_duplicates handle_duplicates) +bool mysql_update(THD *thd, + TABLE_LIST *table_list, + List<Item> &fields, + List<Item> &values, + COND *conds, + uint order_num, ORDER *order, + ha_rows limit, + enum enum_duplicates handle_duplicates) { bool using_limit= limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table, log_delayed; bool ignore_err= (thd->lex->duplicates == DUP_IGNORE); + bool res; int error=0; - int res; uint used_index; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint want_privilege; @@ -111,13 +111,14 @@ int mysql_update(THD *thd, TABLE *table; SQL_SELECT *select; READ_RECORD info; + SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_update"); LINT_INIT(used_index); LINT_INIT(timestamp_query_id); - if ((error= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(error); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); thd->proc_info="init"; table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -132,8 +133,8 @@ int mysql_update(THD *thd, table_list->grant.want_privilege : table->grant.want_privilege); #endif - if ((error= mysql_prepare_update(thd, table_list, &conds, order_num, order))) - DBUG_RETURN(error); + if (mysql_prepare_update(thd, table_list, &conds, order_num, order)) + DBUG_RETURN(TRUE); old_used_keys= table->used_keys; // Keys used in WHERE /* @@ -151,20 +152,20 @@ int mysql_update(THD *thd, table_list->grant.want_privilege= table->grant.want_privilege= want_privilege; #endif { - thd->lex->select_lex.no_wrap_view_item= 1; + select_lex->no_wrap_view_item= 1; res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); - thd->lex->select_lex.no_wrap_view_item= 0; + select_lex->no_wrap_view_item= 0; if (res) - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (table_list->view && check_fields(thd, fields)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (table->timestamp_field) { @@ -182,8 +183,8 @@ int mysql_update(THD *thd, #endif if (setup_fields(thd, 0, table_list, values, 0, 0, 0)) { - free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); /* purecov: inspected */ + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); /* purecov: inspected */ } // Don't count on usage of 'only index' when calculating which key to use @@ -193,13 +194,13 @@ int mysql_update(THD *thd, (select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (error) { - DBUG_RETURN(-1); // Error in where + DBUG_RETURN(TRUE); // Error in where } send_ok(thd); // No matching records - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /* If running in safe sql mode, don't allow updates without keys */ if (table->quick_keys.is_clear_all()) @@ -212,7 +213,7 @@ int mysql_update(THD *thd, goto err; } } - init_ftfuncs(thd, &thd->lex->select_lex, 1); + init_ftfuncs(thd, select_lex, 1); /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) @@ -361,8 +362,9 @@ int mysql_update(THD *thd, if (!(select && select->skip_record())) { store_record(table,record[1]); - if (fill_record(fields,values, 0) || thd->net.report_error) + if (fill_record(thd, fields, values, 0)) break; /* purecov: inspected */ + found++; if (table->triggers) @@ -455,10 +457,8 @@ int mysql_update(THD *thd, thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); - if (error >= 0) - send_error(thd,thd->killed_errno()); /* purecov: inspected */ - else + free_underlaid_joins(thd, select_lex); + if (error < 0) { char buff[80]; sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, @@ -472,18 +472,18 @@ int mysql_update(THD *thd, thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->abort_on_warning= 0; free_io_cache(table); - DBUG_RETURN(0); + DBUG_RETURN(error >= 0 || thd->net.report_error); err: delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (table->key_read) { table->key_read=0; table->file->extra(HA_EXTRA_NO_KEYREAD); } thd->abort_on_warning= 0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -498,11 +498,10 @@ err: order - ORDER BY clause list RETURN VALUE - 0 - OK - 1 - error (message is sent to user) - -1 - error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, +bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order) { TABLE *table= table_list->table; @@ -526,16 +525,16 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, setup_order(thd, select_lex->ref_pointer_array, table_list, all_fields, all_fields, order) || setup_ftfuncs(select_lex)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check that we are not using table that we are updating in a sub select */ if (unique_table(table_list, table_list->next_global)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -568,11 +567,11 @@ static table_map get_table_map(List<Item> *items) thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_multi_update_prepare(THD *thd) +bool mysql_multi_update_prepare(THD *thd) { LEX *lex= thd->lex; ulong opened_tables; @@ -589,7 +588,7 @@ int mysql_multi_update_prepare(THD *thd) /* open tables and create derived ones, but do not lock and fill them */ if (open_tables(thd, table_list, & table_count) || mysql_handle_derived(lex, &mysql_derived_prepare)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); + DBUG_RETURN(TRUE); /* Ensure that we have update privilege for all tables and columns in the SET part @@ -618,7 +617,7 @@ int mysql_multi_update_prepare(THD *thd) res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0), lex->select_lex.no_wrap_view_item= 0, res)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (tl= table_list; tl ; tl= tl->next_local) { @@ -631,7 +630,7 @@ int mysql_multi_update_prepare(THD *thd) if (update_view && check_fields(thd, *fields)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } tables_for_update= get_table_map(fields); @@ -657,7 +656,7 @@ int mysql_multi_update_prepare(THD *thd) if (!tl->updatable || check_key_in_view(thd, tl)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -668,7 +667,7 @@ int mysql_multi_update_prepare(THD *thd) tl->real_name)) { my_error(ER_UPDATE_TABLE_USED, MYF(0), tl->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } DBUG_PRINT("info",("setting table `%s` for update", tl->alias)); tl->lock_type= lex->multi_lock_option; @@ -687,7 +686,7 @@ int mysql_multi_update_prepare(THD *thd) opened_tables= thd->status_var.opened_tables; /* now lock and fill tables */ if (lock_tables(thd, table_list, table_count)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); + DBUG_RETURN(TRUE); /* we have to re-call fixfields for fixed items, because lock maybe @@ -718,12 +717,12 @@ int mysql_multi_update_prepare(THD *thd) res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0), lex->select_lex.no_wrap_view_item= 0, res)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (thd->fill_derived_tables() && mysql_handle_derived(lex, &mysql_derived_filling)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); - DBUG_RETURN (0); + DBUG_RETURN(TRUE); + DBUG_RETURN (FALSE); } @@ -731,25 +730,25 @@ int mysql_multi_update_prepare(THD *thd) Setup multi-update handling and call SELECT to do the join */ -int mysql_multi_update(THD *thd, - TABLE_LIST *table_list, - List<Item> *fields, - List<Item> *values, - COND *conds, - ulong options, - enum enum_duplicates handle_duplicates, - SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) +bool mysql_multi_update(THD *thd, + TABLE_LIST *table_list, + List<Item> *fields, + List<Item> *values, + COND *conds, + ulong options, + enum enum_duplicates handle_duplicates, + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) { - int res; + bool res; multi_update *result; DBUG_ENTER("mysql_multi_update"); - if ((res= mysql_multi_update_prepare(thd))) - DBUG_RETURN(res); + if (mysql_multi_update_prepare(thd)) + DBUG_RETURN(TRUE); if (!(result= new multi_update(thd, table_list, fields, values, handle_duplicates))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); thd->no_trans_update= 0; thd->abort_on_warning= test(thd->variables.sql_mode & @@ -766,7 +765,7 @@ int mysql_multi_update(THD *thd, result, unit, select_lex); delete result; thd->abort_on_warning= 0; - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -804,7 +803,7 @@ int multi_update::prepare(List<Item> ¬_used_values, if (!tables_to_update) { - my_error(ER_NO_TABLES_USED, MYF(0)); + my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); DBUG_RETURN(1); } @@ -1016,7 +1015,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields) case JT_SYSTEM: case JT_CONST: case JT_EQ_REF: - return 1; // At most one matching row + return TRUE; // At most one matching row case JT_REF: return !check_if_key_used(table, join_tab->ref.key, *fields); case JT_ALL: @@ -1027,11 +1026,11 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields) if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && table->primary_key < MAX_KEY) return !check_if_key_used(table, table->primary_key, *fields); - return 1; + return TRUE; default: break; // Avoid compler warning } - return 0; + return FALSE; } @@ -1090,8 +1089,10 @@ bool multi_update::send_data(List<Item> ¬_used_values) { table->status|= STATUS_UPDATED; store_record(table,record[1]); - if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) + if (fill_record(thd, *fields_for_table[offset], + *values_for_table[offset], 0)) DBUG_RETURN(1); + found++; if (compare_record(table, thd->query_id)) { @@ -1134,7 +1135,7 @@ bool multi_update::send_data(List<Item> ¬_used_values) { int error; TABLE *tmp_table= tmp_tables[offset]; - fill_record(tmp_table->field+1, *values_for_table[offset], 1); + fill_record(thd, tmp_table->field+1, *values_for_table[offset], 1); found++; /* Store pointer to row */ memcpy((char*) tmp_table->field[0]->ptr, @@ -1160,7 +1161,7 @@ bool multi_update::send_data(List<Item> ¬_used_values) void multi_update::send_error(uint errcode,const char *err) { /* First send error what ever it is ... */ - ::send_error(thd,errcode,err); + my_error(errcode, MYF(0), err); /* If nothing updated return */ if (!updated) @@ -1353,8 +1354,7 @@ bool multi_update::send_eof() /* Safety: If we haven't got an error before (should not happen) */ my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update", MYF(0)); - ::send_error(thd); - return 1; + return TRUE; } @@ -1364,5 +1364,5 @@ bool multi_update::send_eof() (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; ::send_ok(thd, (ulong) thd->row_count_func, thd->insert_id_used ? thd->insert_id() : 0L,buff); - return 0; + return FALSE; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 760ada9cdbd..68024876b32 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -42,13 +42,12 @@ TYPELIB updatable_views_with_limit_typelib= mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE RETURN VALUE - 0 OK - -1 Error - 1 Error and error message given + FALSE OK + TRUE Error */ -int mysql_create_view(THD *thd, - enum_view_create_mode mode) +bool mysql_create_view(THD *thd, + enum_view_create_mode mode) { LEX *lex= thd->lex; bool link_to_local; @@ -58,7 +57,7 @@ int mysql_create_view(THD *thd, TABLE_LIST *tbl; SELECT_LEX *select_lex= &lex->select_lex, *sl; SELECT_LEX_UNIT *unit= &lex->unit; - int res= 0; + bool res= FALSE; DBUG_ENTER("mysql_create_view"); if (lex->proc_list.first || @@ -67,16 +66,17 @@ int mysql_create_view(THD *thd, my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ? "INTO" : "PROCEDURE")); - res= -1; + res= TRUE; goto err; } if (lex->derived_tables || lex->variables_used || lex->param_list.elements) { - my_error((lex->derived_tables ? + int err= (lex->derived_tables ? ER_VIEW_SELECT_DERIVED : - ER_VIEW_SELECT_VARIABLE), MYF(0)); - res= -1; + ER_VIEW_SELECT_VARIABLE); + my_message(err, ER(err), MYF(0)); + res= TRUE; goto err; } @@ -102,7 +102,7 @@ int mysql_create_view(THD *thd, (check_access(thd, DELETE_ACL, view->db, &view->grant.privilege, 0, 0) || grant_option && check_grant(thd, DELETE_ACL, view, 0, 1, 0)))) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); for (sl= select_lex; sl; sl= sl->next_select()) { for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) @@ -113,14 +113,9 @@ int mysql_create_view(THD *thd, */ if (check_some_access(thd, VIEW_ANY_ACL, tbl)) { - my_printf_error(ER_TABLEACCESS_DENIED_ERROR, - ER(ER_TABLEACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - tbl->real_name); - DBUG_RETURN(-1); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + "ANY", thd->priv_user, thd->host_or_ip, tbl->real_name); + DBUG_RETURN(TRUE); } /* Mark this table as a table which will be checked after the prepare @@ -156,7 +151,7 @@ int mysql_create_view(THD *thd, &tbl->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) { - res= 1; + res= TRUE; goto err; } } @@ -178,8 +173,8 @@ int mysql_create_view(THD *thd, } #endif - if ((res= open_and_lock_tables(thd, tables))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, tables)) + DBUG_RETURN(TRUE); /* check that tables are not temporary and this VIEW do not used in query @@ -188,10 +183,11 @@ int mysql_create_view(THD *thd, for (tbl= tables; tbl; tbl= tbl->next_global) { /* is this table temporary and is not view? */ - if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view) + if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view && + !tbl->schema_table) { my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); - res= -1; + res= TRUE; goto err; } @@ -201,7 +197,7 @@ int mysql_create_view(THD *thd, strcmp(tbl->view_name.str, view->real_name) == 0) { my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str); - res= -1; + res= TRUE; goto err; } @@ -221,7 +217,7 @@ int mysql_create_view(THD *thd, some errors from prepare are reported to user, if is not then it will be checked after err: label */ - res= 1; + res= TRUE; goto err; } @@ -256,7 +252,7 @@ int mysql_create_view(THD *thd, if (strcmp(item->name, check->name) == 0) { my_error(ER_DUP_FIELDNAME, MYF(0), item->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -287,15 +283,10 @@ int mysql_create_view(THD *thd, if ((~fld->have_privileges & priv)) { /* VIEW column has more privileges */ - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "create view", - thd->priv_user, - thd->host_or_ip, - item->name, - view->real_name); - DBUG_RETURN(-1); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "create view", thd->priv_user, thd->host_or_ip, item->name, + view->real_name); + DBUG_RETURN(TRUE); } } } @@ -304,7 +295,7 @@ int mysql_create_view(THD *thd, if (wait_if_global_read_lock(thd, 0, 0)) { - res= -1; + res= TRUE; goto err; } VOID(pthread_mutex_lock(&LOCK_open)); @@ -322,9 +313,7 @@ err: thd->proc_info= "end"; lex->link_first_table_back(view, link_to_local); unit->cleanup(); - if (thd->net.report_error) - res= -1; - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); } @@ -441,8 +430,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (!parser->ok() || strncmp("VIEW", parser->type()->str, parser->type()->length)) { - my_error(ER_WRONG_OBJECT, MYF(0), (view->db ? view->db : thd->db), - view->real_name, "VIEW"); + my_error(ER_WRONG_OBJECT, MYF(0), + (view->db ? view->db : thd->db), view->real_name, "VIEW"); DBUG_RETURN(-1); } @@ -494,7 +483,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, tbl; tbl= tbl->next_local) { - if (tbl->view && !tbl->updatable_view) + if ((tbl->view && !tbl->updatable_view) || tbl->schema_table) { view->updatable_view= 0; break; @@ -696,7 +685,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) if (check_table_access(thd, SELECT_ACL, view_tables, 1) && check_table_access(thd, SHOW_VIEW_ACL, table, 1)) { - my_error(ER_VIEW_NO_EXPLAIN, MYF(0)); + my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); goto err; } } @@ -845,12 +834,11 @@ err: drop_mode - cascade/check RETURN VALUE - 0 OK - -1 Error - 1 Error and error message given + FALSE OK + TRUE Error */ -int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) +bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { DBUG_ENTER("mysql_drop_view"); char path[FN_REFLEN]; @@ -886,11 +874,11 @@ int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) VOID(pthread_mutex_unlock(&LOCK_open)); } send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: VOID(pthread_mutex_unlock(&LOCK_open)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_view.h b/sql/sql_view.h index 538f548d97b..4cb2514f5b9 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -16,12 +16,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -int mysql_create_view(THD *thd, - enum_view_create_mode mode); +bool mysql_create_view(THD *thd, + enum_view_create_mode mode); my_bool mysql_make_view(File_parser *parser, TABLE_LIST *table); -int mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); +bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); bool check_key_in_view(THD *thd, TABLE_LIST * view); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 309a9249d0e..e6e7c9b59ae 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -140,6 +140,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CLIENT_SYM %token COMMENT_SYM %token COMMIT_SYM +%token CONSISTENT_SYM %token COUNT_SYM %token CREATE %token CROSS @@ -176,6 +177,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SELECT_SYM %token SHOW %token SLAVE +%token SNAPSHOT_SYM %token SQL_SYM %token SQL_THREAD %token START_SYM @@ -661,7 +663,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_table_alias %type <table> - table_ident table_ident_nodb references + table_ident table_ident_nodb references from_table_ident %type <simple_string> remember_name remember_end opt_ident opt_db text_or_password @@ -676,6 +678,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option + start_transaction_opts %type <ulong_num> ULONG_NUM raid_types merge_insert_types @@ -814,7 +817,7 @@ query: if (!thd->bootstrap && (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) { - send_error(thd,ER_EMPTY_QUERY); + my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); YYABORT; } else @@ -1150,7 +1153,7 @@ create: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "PROCEDURE"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE"); YYABORT; } /* Order is important here: new - reset - init */ @@ -1223,7 +1226,7 @@ create: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "TRIGGER"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER"); YYABORT; } @@ -1304,7 +1307,7 @@ create_function_tail: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "FUNCTION"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); YYABORT; } /* Order is important here: new - reset - init */ @@ -1464,7 +1467,7 @@ sp_fdparam: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_PARAM, $1.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); @@ -1490,7 +1493,7 @@ sp_pdparam: if (spc->find_pvar(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_PARAM, $2.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $2.str); YYABORT; } spc->push_pvar(&$2, (enum enum_field_types)$3, @@ -1528,12 +1531,14 @@ sp_decls: better error handling this way.) */ if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) { /* Variable or condition following cursor or handler */ - send_error(YYTHD, ER_SP_VARCOND_AFTER_CURSHNDLR); + my_message(ER_SP_VARCOND_AFTER_CURSHNDLR, + ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0)); YYABORT; } if ($2.curs && $1.hndlrs) { /* Cursor following handler */ - send_error(YYTHD, ER_SP_CURSOR_AFTER_HANDLER); + my_message(ER_SP_CURSOR_AFTER_HANDLER, + ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0)); YYABORT; } $$.vars= $1.vars + $2.vars; @@ -1581,7 +1586,7 @@ sp_decl: if (spc->find_cond(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_COND, $2.str); + my_error(ER_SP_DUP_COND, MYF(0), $2.str); YYABORT; } YYTHD->lex->spcont->push_cond(&$2, $5); @@ -1638,7 +1643,7 @@ sp_decl: if (ctx->find_cursor(&$2, &offp, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_CURS, $2.str); + my_error(ER_SP_DUP_CURS, MYF(0), $2.str); delete $5; YYABORT; } @@ -1665,12 +1670,14 @@ sp_cursor_stmt: if (lex->sql_command != SQLCOM_SELECT) { - send_error(YYTHD, ER_SP_BAD_CURSOR_QUERY); + my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY), + MYF(0)); YYABORT; } if (lex->result) { - send_error(YYTHD, ER_SP_BAD_CURSOR_SELECT); + my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT), + MYF(0)); YYABORT; } lex->sp_lex_in_use= TRUE; @@ -1740,7 +1747,7 @@ sp_hcond: $$= Lex->spcont->find_cond(&$1); if ($$ == NULL) { - net_printf(YYTHD, ER_SP_COND_MISMATCH, $1.str); + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); YYABORT; } } @@ -1769,7 +1776,7 @@ sp_decl_idents: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_VAR, $1.str); + my_error(ER_SP_DUP_VAR, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); @@ -1782,7 +1789,7 @@ sp_decl_idents: if (spc->find_pvar(&$3, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_VAR, $3.str); + my_error(ER_SP_DUP_VAR, MYF(0), $3.str); YYABORT; } spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); @@ -1815,7 +1822,7 @@ sp_proc_stmt: } if (lex->sql_command == SQLCOM_CHANGE_DB) { /* "USE db" doesn't work in a procedure */ - send_error(YYTHD, ER_SP_NO_USE); + my_message(ER_SP_NO_USE, ER(ER_SP_NO_USE), MYF(0)); YYABORT; } /* Don't add an instruction for empty SET statements. @@ -1834,7 +1841,7 @@ sp_proc_stmt: */ if (sp->m_type != TYPE_ENUM_PROCEDURE) { - send_error(YYTHD, ER_SP_BADSTATEMENT); + my_message(ER_SP_BADSTATEMENT, ER(ER_SP_BADSTATEMENT), MYF(0)); YYABORT; } else @@ -1864,7 +1871,7 @@ sp_proc_stmt: if (lex->sphead->m_type == TYPE_ENUM_PROCEDURE) { - send_error(YYTHD, ER_SP_BADRETURN); + my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0)); YYABORT; } else @@ -1873,7 +1880,7 @@ sp_proc_stmt: if ($2->type() == Item::SUBSELECT_ITEM) { /* QQ For now, just disallow subselects as values */ - send_error(lex->thd, ER_SP_BADSTATEMENT); + my_message(ER_SP_BADSTATEMENT, ER(ER_SP_BADSTATEMENT), MYF(0)); YYABORT; } i= new sp_instr_freturn(lex->sphead->instructions(), @@ -1936,7 +1943,7 @@ sp_proc_stmt: if (! lab) { - net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str); YYABORT; } else @@ -1966,7 +1973,7 @@ sp_proc_stmt: if (! lab || lab->type != SP_LAB_ITER) { - net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str); YYABORT; } else @@ -1994,7 +2001,7 @@ sp_proc_stmt: if (lab) { - net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str); YYABORT; } else @@ -2018,7 +2025,7 @@ sp_proc_stmt: if (sp->m_in_handler) { - send_error(lex->thd, ER_SP_GOTO_IN_HNDLR); + my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0)); YYABORT; } lab= ctx->find_label($2.str); @@ -2069,7 +2076,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); @@ -2084,7 +2091,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$3, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $3.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str); YYABORT; } i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); @@ -2101,7 +2108,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); @@ -2125,7 +2132,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$1))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } else @@ -2147,7 +2154,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$3))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $3.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str); YYABORT; } else @@ -2271,7 +2278,7 @@ sp_labeled_control: if (lab) { - net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $1.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); YYABORT; } else @@ -2292,7 +2299,7 @@ sp_labeled_control: if (!lab || my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { - net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); YYABORT; } } @@ -2550,9 +2557,9 @@ default_charset: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, - "CHARACTER SET ", cinfo->default_table_charset->csname, - "CHARACTER SET ", $4->csname); + my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2567,8 +2574,8 @@ default_collation: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $4->name, cinfo->default_table_charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $4->name, cinfo->default_table_charset->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2580,7 +2587,7 @@ storage_engines: { $$ = ha_resolve_by_name($1.str,$1.length); if ($$ == DB_TYPE_UNKNOWN) { - net_printf(YYTHD, ER_UNKNOWN_STORAGE_ENGINE, $1.str); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); YYABORT; } }; @@ -2770,18 +2777,18 @@ type: $$=FIELD_TYPE_TINY_BLOB; } | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_BLOB; } - | spatial_type { + | spatial_type + { #ifdef HAVE_SPATIAL - Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint)$1; - $$=FIELD_TYPE_GEOMETRY; + Lex->charset=&my_charset_bin; + Lex->uint_geom_type= (uint)$1; + $$=FIELD_TYPE_GEOMETRY; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, - sym_group_geom.needed_define); - YYABORT; + my_error(ER_FEATURE_DISABLED, MYF(0) + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; #endif - } + } | MEDIUMBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGBLOB { Lex->charset=&my_charset_bin; @@ -2945,8 +2952,8 @@ attribute: { if (Lex->charset && !my_charset_same(Lex->charset,$2)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $2->name,Lex->charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $2->name,Lex->charset->csname); YYABORT; } else @@ -2971,7 +2978,7 @@ charset_name: { if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -2989,7 +2996,7 @@ old_or_new_charset_name: if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && !($$=get_old_charset_by_name($1.str))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -3005,7 +3012,7 @@ collation_name: { if (!($$=get_charset_by_name($1.str,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_COLLATION,$1.str); + my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str); YYABORT; } }; @@ -3029,9 +3036,10 @@ opt_binary: | BYTE_SYM { Lex->charset=&my_charset_bin; } | UNICODE_SYM { - if (!(Lex->charset=get_charset_by_csname("ucs2",MY_CS_PRIMARY,MYF(0)))) + if (!(Lex->charset=get_charset_by_csname("ucs2", + MY_CS_PRIMARY,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,"ucs2"); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2"); YYABORT; } } @@ -3093,8 +3101,8 @@ key_type: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif }; @@ -3126,8 +3134,8 @@ opt_unique_or_fulltext: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_message(ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -3157,9 +3165,7 @@ key_part: int key_part_len= atoi($3.str); if (!key_part_len) { - my_printf_error(ER_UNKNOWN_ERROR, - "Key part '%s' length cannot be 0", - MYF(0), $1.str); + my_error(ER_KEY_PART_0, MYF(0), $1.str); } $$=new key_part_spec($1.str,(uint) key_part_len); }; @@ -3368,7 +3374,7 @@ alter_list_item: if (check_table_name($3->table.str,$3->table.length) || $3->db.str && check_db_name($3->db.str)) { - net_printf(lex->thd,ER_WRONG_TABLE_NAME,$3->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); YYABORT; } lex->alter_info.flags|= ALTER_RENAME; @@ -3383,8 +3389,8 @@ alter_list_item: $5= $5 ? $5 : $4; if (!my_charset_same($4,$5)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $5->name,$4->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $5->name, $4->csname); YYABORT; } LEX *lex= Lex; @@ -3473,10 +3479,21 @@ slave: start: - START_SYM TRANSACTION_SYM { Lex->sql_command = SQLCOM_BEGIN;} - {} + START_SYM TRANSACTION_SYM start_transaction_opts + { + Lex->sql_command = SQLCOM_BEGIN; + Lex->start_transaction_opt= $3; + } ; +start_transaction_opts: + /*empty*/ { $$ = 0; } + | WITH CONSISTENT_SYM SNAPSHOT_SYM + { + $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT; + } + ; + slave_thread_opts: { Lex->slave_thd_opt= 0; } slave_thread_opt_list @@ -3504,7 +3521,8 @@ slave_until: !((lex->mi.log_file_name && lex->mi.pos) || (lex->mi.relay_log_name && lex->mi.relay_log_pos))) { - send_error(lex->thd, ER_BAD_SLAVE_UNTIL_COND); + my_message(ER_BAD_SLAVE_UNTIL_COND, + ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0)); YYABORT; } @@ -4217,9 +4235,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(void))($1.symbol->create_func))(); @@ -4228,9 +4246,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); @@ -4239,9 +4257,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); @@ -4250,9 +4268,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); @@ -4355,8 +4373,8 @@ simple_expr: #ifdef HAVE_SPATIAL $$= $1; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -5212,12 +5230,12 @@ olap_opt: LEX *lex=Lex; if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, "WITH CUBE", + my_error(ER_WRONG_USAGE, MYF(0), "WITH CUBE", "global union parameters"); YYABORT; } lex->current_select->olap= CUBE_TYPE; - net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "CUBE"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "CUBE"); YYABORT; /* To be deleted in 5.1 */ } | WITH ROLLUP_SYM @@ -5225,7 +5243,7 @@ olap_opt: LEX *lex= Lex; if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, "WITH ROLLUP", + my_error(ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", "global union parameters"); YYABORT; } @@ -5249,9 +5267,8 @@ order_clause: lex->current_select->olap != UNSPECIFIED_OLAP_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, - "CUBE/ROLLUP", - "ORDER BY"); + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); YYABORT; } } order_list; @@ -5349,9 +5366,7 @@ procedure_clause: LEX *lex=Lex; if (&lex->select_lex != lex->current_select) { - net_printf(lex->thd, ER_WRONG_USAGE, - "PROCEDURE", - "subquery"); + my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); YYABORT; } lex->proc_list.elements=0; @@ -5415,7 +5430,7 @@ select_var_ident: if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } if (! lex->result) @@ -5506,7 +5521,7 @@ drop: LEX *lex=Lex; if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_DROP_SP, "FUNCTION"); + my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); YYABORT; } lex->sql_command = SQLCOM_DROP_FUNCTION; @@ -5518,7 +5533,7 @@ drop: LEX *lex=Lex; if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_DROP_SP, "PROCEDURE"); + my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"); YYABORT; } lex->sql_command = SQLCOM_DROP_PROCEDURE; @@ -5771,8 +5786,8 @@ update: else if (lex->select_lex.get_table_list()->derived) { /* it is single table update and it is update of derived table */ - net_printf(lex->thd, ER_NON_UPDATABLE_TABLE, - lex->select_lex.get_table_list()->alias, "UPDATE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + lex->select_lex.get_table_list()->alias, "UPDATE"); YYABORT; } else @@ -5890,21 +5905,32 @@ show: SHOW ; show_param: - DATABASES wild - { Lex->sql_command= SQLCOM_SHOW_DATABASES; } - | opt_full TABLES opt_db wild - { - LEX *lex= Lex; - lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $3; - } - | TABLE_SYM STATUS_SYM opt_db wild - { - LEX *lex= Lex; - lex->sql_command= SQLCOM_SHOW_TABLES; - lex->describe= DESCRIBE_EXTENDED; - lex->select_lex.db= $3; - } + DATABASES ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_DATABASES; + if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA)) + YYABORT; + } + | opt_full TABLES ext_select_item_list opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_TABLES; + lex->select_lex.db= $4; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES)) + YYABORT; + } + | TABLE_SYM STATUS_SYM ext_select_item_list opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATUS; + lex->select_lex.db= $4; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES)) + YYABORT; + } | OPEN_SYM TABLES opt_db wild { LEX *lex= Lex; @@ -5914,12 +5940,14 @@ show_param: | ENGINE_SYM storage_engines { Lex->create_info.db_type= $2; } show_engine_param - | opt_full COLUMNS from_or_in table_ident opt_db wild + | opt_full COLUMNS ext_select_item_list from_table_ident opt_db wild_and_where { - Lex->sql_command= SQLCOM_SHOW_FIELDS; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_FIELDS; if ($5) $4->change_db($5); - if (!Select->add_table_to_list(YYTHD, $4, NULL, 0)) + if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS)) YYABORT; } | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ @@ -5945,13 +5973,15 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; } opt_limit_clause_init - | keys_or_index from_or_in table_ident opt_db - { - Lex->sql_command= SQLCOM_SHOW_KEYS; + | keys_or_index ext_select_item_list from_table_ident opt_db where_clause + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_KEYS; if ($4) $3->change_db($4); - if (!Select->add_table_to_list(YYTHD, $3, NULL, 0)) - YYABORT; + if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS)) + YYABORT; } | COLUMN_SYM TYPES_SYM { @@ -5998,10 +6028,22 @@ show_param: thd->lex->sql_command= SQLCOM_SHOW_VARIABLES; thd->lex->option_type= (enum_var_type) $1; } - | charset wild - { Lex->sql_command= SQLCOM_SHOW_CHARSETS; } - | COLLATION_SYM wild - { Lex->sql_command= SQLCOM_SHOW_COLLATIONS; } + | charset ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_CHARSETS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS)) + YYABORT; + } + | COLLATION_SYM ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_COLLATIONS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS)) + YYABORT; + } | BERKELEY_DB_SYM LOGS_SYM { Lex->sql_command= SQLCOM_SHOW_LOGS; WARN_DEPRECATED("SHOW BDB LOGS", "SHOW ENGINE BDB LOGS"); } | LOGS_SYM @@ -6080,13 +6122,21 @@ show_param: lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; lex->spname= $3; } - | PROCEDURE STATUS_SYM wild + | PROCEDURE STATUS_SYM ext_select_item_list wild_and_where { - Lex->sql_command = SQLCOM_SHOW_STATUS_PROC; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_STATUS_PROC; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; } - | FUNCTION_SYM STATUS_SYM wild + | FUNCTION_SYM STATUS_SYM ext_select_item_list wild_and_where { - Lex->sql_command = SQLCOM_SHOW_STATUS_FUNC; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_STATUS_FUNC; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; }; show_engine_param: @@ -6097,7 +6147,7 @@ show_engine_param: Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; break; default: - net_printf(YYTHD, ER_NOT_SUPPORTED_YET, "STATUS"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "STATUS"); YYABORT; } } @@ -6108,7 +6158,7 @@ show_engine_param: Lex->sql_command = SQLCOM_SHOW_LOGS; break; default: - net_printf(YYTHD, ER_NOT_SUPPORTED_YET, "LOGS"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "LOGS"); YYABORT; } }; @@ -6147,16 +6197,49 @@ binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } | FROM ulonglong_num { Lex->mi.pos = $2; }; +from_table_ident: + /* empty */ { $$= 0; } + | from_or_in table_ident { $$= $2; } + ; + +wild_and_where: + /* empty */ + | LIKE TEXT_STRING_sys + { Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length, + system_charset_info); } + | WHERE expr + { + Select->where= $2; + if ($2) + $2->top_level_item(); + } + ; + +ext_select_item_list: + { + LEX *lex=Lex; + SELECT_LEX *sel= lex->current_select; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + } + /* empty */ + | select_item_list {}; + /* A Oracle compatible synonym for show */ describe: describe_command table_ident { - LEX *lex=Lex; - lex->wild=0; - lex->verbose=0; - lex->sql_command=SQLCOM_SHOW_FIELDS; - if (!Select->add_table_to_list(lex->thd, $2, NULL,0)) + LEX *lex= Lex; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_FIELDS; + lex->select_lex.db= 0; + lex->verbose= 0; + if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS)) YYABORT; } opt_describe_column {} @@ -6260,7 +6343,7 @@ purge_option: { if ($2->check_cols(1) || $2->fix_fields(Lex->thd, 0, &$2)) { - net_printf(Lex->thd, ER_WRONG_ARGUMENTS, "PURGE LOGS BEFORE"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); YYABORT; } Item *tmp= new Item_func_unix_timestamp($2); @@ -6282,7 +6365,8 @@ kill: LEX *lex=Lex; if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) { - send_error(lex->thd, ER_SET_CONSTANTS_ONLY); + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), + MYF(0)); YYABORT; } lex->sql_command=SQLCOM_KILL; @@ -6453,7 +6537,7 @@ param_marker: (uchar *) thd->query)); if (!($$= item) || lex->param_list.push_back(item)) { - send_error(thd, ER_OUT_OF_RESOURCES); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); YYABORT; } } @@ -6509,7 +6593,6 @@ NUM_literal: $$= new Item_real($1.str, $1.length); if (YYTHD->net.report_error) { - send_error(YYTHD, 0, NullS); YYABORT; } } @@ -6518,7 +6601,6 @@ NUM_literal: $$ = new Item_float($1.str, $1.length); if (YYTHD->net.report_error) { - send_error(YYTHD, 0, NullS); YYABORT; } } @@ -6607,16 +6689,14 @@ simple_ident_q: if (lex->trg_chistics.event == TRG_EVENT_INSERT && !new_row) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "OLD", - "on INSERT"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); YYABORT; } if (lex->trg_chistics.event == TRG_EVENT_DELETE && new_row) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", - "on DELETE"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); YYABORT; } @@ -6633,8 +6713,8 @@ simple_ident_q: FIXME. Far from perfect solution. See comment for "SET NEW.field_name:=..." for more info. */ - net_printf(YYTHD, ER_BAD_FIELD_ERROR, $3.str, - new_row ? "NEW": "OLD"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + $3.str, new_row ? "NEW": "OLD"); YYABORT; } @@ -6645,9 +6725,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $1.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $1.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6662,9 +6741,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $2.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $2.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6678,9 +6756,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $3.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $3.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6721,8 +6798,8 @@ IDENT_sys: $1.length); if (wlen < $1.length) { - net_printf(YYTHD, ER_INVALID_CHARACTER_STRING, cs->csname, - $1.str + wlen); + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), + cs->csname, $1.str + wlen); YYABORT; } $$= $1; @@ -6846,6 +6923,7 @@ keyword: | COMMIT_SYM {} | COMPRESSED_SYM {} | CONCURRENT {} + | CONSISTENT_SYM {} | CONTAINS_SYM {} | CUBE_SYM {} | DATA_SYM {} @@ -6998,6 +7076,7 @@ keyword: | SHARE_SYM {} | SHUTDOWN {} | SLAVE {} + | SNAPSHOT_SYM {} | SOUNDS_SYM {} | SQL_CACHE_SYM {} | SQL_BUFFER_RESULT {} @@ -7103,7 +7182,8 @@ option_value: */ if (lex->query_tables) { - send_error(YYTHD, ER_SP_SUBSELECT_NYI); + my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), + MYF(0)); YYABORT; } sp_instr_set_user_var *i= @@ -7126,7 +7206,8 @@ option_value: sp_instr_set_trigger_field *i; if (lex->query_tables) { - send_error(YYTHD, ER_SP_SUBSELECT_NYI); + my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), + MYF(0)); YYABORT; } if ($3) @@ -7155,7 +7236,7 @@ option_value: Error message also should be improved. */ - net_printf(YYTHD, ER_BAD_FIELD_ERROR, $1.base_name, "NEW"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), $1.base_name, "NEW"); YYABORT; } lex->sphead->add_instr(i); @@ -7221,7 +7302,8 @@ option_value: $3= $3 ? $3 : $2; if (!my_charset_same($2,$3)) { - net_printf(thd,ER_COLLATION_CHARSET_MISMATCH,$3->name,$2->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $3->name, $2->csname); YYABORT; } lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); @@ -7287,18 +7369,18 @@ internal_variable_name: { if ($1.str[0]=='O' || $1.str[0]=='o') { - net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "OLD", ""); + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", ""); YYABORT; } if (lex->trg_chistics.event == TRG_EVENT_DELETE) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", - "on DELETE"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), + "NEW", "on DELETE"); YYABORT; } if (lex->trg_chistics.action_time == TRG_ACTION_AFTER) { - net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "NEW", "after "); + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after "); YYABORT; } /* This special combination will denote field of NEW row */ @@ -7311,7 +7393,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name= $1; } @@ -7322,7 +7404,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name.str= (char*) "default"; $$.base_name.length= 7; @@ -7489,7 +7571,7 @@ revoke_command: grant_privileges ON opt_table FROM user_list {} | - ALL PRIVILEGES ',' GRANT OPTION FROM user_list + ALL opt_privileges ',' GRANT OPTION FROM user_list { Lex->sql_command = SQLCOM_REVOKE_ALL; } @@ -7515,10 +7597,14 @@ grant: grant_privileges: grant_privilege_list {} - | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;} - | ALL { Lex->grant = GLOBAL_ACLS;} + | ALL opt_privileges { Lex->grant = GLOBAL_ACLS;} ; +opt_privileges: + /* empty */ + | PRIVILEGES + ; + grant_privilege_list: grant_privilege | grant_privilege_list ',' grant_privilege; @@ -7567,7 +7653,7 @@ require_list_element: LEX *lex=Lex; if (lex->x509_subject) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "SUBJECT"); + my_error(ER_DUP_ARGUMENT, MYF(0), "SUBJECT"); YYABORT; } lex->x509_subject=$2.str; @@ -7577,7 +7663,7 @@ require_list_element: LEX *lex=Lex; if (lex->x509_issuer) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "ISSUER"); + my_error(ER_DUP_ARGUMENT, MYF(0), "ISSUER"); YYABORT; } lex->x509_issuer=$2.str; @@ -7587,7 +7673,7 @@ require_list_element: LEX *lex=Lex; if (lex->ssl_cipher) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "CIPHER"); + my_error(ER_DUP_ARGUMENT, MYF(0), "CIPHER"); YYABORT; } lex->ssl_cipher=$2.str; @@ -7603,7 +7689,8 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } @@ -7615,7 +7702,8 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } @@ -7627,7 +7715,8 @@ opt_table: lex->grant= GLOBAL_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } @@ -7767,7 +7856,7 @@ grant_option: ; begin: - BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work {} + BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN; Lex->start_transaction_opt= 0;} opt_work {} ; opt_work: @@ -7812,7 +7901,7 @@ union_list: if (lex->exchange) { /* Only the last SELECT can have INTO...... */ - net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "INTO"); + my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) diff --git a/sql/table.cc b/sql/table.cc index 0e8045abacf..6702a9acf0a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -984,11 +984,11 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) uint length=dirname_part(buff,name); buff[length-1]=0; db=buff+dirname_length(buff); - my_error(ER_NO_SUCH_TABLE,MYF(0),db,form->real_name); + my_error(ER_NO_SUCH_TABLE, MYF(0), db, form->real_name); } else - my_error(ER_FILE_NOT_FOUND,errortype, - fn_format(buff,name,form_dev,reg_ext,0),my_errno); + my_error(ER_FILE_NOT_FOUND, errortype, + fn_format(buff, name, form_dev, reg_ext, 0), my_errno); break; case 2: { @@ -996,14 +996,14 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) datext= datext==NullS ? "" : datext; err_no= (my_errno == ENOENT) ? ER_FILE_NOT_FOUND : (my_errno == EAGAIN) ? ER_FILE_USED : ER_CANT_OPEN_FILE; - my_error(err_no,errortype, - fn_format(buff,form->real_name,form_dev,datext,2),my_errno); + my_error(err_no, errortype, + fn_format(buff, form->real_name, form_dev, datext, 2), my_errno); break; } default: /* Better wrong error than none */ case 4: - my_error(ER_NOT_FORM_FILE,errortype, - fn_format(buff,name,form_dev,reg_ext,0)); + my_error(ER_NOT_FORM_FILE, errortype, + fn_format(buff, name, form_dev, reg_ext, 0)); break; } DBUG_VOID_RETURN; @@ -1520,6 +1520,7 @@ void st_table_list::set_ancestor() if (ancestor->ancestor) ancestor->set_ancestor(); table= ancestor->table; + schema_table= ancestor->schema_table; ancestor->table->grant= grant; } diff --git a/sql/table.h b/sql/table.h index f95be1fcccb..db3ce638842 100644 --- a/sql/table.h +++ b/sql/table.h @@ -204,6 +204,58 @@ struct st_table { }; +typedef struct st_foreign_key_info +{ + LEX_STRING *forein_id; + LEX_STRING *referenced_db; + LEX_STRING *referenced_table; + LEX_STRING *constraint_method; + List<LEX_STRING> foreign_fields; + List<LEX_STRING> referenced_fields; +} FOREIGN_KEY_INFO; + + +enum enum_schema_tables +{ + SCH_SCHEMATA= 0, SCH_TABLES, SCH_COLUMNS, SCH_CHARSETS, SCH_COLLATIONS, + SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_PROCEDURES, SCH_STATISTICS, + SCH_VIEWS, SCH_USER_PRIVILEGES, SCH_SCHEMA_PRIVILEGES, SCH_TABLE_PRIVILEGES, + SCH_COLUMN_PRIVILEGES, SCH_TABLE_CONSTRAINTS, SCH_KEY_COLUMN_USAGE, + SCH_TABLE_NAMES +}; + + +typedef struct st_field_info +{ + const char* field_name; + uint field_length; + enum enum_field_types field_type; + int value; + bool maybe_null; + bool utf8; + const char* old_name; +} ST_FIELD_INFO; + +struct st_table_list; +typedef class Item COND; + +typedef struct st_schema_table +{ + const char* table_name; + ST_FIELD_INFO *fields_info; + /* Create information_schema table */ + TABLE *(*create_table) (THD *thd, struct st_schema_table *schema_table); + /* Fill table with data */ + int (*fill_table) (THD *thd, struct st_table_list *tables, COND *cond); + /* Handle fileds for old SHOW */ + int (*old_format) (THD *thd, struct st_schema_table *schema_table); + int (*process_table) (THD *thd, struct st_table_list *tables, + TABLE *table, bool res, const char *base_name, + const char *file_name); + int idx_field1, idx_field2; +} ST_SCHEMA_TABLE; + + #define JOIN_TYPE_LEFT 1 #define JOIN_TYPE_RIGHT 2 @@ -252,6 +304,8 @@ typedef struct st_table_list */ st_table_list *correspondent_table; st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */ + ST_SCHEMA_TABLE *schema_table; /* Information_schema table */ + st_select_lex *schema_select_lex; /* link to select_lex where this table was used */ st_select_lex *select_lex; st_lex *view; /* link on VIEW lex for merging */ diff --git a/sql/unireg.cc b/sql/unireg.cc index decac2a0549..636156940a4 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -383,7 +383,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, if (create_fields.elements > MAX_FIELDS) { - my_error(ER_TOO_MANY_FIELDS,MYF(0)); + my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0)); DBUG_RETURN(1); } @@ -448,7 +448,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, if (info_length+(ulong) create_fields.elements*FCOMP+288+ n_length+int_length+com_length > 65535L || int_count > 255) { - my_error(ER_TOO_MANY_FIELDS,MYF(0)); + my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0)); DBUG_RETURN(1); } diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 268f7d18f2a..4d7c17e977c 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -52,15 +52,30 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) if (*fmt == '-') fmt++; length= width= pre_zero= have_long= 0; - for (;my_isdigit(&my_charset_latin1,*fmt); fmt++) + if (*fmt == '*') { - length=length*10+ (uint) (*fmt-'0'); - if (!length) - pre_zero= 1; /* first digit was 0 */ + fmt++; + length= va_arg(ap, int); } + else + for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) + { + length= length * 10 + (uint)(*fmt - '0'); + if (!length) + pre_zero= 1; /* first digit was 0 */ + } if (*fmt == '.') - for (fmt++;my_isdigit(&my_charset_latin1,*fmt); fmt++) - width=width*10+ (uint) (*fmt-'0'); + { + fmt++; + if (*fmt == '*') + { + fmt++; + width= va_arg(ap, int); + } + else + for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) + width= width * 10 + (uint)(*fmt - '0'); + } else width= ~0; if (*fmt == 'l') diff --git a/tests/client_test.c b/tests/client_test.c index e03be170a03..034d846017a 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -21,13 +21,19 @@ Main author: venu ( venu@mysql.com ) ***************************************************************************/ +/* + XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST + DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. +*/ + + #include <my_global.h> #include <my_sys.h> #include <mysql.h> #include <my_getopt.h> #include <m_string.h> -#define VER "2.0" +#define VER "2.1" #define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ #define MAX_KEY 64 @@ -53,6 +59,12 @@ static double total_time; const char *default_dbug_option= "d:t:o,/tmp/client_test.trace"; +struct my_tests_st +{ + const char *name; + void (*function)(); +}; + #define myheader(str) \ if (opt_silent < 2) \ { \ @@ -216,6 +228,7 @@ static void client_connect() if (!(mysql= mysql_init(NULL))) { + opt_silent= 0; myerror("mysql_init() failed"); exit(1); } @@ -224,6 +237,7 @@ static void client_connect() opt_password, opt_db ? opt_db:"test", opt_port, opt_unix_socket, 0))) { + opt_silent= 0; myerror("connection failed"); mysql_close(mysql); fprintf(stdout, "\n Check the connection options using --help or -?\n"); @@ -641,10 +655,12 @@ static void verify_prepare_field(MYSQL_RES *result, fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)", field->org_name, org_name); fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type); - fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", - field->table, table); - fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", - field->org_table, org_table); + if (table) + fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", + field->table, table); + if (org_table) + fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", + field->org_table, org_table); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n length :`%ld`\t(expected: `%ld`)", field->length, length); @@ -657,8 +673,10 @@ static void verify_prepare_field(MYSQL_RES *result, DIE_UNLESS(strcmp(field->name, name) == 0); DIE_UNLESS(strcmp(field->org_name, org_name) == 0); DIE_UNLESS(field->type == type); - DIE_UNLESS(strcmp(field->table, table) == 0); - DIE_UNLESS(strcmp(field->org_table, org_table) == 0); + if (table) + DIE_UNLESS(strcmp(field->table, table) == 0); + if (org_table) + DIE_UNLESS(strcmp(field->org_table, org_table) == 0); DIE_UNLESS(strcmp(field->db, db) == 0); DIE_UNLESS(field->length == length); if (def) @@ -7242,23 +7260,23 @@ static void test_explain_bug() mysql_num_fields(result)); DIE_UNLESS(6 == mysql_num_fields(result)); - verify_prepare_field(result, 0, "Field", "", MYSQL_TYPE_VAR_STRING, - "", "", "", NAME_LEN, 0); + verify_prepare_field(result, 0, "Field", "COLUMN_NAME", + MYSQL_TYPE_STRING, 0, 0, "", NAME_LEN, 0); - verify_prepare_field(result, 1, "Type", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 40, 0); + verify_prepare_field(result, 1, "Type", "TYPE", + MYSQL_TYPE_STRING, 0, 0, "", 40, 0); - verify_prepare_field(result, 2, "Null", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 1, 0); + verify_prepare_field(result, 2, "Null", "IS_NULLABLE", + MYSQL_TYPE_STRING, 0, 0, "", 3, 0); - verify_prepare_field(result, 3, "Key", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 3, 0); + verify_prepare_field(result, 3, "Key", "KEY", + MYSQL_TYPE_STRING, 0, 0, "", 3, 0); - verify_prepare_field(result, 4, "Default", "", MYSQL_TYPE_VAR_STRING, - "", "", "", NAME_LEN, 0); + verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", + MYSQL_TYPE_STRING, 0, 0, "", NAME_LEN, 0); - verify_prepare_field(result, 5, "Extra", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 20, 0); + verify_prepare_field(result, 5, "Extra", "EXTRA", + MYSQL_TYPE_STRING, 0, 0, "", 20, 0); mysql_free_result(result); mysql_stmt_close(stmt); @@ -11860,31 +11878,35 @@ static char **defaults_argv; static struct my_option client_test_long_options[] = { - {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, - 0, 0, 0, 0, 0}, + {"count", 't', "Number of times test to be executed", (char **) &opt_count, + (char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, {"database", 'D', "Database to use", (char **) &opt_db, (char **) &opt_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"debug", '#', "Output debug log", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"host", 'h', "Connect to host", (char **) &opt_host, (char **) &opt_host, 0, GET_STR_ALLOC, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host", (char **) &opt_host, (char **) &opt_host, + 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DONT_ALLOW_USER_CHANGE - {"user", 'u', "User for login if not current user", (char **) &opt_user, - (char **) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif {"port", 'P', "Port number to use for connection", (char **) &opt_port, (char **) &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"socket", 'S', "Socket file to use for connection", (char **) &opt_unix_socket, - (char **) &opt_unix_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"testcase", 'c', "May disable some code when runs as mysql-test-run testcase.", + {"socket", 'S', "Socket file to use for connection", + (char **) &opt_unix_socket, (char **) &opt_unix_socket, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"testcase", 'c', + "May disable some code when runs as mysql-test-run testcase.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"count", 't', "Number of times test to be executed", (char **) &opt_count, - (char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, +#ifndef DONT_ALLOW_USER_CHANGE + {"user", 'u', "User for login if not current user", (char **) &opt_user, + (char **) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -11900,13 +11922,169 @@ static void usage(void) Copyright (C) 2002-2004 MySQL AB\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ and you are welcome to modify and redistribute it under the GPL license\n"); - printf("Usage: %s [OPTIONS]\n", my_progname); + printf("Usage: %s [OPTIONS] [TESTNAME1 TESTNAME2...]\n", my_progname); my_print_help(client_test_long_options); print_defaults("my", client_test_load_default_groups); my_print_variables(client_test_long_options); } +static struct my_tests_st my_tests[]= { + { "client_query", client_query }, +#if NOT_YET_WORKING + { "test_drop_temp", test_drop_temp }, +#endif + { "test_fetch_seek", test_fetch_seek }, + { "test_fetch_nobuffs", test_fetch_nobuffs }, + { "test_open_direct", test_open_direct }, + { "test_fetch_null", test_fetch_null }, + { "test_ps_null_param", test_ps_null_param }, + { "test_fetch_date", test_fetch_date }, + { "test_fetch_str", test_fetch_str }, + { "test_fetch_long", test_fetch_long }, + { "test_fetch_short", test_fetch_short }, + { "test_fetch_tiny", test_fetch_tiny }, + { "test_fetch_bigint", test_fetch_bigint }, + { "test_fetch_float", test_fetch_float }, + { "test_fetch_double", test_fetch_double }, + { "test_bind_result_ext", test_bind_result_ext }, + { "test_bind_result_ext1", test_bind_result_ext1 }, + { "test_select_direct", test_select_direct }, + { "test_select_prepare", test_select_prepare }, + { "test_select", test_select }, + { "test_select_version", test_select_version }, + { "test_ps_conj_select", test_ps_conj_select }, + { "test_select_show_table", test_select_show_table }, + { "test_func_fields", test_func_fields }, + { "test_long_data", test_long_data }, + { "test_insert", test_insert }, + { "test_set_variable", test_set_variable }, + { "test_select_show", test_select_show }, + { "test_prepare_noparam", test_prepare_noparam }, + { "test_bind_result", test_bind_result }, + { "test_prepare_simple", test_prepare_simple }, + { "test_prepare", test_prepare }, + { "test_null", test_null }, + { "test_debug_example", test_debug_example }, + { "test_update", test_update }, + { "test_simple_update", test_simple_update }, + { "test_simple_delete", test_simple_delete }, + { "test_double_compare", test_double_compare }, + { "client_store_result", client_store_result }, + { "client_use_result", client_use_result }, + { "test_tran_bdb", test_tran_bdb }, + { "test_tran_innodb", test_tran_innodb }, + { "test_prepare_ext", test_prepare_ext }, + { "test_prepare_syntax", test_prepare_syntax }, + { "test_field_names", test_field_names }, + { "test_field_flags", test_field_flags }, + { "test_long_data_str", test_long_data_str }, + { "test_long_data_str1", test_long_data_str1 }, + { "test_long_data_bin", test_long_data_bin }, + { "test_warnings", test_warnings }, + { "test_errors", test_errors }, + { "test_prepare_resultset", test_prepare_resultset }, + { "test_stmt_close", test_stmt_close }, + { "test_prepare_field_result", test_prepare_field_result }, + { "test_multi_stmt", test_multi_stmt }, + { "test_multi_statements", test_multi_statements }, + { "test_prepare_multi_statements", test_prepare_multi_statements }, + { "test_store_result", test_store_result }, + { "test_store_result1", test_store_result1 }, + { "test_store_result2", test_store_result2 }, + { "test_subselect", test_subselect }, + { "test_date", test_date }, + { "test_date_date", test_date_date }, + { "test_date_time", test_date_time }, + { "test_date_ts", test_date_ts }, + { "test_date_dt", test_date_dt }, + { "test_prepare_alter", test_prepare_alter }, + { "test_manual_sample", test_manual_sample }, + { "test_pure_coverage", test_pure_coverage }, + { "test_buffers", test_buffers }, + { "test_ushort_bug", test_ushort_bug }, + { "test_sshort_bug", test_sshort_bug }, + { "test_stiny_bug", test_stiny_bug }, + { "test_field_misc", test_field_misc }, + { "test_set_option", test_set_option }, +#ifndef EMBEDDED_LIBRARY + { "test_prepare_grant", test_prepare_grant }, +#endif + { "test_frm_bug", test_frm_bug }, + { "test_explain_bug", test_explain_bug }, + { "test_decimal_bug", test_decimal_bug }, + { "test_nstmts", test_nstmts }, + { "test_logs;", test_logs }, + { "test_cuted_rows", test_cuted_rows }, + { "test_fetch_offset", test_fetch_offset }, + { "test_fetch_column", test_fetch_column }, + { "test_mem_overun", test_mem_overun }, + { "test_list_fields", test_list_fields }, + { "test_free_result", test_free_result }, + { "test_free_store_result", test_free_store_result }, + { "test_sqlmode", test_sqlmode }, + { "test_ts", test_ts }, + { "test_bug1115", test_bug1115 }, + { "test_bug1180", test_bug1180 }, + { "test_bug1500", test_bug1500 }, + { "test_bug1644", test_bug1644 }, + { "test_bug1946", test_bug1946 }, + { "test_bug2248", test_bug2248 }, + { "test_parse_error_and_bad_length", test_parse_error_and_bad_length }, + { "test_bug2247", test_bug2247 }, + { "test_subqueries", test_subqueries }, + { "test_bad_union", test_bad_union }, + { "test_distinct", test_distinct }, + { "test_subqueries_ref", test_subqueries_ref }, + { "test_union", test_union }, + { "test_bug3117", test_bug3117 }, + { "test_join", test_join }, + { "test_selecttmp", test_selecttmp }, + { "test_create_drop", test_create_drop }, + { "test_rename", test_rename }, + { "test_do_set", test_do_set }, + { "test_multi", test_multi }, + { "test_insert_select", test_insert_select }, + { "test_bind_nagative", test_bind_nagative }, + { "test_derived", test_derived }, + { "test_xjoin", test_xjoin }, + { "test_bug3035", test_bug3035 }, + { "test_union2", test_union2 }, + { "test_bug1664", test_bug1664 }, + { "test_union_param", test_union_param }, + { "test_order_param", test_order_param }, + { "test_ps_i18n", test_ps_i18n }, + { "test_bug3796", test_bug3796 }, + { "test_bug4026", test_bug4026 }, + { "test_bug4079", test_bug4079 }, + { "test_bug4236", test_bug4236 }, + { "test_bug4030", test_bug4030 }, + { "test_bug5126", test_bug5126 }, + { "test_bug4231", test_bug4231 }, + { "test_bug5399", test_bug5399 }, + { "test_bug5194", test_bug5194 }, + { "test_bug5315", test_bug5315 }, + { "test_bug6049", test_bug6049 }, + { "test_bug6058", test_bug6058 }, + { "test_bug6059", test_bug6059 }, + { "test_bug6046", test_bug6046 }, + { "test_bug6081", test_bug6081 }, + { "test_bug6096", test_bug6096 }, + { "test_bug4172", test_bug4172 }, + { "test_conversion", test_conversion }, + { "test_view", test_view }, + { "test_view_where", test_view_where }, + { "test_view_2where", test_view_2where }, + { "test_view_star", test_view_star }, + { "test_view_insert", test_view_insert }, + { "test_left_join_view", test_left_join_view }, + { "test_view_insert_fields", test_view_insert_fields }, + { "test_basic_cursors", test_basic_cursors }, + { "test_cursors_with_union", test_cursors_with_union }, + { 0, 0 } +}; + + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) @@ -11937,6 +12115,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else opt_silent++; break; + case 'T': + { + struct my_tests_st *fptr; + + printf("All possible test names:\n\n"); + for (fptr= my_tests; fptr->name; fptr++) + printf("%s\n", fptr->name); + exit(0); + break; + } case '?': case 'I': /* Info */ usage(); @@ -11946,11 +12134,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), return 0; } -static void get_options(int argc, char **argv) +static void get_options(int *argc, char ***argv) { int ho_error; - if ((ho_error= handle_options(&argc, &argv, client_test_long_options, + if ((ho_error= handle_options(argc, argv, client_test_long_options, get_one_option))) exit(ho_error); @@ -11983,14 +12171,17 @@ static void print_test_output() main routine ***************************************************************************/ + int main(int argc, char **argv) { + struct my_tests_st *fptr; + DEBUGGER_OFF; MY_INIT(argv[0]); - + load_defaults("my", client_test_load_default_groups, &argc, &argv); defaults_argv= argv; - get_options(argc, argv); + get_options(&argc, &argv); client_connect(); /* connect to server */ @@ -11999,193 +12190,35 @@ int main(int argc, char **argv) { /* Start of tests */ test_count= 1; - start_time= time((time_t *)0); - - client_query(); /* simple client query test */ -#if NOT_YET_WORKING - /* Used for internal new development debugging */ - test_drop_temp(); /* Test DROP TEMPORARY TABLE Access checks */ -#endif - test_fetch_seek(); /* Test stmt seek() functions */ - test_fetch_nobuffs(); /* to fecth without prior bound buffers */ - test_open_direct(); /* direct execution in the middle of open stmts */ - test_fetch_null(); /* to fetch null data */ - test_ps_null_param(); /* Fetch value of null parameter */ - test_fetch_date(); /* to fetch date, time and timestamp */ - test_fetch_str(); /* to fetch string to all types */ - test_fetch_long(); /* to fetch long to all types */ - test_fetch_short(); /* to fetch short to all types */ - test_fetch_tiny(); /* to fetch tiny to all types */ - test_fetch_bigint(); /* to fetch bigint to all types */ - test_fetch_float(); /* to fetch float to all types */ - test_fetch_double(); /* to fetch double to all types */ - test_bind_result_ext(); /* result bind test - extension */ - test_bind_result_ext1(); /* result bind test - extension */ - test_select_direct(); /* direct select - protocol_simple debug */ - test_select_prepare(); /* prepare select - protocol_prep debug */ - test_select(); /* simple select test */ - test_select_version(); /* select with variables */ - test_ps_conj_select(); /* prepare select with "where a=? or b=?" */ - test_select_show_table();/* simple show prepare */ -#if NOT_USED - /* - Enable this tests from 4.1.1 when mysql_param_result() is - supported - */ - test_select_meta(); /* select param meta information */ - test_update_meta(); /* update param meta information */ - test_insert_meta(); /* insert param meta information */ -#endif - test_func_fields(); /* test for new 4.1 MYSQL_FIELD members */ - test_long_data(); /* test for sending text data in chunks */ - test_insert(); /* simple insert test - prepare */ - test_set_variable(); /* prepare with set variables */ - test_select_show(); /* prepare - show test */ - test_prepare_noparam(); /* prepare without parameters */ - test_bind_result(); /* result bind test */ - test_prepare_simple(); /* simple prepare */ - test_prepare(); /* prepare test */ - test_null(); /* test null data handling */ - test_debug_example(); /* some debugging case */ - test_update(); /* prepare-update test */ - test_simple_update(); /* simple prepare with update */ - test_simple_delete(); /* prepare with delete */ - test_double_compare(); /* float comparision */ - client_store_result(); /* usage of mysql_store_result() */ - client_use_result(); /* usage of mysql_use_result() */ - test_tran_bdb(); /* transaction test on BDB table type */ - test_tran_innodb(); /* transaction test on InnoDB table type */ - test_prepare_ext(); /* test prepare with all types - conversion -- TODO */ - test_prepare_syntax(); /* syntax check for prepares */ - test_field_names(); /* test for field names */ - test_field_flags(); /* test to help .NET provider team */ - test_long_data_str(); /* long data handling */ - test_long_data_str1(); /* yet another long data handling */ - test_long_data_bin(); /* long binary insertion */ - test_warnings(); /* show warnings test */ - test_errors(); /* show errors test */ - test_prepare_resultset();/* prepare meta info test */ - test_stmt_close(); /* mysql_stmt_close() test -- hangs */ - test_prepare_field_result(); /* prepare meta info */ - test_multi_stmt(); /* multi stmt test */ - test_multi_statements();/* test multi statement execution */ - test_prepare_multi_statements(); /* check that multi statements are - disabled in PS */ - test_store_result(); /* test the store_result */ - test_store_result1(); /* test store result without buffers */ - test_store_result2(); /* test store result for misc case */ - test_subselect(); /* test subselect prepare -TODO*/ - test_date(); /* test the MYSQL_TIME conversion */ - test_date_date(); /* test conversion from DATE to all */ - test_date_time(); /* test conversion from TIME to all */ - test_date_ts() ; /* test conversion from TIMESTAMP to all */ - test_date_dt() ; /* test conversion from DATETIME to all */ - test_prepare_alter(); /* change table schema in middle of prepare */ - test_manual_sample(); /* sample in the manual */ - test_pure_coverage(); /* keep pure coverage happy */ - test_buffers(); /* misc buffer handling */ - test_ushort_bug(); /* test a simple conv bug from php */ - test_sshort_bug(); /* test a simple conv bug from php */ - test_stiny_bug(); /* test a simple conv bug from php */ - test_field_misc(); /* check the field info for misc case, bug: #74 */ - test_set_option(); /* test the SET OPTION feature, bug #85 */ - /*TODO HF: here should be NO_EMBEDDED_ACCESS_CHECKS*/ -#ifndef EMBEDDED_LIBRARY - test_prepare_grant(); /* Test the GRANT command, bug #89 */ -#endif - test_frm_bug(); /* test the crash when .frm is invalid, bug #93 */ - test_explain_bug(); /* test for the EXPLAIN, bug #115 */ - test_decimal_bug(); /* test for the decimal bug */ - test_nstmts(); /* test n statements */ - test_logs(); ; /* Test logs */ - test_cuted_rows(); /* Test for WARNINGS from cuted rows */ - test_fetch_offset(); /* Test mysql_stmt_fetch_column with offset */ - test_fetch_column(); /* Test mysql_stmt_fetch_column */ - test_mem_overun(); /* test DBD ovverun bug */ - test_list_fields(); /* test COM_LIST_FIELDS for DEFAULT */ - test_free_result(); /* test mysql_stmt_free_result() */ - test_free_store_result(); /* test to make sure stmt results are cleared - during stmt_free_result() */ - test_sqlmode(); /* test for SQL_MODE */ - test_ts(); /* test for timestamp BR#819 */ - test_bug1115(); /* BUG#1115 */ - test_bug1180(); /* BUG#1180 */ - test_bug1500(); /* BUG#1500 */ - test_bug1644(); /* BUG#1644 */ - test_bug1946(); /* test that placeholders are allowed only in - prepared queries */ - test_bug2248(); /* BUG#2248 */ - test_parse_error_and_bad_length(); /* test if bad length param in - mysql_stmt_prepare() triggers error */ - test_bug2247(); /* test that mysql_stmt_affected_rows() returns - number of rows affected by last prepared - statement execution */ - test_subqueries(); /* repeatable subqueries */ - test_bad_union(); /* correct setup of UNION */ - test_distinct(); /* distinct aggregate functions */ - test_subqueries_ref(); /* outer reference in subqueries converted - Item_field -> Item_ref */ - test_union(); /* test union with prepared statements */ - test_bug3117(); /* BUG#3117: LAST_INSERT_ID() */ - test_join(); /* different kinds of join, BUG#2794 */ - test_selecttmp(); /* temporary table used in select execution */ - test_create_drop(); /* some table manipulation BUG#2811 */ - test_rename(); /* rename test */ - test_do_set(); /* DO & SET commands test BUG#3393 */ - test_multi(); /* test of multi delete & update */ - test_insert_select(); /* test INSERT ... SELECT */ - test_bind_nagative(); /* bind negative to unsigned BUG#3223 */ - test_derived(); /* derived table with parameter BUG#3020 */ - test_xjoin(); /* complex join test */ - test_bug3035(); /* inserts of INT32_MAX/UINT32_MAX */ - test_union2(); /* repeatable execution of union (Bug #3577) */ - test_bug1664(); /* test for bugs in mysql_stmt_send_long_data() - call (Bug #1664) */ - test_union_param(); - test_order_param(); /* ORDER BY with parameters in select list - (Bug #3686 */ - test_ps_i18n(); /* test for i18n support in binary protocol */ - test_bug3796(); /* test for select concat(?, <string>) */ - test_bug4026(); /* test microseconds precision of time types */ - test_bug4079(); /* erroneous subquery in prepared statement */ - test_bug4236(); /* init -> execute */ - test_bug4030(); /* test conversion string -> time types in - libmysql */ - test_bug5126(); /* support for mediumint type in libmysql */ - test_bug4231(); /* proper handling of all-zero times and - dates in the server */ - test_bug5399(); /* check that statement id uniquely identifies - statement */ - test_bug5194(); /* bulk inserts in prepared mode */ - test_bug5315(); /* check that mysql_change_user closes all - prepared statements */ - test_bug6049(); /* check support for negative TIME values */ - test_bug6058(); /* check support for 0000-00-00 dates */ - test_bug6059(); /* correct metadata for SELECT ... INTO OUTFILE */ - test_bug6046(); /* NATURAL JOIN transformation works in PS */ - test_bug6081(); /* test of mysql_create_db()/mysql_rm_db() */ - test_bug6096(); /* max_length for numeric columns */ - test_bug4172(); /* floating point conversions in libmysql */ - - test_conversion(); /* placeholder value is not converted to - character set of column if character set - of connection equals to character set of - client */ - test_view(); /* Test of VIEWS with prepared statements */ - test_view_where(); /* VIEW with WHERE clause & merge algorithm */ - test_view_2where(); /* VIEW with WHERE * SELECt with WHERE */ - test_view_star(); /* using query with * from VIEW */ - test_view_insert(); /* inserting in VIEW without field list */ - test_left_join_view(); /* left join on VIEW with WHERE condition */ - test_view_insert_fields(); /* insert into VIOEW with fields list */ - test_basic_cursors(); - test_cursors_with_union(); - /* - XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST - DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. - */ + if (!argc) + { + for (fptr= my_tests; fptr->name; fptr++) + (*fptr->function)(); + } + else + { + for ( ; *argv ; argv++) + { + for (fptr= my_tests; fptr->name; fptr++) + { + if (!strcmp(fptr->name, *argv)) + { + (*fptr->function)(); + break; + } + } + if (!fptr->name) + { + fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv); + fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n", + my_progname); + client_disconnect(); + free_defaults(defaults_argv); + exit(1); + } + } + } end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); |