diff options
101 files changed, 1312 insertions, 1033 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index c89c60287fd..0b60ac21b0f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -106,6 +106,7 @@ monty@tik. monty@tik.mysql.fi monty@tramp.mysql.fi monty@work.mysql.com +msvensson@build.mysql.com mwagner@cash.mwagner.org mwagner@evoq.mwagner.org mwagner@work.mysql.com @@ -160,6 +161,7 @@ tim@white.box tim@work.mysql.com tom@basil-firewall.home.com tomas@mc05.(none) +tomas@poseidon.(none) tonu@hundin.mysql.fi tonu@volk.internalnet tonu@x153.internalnet diff --git a/Build-tools/mysql-copyright-2 b/Build-tools/mysql-copyright-2 index 447a2d7c164..e946ed217d1 100755 --- a/Build-tools/mysql-copyright-2 +++ b/Build-tools/mysql-copyright-2 @@ -93,7 +93,7 @@ sub add_copyright { $start_copyright="/* "; $line_copyright= " "; - $end_copyright= " */"; + $end_copyright= "*/"; } elsif ($ARGV =~ /-x86\.s$/) { diff --git a/client/mysql.cc b/client/mysql.cc index 3cf4a01a9cf..d3885645124 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1245,7 +1245,6 @@ static void fix_history(String *final_command) static int not_in_history(const char *line) { HIST_ENTRY *oldhist = history_get(history_length); - int num; if (oldhist == 0) return 1; @@ -1595,7 +1594,6 @@ static int com_server_help(String *buffer __attribute__((unused)), const char *server_cmd= buffer->ptr(); char cmd_buf[100]; MYSQL_RES *result; - MYSQL_FIELD *fields; int error; if (help_arg[0] != '\'') @@ -1621,7 +1619,7 @@ static int com_server_help(String *buffer __attribute__((unused)), { unsigned int num_fields= mysql_num_fields(result); my_ulonglong num_rows= mysql_num_rows(result); - fields= mysql_fetch_fields(result); + mysql_fetch_fields(result); if (num_fields==3 && num_rows==1) { if (!(cur= mysql_fetch_row(result))) @@ -2410,6 +2408,10 @@ static int com_shell(String *buffer, char *line __attribute__((unused))) { char *shell_cmd; + + /* Skip space from line begin */ + while (my_isspace(charset_info, *line)) + line++; if (!(shell_cmd = strchr(line, ' '))) { put_info("Usage: \\! shell-command", INFO_ERROR); diff --git a/client/mysqldump.c b/client/mysqldump.c index 20792f8c025..97ae0070e04 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1264,18 +1264,32 @@ static char *field_escape(char *to,const char *from,uint length) } /* field_escape */ +static char *alloc_query_str(ulong size) +{ + char *query; + + if (!(query= (char*) my_malloc(size, MYF(MY_WME)))) + { + ignore_errors= 0; /* Fatal error */ + safe_exit(EX_MYSQLERR); /* Force exit */ + } + return query; +} + /* ** dumpTable saves database contents as a series of INSERT statements. */ static void dumpTable(uint numFields, char *table) { - char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; + char *query= query_buf; MYSQL_RES *res; MYSQL_FIELD *field; MYSQL_ROW row; ulong rownr, row_break, total_length, init_length; const char *table_type; + int error= 0; result_table= quote_name(table,table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); @@ -1321,8 +1335,11 @@ static void dumpTable(uint numFields, char *table) sprintf(buff," FROM %s", result_table); end= strmov(end,buff); if (where) - end= strxmov(end, " WHERE ",where,NullS); - if (mysql_query(sock, query)) + { + query= alloc_query_str((ulong) (strlen(where) + (end - query) + 10)); + end= strxmov(query, query_buf, " WHERE ", where, NullS); + } + if (mysql_real_query(sock, query, (uint) (end - query))) { DBerror(sock, "when executing 'SELECT INTO OUTFILE'"); return; @@ -1339,14 +1356,16 @@ static void dumpTable(uint numFields, char *table) { if (!opt_xml && opt_comments) fprintf(md_result_file,"-- WHERE: %s\n",where); - strxmov(strend(query), " WHERE ",where,NullS); + query= alloc_query_str((ulong) (strlen(where) + strlen(query) + 10)); + strxmov(query, query_buf, " WHERE ", where, NullS); } if (!opt_xml && !opt_compact) fputs("\n", md_result_file); if (mysql_query(sock, query)) { DBerror(sock, "when retrieving data from server"); - return; + error= EX_CONSCHECK; + goto err; } if (quick) res=mysql_use_result(sock); @@ -1355,7 +1374,8 @@ static void dumpTable(uint numFields, char *table) if (!res) { DBerror(sock, "when retrieving data from server"); - return; + error= EX_CONSCHECK; + goto err; } if (verbose) fprintf(stderr, "-- Retrieving rows...\n"); @@ -1363,8 +1383,8 @@ static void dumpTable(uint numFields, char *table) { fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n", my_progname, result_table); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (opt_disable_keys) @@ -1402,8 +1422,8 @@ static void dumpTable(uint numFields, char *table) sprintf(query,"%s: Not enough fields from table %s! Aborting.\n", my_progname, result_table); fputs(query,stderr); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (extended_insert) { @@ -1422,7 +1442,8 @@ static void dumpTable(uint numFields, char *table) if (dynstr_realloc(&extended_row,length * 2+2)) { fputs("Aborting dump (out of memory)",stderr); - safe_exit(EX_EOM); + error= EX_EOM; + goto err; } dynstr_append(&extended_row,"'"); extended_row.length += @@ -1458,7 +1479,8 @@ static void dumpTable(uint numFields, char *table) else if (dynstr_append(&extended_row,"NULL")) { fputs("Aborting dump (out of memory)",stderr); - safe_exit(EX_EOM); + error= EX_EOM; + goto err; } } else @@ -1552,8 +1574,8 @@ static void dumpTable(uint numFields, char *table) result_table, rownr); fputs(query,stderr); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); @@ -1563,7 +1585,16 @@ static void dumpTable(uint numFields, char *table) if (opt_autocommit) fprintf(md_result_file, "commit;\n"); mysql_free_result(res); - } + if (query != query_buf) + my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + } + return; + +err: + if (query != query_buf) + my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + safe_exit(error); + return; } /* dumpTable */ diff --git a/client/mysqltest.c b/client/mysqltest.c index be5dac1c9d9..303473ef558 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -109,7 +109,7 @@ MYSQL_MANAGER* manager=0; static char **default_argv; static const char *load_default_groups[]= { "mysqltest","client",0 }; -static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer;; +static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer; static FILE* file_stack[MAX_INCLUDE_DEPTH]; static FILE** cur_file; @@ -1097,7 +1097,7 @@ int do_sync_with_master2(const char* p) MYSQL_ROW row; MYSQL* mysql = &cur_con->mysql; char query_buf[FN_REFLEN+128]; - int offset = 0; + int offset= 0, tries= 0; int rpl_parse; if (!master_pos.file[0]) @@ -1112,6 +1112,9 @@ int do_sync_with_master2(const char* p) sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, master_pos.pos + offset); + +wait_for_position: + if (mysql_query(mysql, query_buf)) die("line %u: failed in %s: %d: %s", start_lineno, query_buf, mysql_errno(mysql), mysql_error(mysql)); @@ -1122,8 +1125,20 @@ int do_sync_with_master2(const char* p) if (!(row = mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); if (!row[0]) - die("line %u: could not sync with master ('%s' returned NULL)", - start_lineno, query_buf); + { + /* + It may be that the slave SQL thread has not started yet, though START + SLAVE has been issued ? + */ + if (tries++ == 3) + { + die("line %u: could not sync with master ('%s' returned NULL)", + start_lineno, query_buf); + } + sleep(1); /* So at most we will wait 3 seconds and make 4 tries */ + mysql_free_result(res); + goto wait_for_position; + } mysql_free_result(res); last_result=0; if (rpl_parse) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 8388009dc9c..09f5c66f687 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -883,7 +883,7 @@ btr_page_reorganize_low( fprintf(stderr, "InnoDB: Error: page old data size %lu new data size %lu\n" "InnoDB: Error: page old max ins size %lu new max ins size %lu\n" -"InnoDB: Make a detailed bug report and send it to mysql@lists.mysql.com\n", +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", (unsigned long) data_size1, (unsigned long) data_size2, (unsigned long) max_ins_size1, (unsigned long) max_ins_size2); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b22d93d6bd8..6a6ac2492f8 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -70,7 +70,7 @@ dict_col_reposition_in_cache( /*=========================*/ dict_table_t* table, /* in: table */ dict_col_t* col, /* in: column */ - char* new_name); /* in: new table name */ + const char* new_name); /* in: new table name */ /************************************************************************** Removes a column from the data dictionary hash table. */ static @@ -309,7 +309,7 @@ dict_table_get_index_noninline( /*===========================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name) /* in: index name */ + const char* name) /* in: index name */ { return(dict_table_get_index(table, name)); } @@ -693,9 +693,10 @@ directory dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx) /* in: transaction handle or NULL */ { dict_table_t* table; @@ -722,9 +723,10 @@ Returns a table object and increments MySQL open handle count on the table. */ dict_table_t* dict_table_get_and_increment_handle_count( /*======================================*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx) /* in: transaction handle or NULL */ { dict_table_t* table; @@ -886,7 +888,7 @@ dict_table_rename_in_cache( /*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ - char* new_name, /* in: new name */ + const char* new_name, /* in: new name */ ibool rename_also_foreigns)/* in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ @@ -1294,7 +1296,7 @@ dict_col_reposition_in_cache( /*=========================*/ dict_table_t* table, /* in: table */ dict_col_t* col, /* in: column */ - char* new_name) /* in: new table name */ + const char* new_name) /* in: new table name */ { ulint fold; @@ -2019,7 +2021,7 @@ dict_foreign_find_index( column types must match */ { dict_index_t* index; - char* col_name; + const char* col_name; ulint i; index = dict_table_get_first_index(table); @@ -2564,14 +2566,14 @@ static char* dict_strip_comments( /*================*/ - /* out, own: SQL string stripped from - comments; the caller must free this - with mem_free()! */ - char* sql_string) /* in: SQL string */ + /* out, own: SQL string stripped from + comments; the caller must free this + with mem_free()! */ + const char* sql_string) /* in: SQL string */ { - char* str; - char* sptr; - char* ptr; + char* str; + const char* sptr; + char* ptr; str = mem_alloc(strlen(sql_string) + 1); @@ -2970,7 +2972,8 @@ col_loop1: } foreign->foreign_table = table; - foreign->foreign_table_name = table->name; + foreign->foreign_table_name = mem_heap_strdup(foreign->heap, + table->name); foreign->foreign_index = index; foreign->n_fields = i; foreign->foreign_col_names = mem_heap_alloc(foreign->heap, @@ -3244,16 +3247,19 @@ allowed to contain more fields than mentioned in the constraint. */ ulint dict_create_foreign_constraints( /*============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create or ALTER TABLE - statement where foreign keys are declared like: - FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2; the default - database is the database of parameter name */ - char* name) /* in: table full name in the normalized form - database_name/table_name */ + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: + FOREIGN KEY (a, b) REFERENCES + table2(c, d), table2 can be written + also with the database + name before it: test.table2; the + default database id the database of + parameter name */ + const char* name) /* in: table full name in the + normalized form + database_name/table_name */ { char* str; ulint err; @@ -4287,5 +4293,5 @@ dict_index_name_print( fputs("index ", file); ut_print_name(file, index->name); fputs(" of table ", file); - ut_print_name(stderr, index->table_name); + ut_print_name(file, index->table_name); } diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index abb06b15ea7..071a3b4c684 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -27,9 +27,10 @@ Finds the first table name in the given database. */ char* dict_get_first_table_name_in_db( /*============================*/ - /* out, own: table name, NULL if does not exist; - the caller must free the memory in the string! */ - char* name) /* in: database name which ends to '/' */ + /* out, own: table name, NULL if + does not exist; the caller must + free the memory in the string! */ + const char* name) /* in: database name which ends to '/' */ { dict_table_t* sys_tables; btr_pcur_t pcur; @@ -389,8 +390,8 @@ Report that an index field or index for a table has been delete marked. */ static void dict_load_report_deleted_index( - char* name, /* in: table name */ - ulint field) /* in: index field, or ULINT_UNDEFINED */ + const char* name, /* in: table name */ + ulint field) /* in: index field, or ULINT_UNDEFINED */ { fputs("InnoDB: Error: data dictionary entry" " for table ", stderr); @@ -688,12 +689,13 @@ dictionary cache. */ dict_table_t* dict_load_table( /*============*/ - /* out: table, NULL if does not exist; if the table is - stored in an .ibd file, but the file does not exist, - then we set the ibd_file_missing flag TRUE in the table - object we return */ - char* name) /* in: table name in the databasename/tablename - format */ + /* out: table, NULL if does not exist; + if the table is stored in an .ibd file, + but the file does not exist, + then we set the ibd_file_missing flag TRUE + in the table object we return */ + const char* name) /* in: table name in the + databasename/tablename format */ { ibool ibd_file_missing = FALSE; dict_table_t* table; @@ -849,7 +851,7 @@ dict_load_table( "InnoDB: the foreign key table or the referenced table!\n" "InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n" "InnoDB: and recreate the foreign key table or the referenced table.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf); mutex_exit(&dict_foreign_err_mutex); @@ -1185,8 +1187,8 @@ already in the dictionary cache. */ ulint dict_load_foreigns( /*===============*/ - /* out: DB_SUCCESS or error code */ - char* table_name) /* in: table name */ + /* out: DB_SUCCESS or error code */ + const char* table_name) /* in: table name */ { btr_pcur_t pcur; mem_heap_t* heap; diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index a4f83ddd657..936b06b1905 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -30,15 +30,14 @@ dict_table_t* dict_mem_table_create( /*==================*/ /* out, own: table object */ - char* name, /* in: table name */ - ulint space, /* in: space where the clustered index of + const char* name, /* in: table name */ + ulint space, /* in: space where the clustered index of the table is placed; this parameter is ignored if the table is made a member of a cluster */ - ulint n_cols) /* in: number of columns */ + ulint n_cols) /* in: number of columns */ { dict_table_t* table; - char* str; mem_heap_t* heap; ut_ad(name); @@ -48,11 +47,9 @@ dict_mem_table_create( table = mem_heap_alloc(heap, sizeof(dict_table_t)); table->heap = heap; - - str = mem_heap_strdup(heap, name); table->type = DICT_TABLE_ORDINARY; - table->name = str; + table->name = mem_heap_strdup(heap, name); table->space = space; table->ibd_file_missing = FALSE; table->tablespace_discarded = FALSE; @@ -103,11 +100,11 @@ dict_table_t* dict_mem_cluster_create( /*====================*/ /* out, own: cluster object */ - char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered indexes + const char* name, /* in: cluster name */ + ulint space, /* in: space where the clustered indexes of the member tables are placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len) /* in: length of the common key prefix in the + ulint n_cols, /* in: number of columns */ + ulint mix_len)/* in: length of the common key prefix in the cluster */ { dict_table_t* cluster; @@ -127,7 +124,7 @@ void dict_mem_table_make_cluster_member( /*===============================*/ dict_table_t* table, /* in: non-published table */ - char* cluster_name) /* in: cluster name */ + const char* cluster_name) /* in: cluster name */ { table->type = DICT_TABLE_CLUSTER_MEMBER; table->cluster_name = cluster_name; @@ -140,7 +137,7 @@ void dict_mem_table_add_col( /*===================*/ dict_table_t* table, /* in: table */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint mtype, /* in: main datatype */ ulint prtype, /* in: precise type */ ulint len, /* in: length */ @@ -174,14 +171,15 @@ Creates an index memory object. */ dict_index_t* dict_mem_index_create( /*==================*/ - /* out, own: index object */ - char* table_name, /* in: table name */ - char* index_name, /* in: index name */ - ulint space, /* in: space where the index tree is placed, - ignored if the index is of the clustered - type */ - ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ - ulint n_fields) /* in: number of fields */ + /* out, own: index object */ + const char* table_name, /* in: table name */ + const char* index_name, /* in: index name */ + ulint space, /* in: space where the index tree is + placed, ignored if the index is of + the clustered type */ + ulint type, /* in: DICT_UNIQUE, + DICT_CLUSTERED, ... ORed */ + ulint n_fields) /* in: number of fields */ { dict_index_t* index; mem_heap_t* heap; @@ -259,7 +257,7 @@ void dict_mem_index_add_field( /*=====================*/ dict_index_t* index, /* in: index */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint order, /* in: order criterion; 0 means an ascending order */ ulint prefix_len) /* in: 0 or the column prefix length diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index b9aff246802..28eea0ba188 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -390,11 +390,12 @@ Appends a new file to the chain of files of a space. File must be closed. */ void fil_node_create( /*============*/ - char* name, /* in: file name (file must be closed) */ - ulint size, /* in: file size in database blocks, rounded downwards - to an integer */ - ulint id, /* in: space id where to append */ - ibool is_raw) /* in: TRUE if a raw device or a raw disk partition */ + const char* name, /* in: file name (file must be closed) */ + ulint size, /* in: file size in database blocks, rounded + downwards to an integer */ + ulint id, /* in: space id where to append */ + ibool is_raw) /* in: TRUE if a raw device or + a raw disk partition */ { fil_system_t* system = fil_system; fil_node_t* node; @@ -804,10 +805,10 @@ there is an error, prints an error message to the .err log. */ ibool fil_space_create( /*=============*/ - /* out: TRUE if success */ - char* name, /* in: space name */ - ulint id, /* in: space id */ - ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ + /* out: TRUE if success */ + const char* name, /* in: space name */ + ulint id, /* in: space id */ + ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ { fil_system_t* system = fil_system; fil_space_t* space; @@ -1542,16 +1543,18 @@ static void fil_op_write_log( /*=============*/ - ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or - MLOG_FILE_RENAME */ - ulint space_id, /* in: space id */ - char* name, /* in: table name in the familiar - 'databasename/tablename' format, or the file - path in the case of MLOG_FILE_DELETE */ - char* new_name, /* in: if type is MLOG_FILE_RENAME, the new - table name in the 'databasename/tablename' - format */ - mtr_t* mtr) /* in: mini-transaction handle */ + ulint type, /* in: MLOG_FILE_CREATE, + MLOG_FILE_DELETE, or + MLOG_FILE_RENAME */ + ulint space_id, /* in: space id */ + const char* name, /* in: table name in the familiar + 'databasename/tablename' format, or + the file path in the case of + MLOG_FILE_DELETE */ + const char* new_name, /* in: if type is MLOG_FILE_RENAME, + the new table name in the + 'databasename/tablename' format */ + mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; @@ -1960,14 +1963,15 @@ tablespace memory cache. */ ibool fil_rename_tablespace( /*==================*/ - /* out: TRUE if success */ - char* old_name, /* in: old table name in the standard - databasename/tablename format of InnoDB, or - NULL if we do the rename based on the space - id only */ - ulint id, /* in: space id */ - char* new_name) /* in: new table name in the standard - databasename/tablename format of InnoDB */ + /* out: TRUE if success */ + const char* old_name, /* in: old table name in the standard + databasename/tablename format of + InnoDB, or NULL if we do the rename + based on the space id only */ + ulint id, /* in: space id */ + const char* new_name) /* in: new table name in the standard + databasename/tablename format + of InnoDB */ { fil_system_t* system = fil_system; ibool success; @@ -2124,15 +2128,16 @@ path '.'. */ ulint fil_create_new_single_table_tablespace( /*===================================*/ - /* out: DB_SUCCESS or error code */ - ulint* space_id, /* in/out: space id; if this is != 0, then - this is an input parameter, otherwise - output */ - char* tablename, /* in: the table name in the usual - databasename/tablename format of InnoDB */ - ulint size) /* in: the initial size of the tablespace file - in pages, must be >= FIL_IBD_FILE_INITIAL_SIZE - */ + /* out: DB_SUCCESS or error code */ + ulint* space_id, /* in/out: space id; if this is != 0, + then this is an input parameter, + otherwise output */ + const char* tablename, /* in: the table name in the usual + databasename/tablename format + of InnoDB */ + ulint size) /* in: the initial size of the + tablespace file in pages, + must be >= FIL_IBD_FILE_INITIAL_SIZE */ { os_file_t file; ibool ret; @@ -2293,12 +2298,12 @@ lsn's just by looking at that flush lsn. */ ibool fil_reset_too_high_lsns( /*====================*/ - /* out: TRUE if success */ - char* name, /* in: table name in the databasename/tablename - format */ - dulint current_lsn) /* in: reset lsn's if the lsn stamped to - FIL_PAGE_FILE_FLUSH_LSN in the first page is - too high */ + /* out: TRUE if success */ + const char* name, /* in: table name in the + databasename/tablename format */ + dulint current_lsn) /* in: reset lsn's if the lsn stamped + to FIL_PAGE_FILE_FLUSH_LSN in the + first page is too high */ { os_file_t file; char* filepath; @@ -2433,10 +2438,10 @@ closes it after we have looked at the space id in it. */ ibool fil_open_single_table_tablespace( /*=============================*/ - /* out: TRUE if success */ - ulint id, /* in: space id */ - char* name) /* in: table name in the databasename/tablename - format */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + const char* name) /* in: table name in the + databasename/tablename format */ { os_file_t file; char* filepath; @@ -2937,20 +2942,22 @@ there may be many tablespaces which are not yet in the memory cache. */ ibool fil_space_for_table_exists_in_mem( /*==============================*/ - /* out: TRUE if a matching tablespace exists - in the memory cache */ - ulint id, /* in: space id */ - char* name, /* in: table name in the standard - 'databasename/tablename' format */ - ibool mark_space, /* in: in crash recovery, at database startup - we mark all spaces which have an associated - table in the InnoDB data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist) - /* in: print detailed error information to - the .err log if a matching tablespace is - not found from memory */ + /* out: TRUE if a matching tablespace + exists in the memory cache */ + ulint id, /* in: space id */ + const char* name, /* in: table name in the standard + 'databasename/tablename' format */ + ibool mark_space, /* in: in crash recovery, at database + startup we mark all spaces which have + an associated table in the InnoDB + data dictionary, so that + we can print a warning about orphaned + tablespaces */ + ibool print_error_if_does_not_exist) + /* in: print detailed error + information to the .err log if a + matching tablespace is not found from + memory */ { fil_system_t* system = fil_system; fil_space_t* namespace; diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 7dc0bd98001..9246bb03138 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -2770,7 +2770,7 @@ ibuf_insert_to_index_page( fprintf(stderr, "Bitmap bits %lu\n", (ulong) old_bits); fputs( -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com!\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } } } @@ -2833,7 +2833,7 @@ ibuf_delete_rec( if (!success) { fprintf(stderr, - "InnoDB: ERROR: Send the output to mysql@lists.mysql.com\n" + "InnoDB: ERROR: Submit the output to http://bugs.mysql.com\n" "InnoDB: ibuf cursor restoration fails!\n" "InnoDB: ibuf record inserted to page %lu\n", (ulong) page_no); fflush(stderr); @@ -3025,8 +3025,7 @@ ibuf_merge_or_delete_for_page( "InnoDB: We try to resolve the problem by skipping the insert buffer\n" "InnoDB: merge for this page. Please run CHECK TABLE on your tables\n" "InnoDB: to determine if they are corrupt after this.\n\n" -"InnoDB: Please make a detailed bug report and send it to\n" -"InnoDB: mysql@lists.mysql.com\n\n", +"InnoDB: Please submit a detailed bug report to http://bugs.mysql.com\n\n", (ulong) page_no, (ulong) fil_page_get_type(page)); } diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index 99d3c297039..e2de13d0520 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -86,7 +86,7 @@ void dfield_set_data( /*============*/ dfield_t* field, /* in: field */ - void* data, /* in: data */ + const void* data, /* in: data */ ulint len); /* in: length or UNIV_SQL_NULL */ /************************************************************************** Writes an SQL null field full of zeros. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index 697a272ccd6..569bf898801 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -93,7 +93,7 @@ void dfield_set_data( /*============*/ dfield_t* field, /* in: field */ - void* data, /* in: data */ + const void* data, /* in: data */ ulint len) /* in: length or UNIV_SQL_NULL */ { ut_ad(field); diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 98636f6e1cb..fe04359d6f1 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -166,7 +166,7 @@ dict_table_rename_in_cache( /*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ - char* new_name, /* in: new name */ + const char* new_name, /* in: new name */ ibool rename_also_foreigns);/* in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ @@ -210,16 +210,19 @@ fields than mentioned in the constraint. */ ulint dict_create_foreign_constraints( /*============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: - FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2; the default - database id the database of parameter name */ - char* name); /* in: table full name in the normalized form - database_name/table_name */ + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: + FOREIGN KEY (a, b) REFERENCES + table2(c, d), table2 can be written + also with the database + name before it: test.table2; the + default database id the database of + parameter name */ + const char* name); /* in: table full name in the + normalized form + database_name/table_name */ /************************************************************************** Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */ @@ -246,9 +249,10 @@ directory dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************** Returns a table object and increments MySQL open handle count on the table. */ @@ -256,9 +260,10 @@ Returns a table object and increments MySQL open handle count on the table. dict_table_t* dict_table_get_and_increment_handle_count( /*======================================*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx); /* in: transaction handle or NULL */ /************************************************************************** Returns a table object, based on table id, and memoryfixes it. */ @@ -290,8 +295,8 @@ UNIV_INLINE dict_table_t* dict_table_check_if_in_cache_low( /*==============================*/ - /* out: table, NULL if not found */ - char* table_name); /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name); /* in: table name */ /************************************************************************** Gets a table; loads it to the dictionary cache if necessary. A low-level function. */ @@ -299,8 +304,8 @@ UNIV_INLINE dict_table_t* dict_table_get_low( /*===============*/ - /* out: table, NULL if not found */ - char* table_name); /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name); /* in: table name */ /************************************************************************** Returns an index object. */ UNIV_INLINE @@ -309,7 +314,7 @@ dict_table_get_index( /*=================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name); /* in: index name */ + const char* name); /* in: index name */ /************************************************************************** Returns an index object. */ @@ -318,7 +323,7 @@ dict_table_get_index_noninline( /*===========================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name); /* in: index name */ + const char* name); /* in: index name */ /************************************************************************** Prints a table data. */ @@ -340,7 +345,7 @@ Prints a table data when we know the table name. */ void dict_table_print_by_name( /*=====================*/ - char* name); + const char* name); #endif /* UNIV_DEBUG */ /************************************************************************** Outputs info on foreign keys of a table. */ diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 57ef4b896f5..0f7cc8973db 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -536,8 +536,8 @@ UNIV_INLINE dict_table_t* dict_table_check_if_in_cache_low( /*==============================*/ - /* out: table, NULL if not found */ - char* table_name) /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name) /* in: table name */ { dict_table_t* table; ulint table_fold; @@ -562,8 +562,8 @@ UNIV_INLINE dict_table_t* dict_table_get_low( /*===============*/ - /* out: table, NULL if not found */ - char* table_name) /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name) /* in: table name */ { dict_table_t* table; @@ -642,7 +642,7 @@ dict_table_get_index( /*=================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name) /* in: index name */ + const char* name) /* in: index name */ { dict_index_t* index = NULL; diff --git a/innobase/include/dict0load.h b/innobase/include/dict0load.h index f7168a0f45f..d4dccb33373 100644 --- a/innobase/include/dict0load.h +++ b/innobase/include/dict0load.h @@ -31,9 +31,10 @@ Finds the first table name in the given database. */ char* dict_get_first_table_name_in_db( /*============================*/ - /* out, own: table name, NULL if does not exist; - the caller must free the memory in the string! */ - char* name); /* in: database name which ends to '/' */ + /* out, own: table name, NULL if + does not exist; the caller must free + the memory in the string! */ + const char* name); /* in: database name which ends to '/' */ /************************************************************************ Loads a table definition and also all its index definitions, and also the cluster definition if the table is a member in a cluster. Also loads @@ -43,11 +44,13 @@ a foreign key references columns in this table. */ dict_table_t* dict_load_table( /*============*/ - /* out: table, NULL if does not exist; if the table is - stored in an .ibd file, but the file does not exist, - then we set the ibd_file_missing flag TRUE in the table - object we return */ - char* name); /* in: table name */ + /* out: table, NULL if does not exist; + if the table is stored in an .ibd file, + but the file does not exist, + then we set the ibd_file_missing flag TRUE + in the table object we return */ + const char* name); /* in: table name in the + databasename/tablename format */ /*************************************************************************** Loads a table object based on the table id. */ @@ -75,8 +78,8 @@ already in the dictionary cache. */ ulint dict_load_foreigns( /*===============*/ - /* out: DB_SUCCESS or error code */ - char* table_name); /* in: table name */ + /* out: DB_SUCCESS or error code */ + const char* table_name); /* in: table name */ /************************************************************************ Prints to the standard output information on all tables found in the data dictionary system table. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 674868c9fce..f141ea9da09 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -48,27 +48,28 @@ Creates a table memory object. */ dict_table_t* dict_mem_table_create( /*==================*/ - /* out, own: table object */ - char* name, /* in: table name */ - ulint space, /* in: space where the clustered index of - the table is placed; this parameter is - ignored if the table is made a member of - a cluster */ - ulint n_cols); /* in: number of columns */ + /* out, own: table object */ + const char* name, /* in: table name */ + ulint space, /* in: space where the clustered index + of the table is placed; this parameter + is ignored if the table is made + a member of a cluster */ + ulint n_cols); /* in: number of columns */ /************************************************************************** Creates a cluster memory object. */ dict_cluster_t* dict_mem_cluster_create( /*====================*/ - /* out, own: cluster object (where the type - dict_cluster_t == dict_table_t) */ - char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered indexes - of the member tables are placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len); /* in: length of the common key prefix in the - cluster */ + /* out, own: cluster object (where the + type dict_cluster_t == dict_table_t) */ + const char* name, /* in: cluster name */ + ulint space, /* in: space where the clustered + indexes of the member tables are + placed */ + ulint n_cols, /* in: number of columns */ + ulint mix_len); /* in: length of the common key prefix + in the cluster */ /************************************************************************** Declares a non-published table as a member in a cluster. */ @@ -76,7 +77,7 @@ void dict_mem_table_make_cluster_member( /*===============================*/ dict_table_t* table, /* in: non-published table */ - char* cluster_name); /* in: cluster name */ + const char* cluster_name); /* in: cluster name */ /************************************************************************** Adds a column definition to a table. */ @@ -84,7 +85,7 @@ void dict_mem_table_add_col( /*===================*/ dict_table_t* table, /* in: table */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint mtype, /* in: main datatype */ ulint prtype, /* in: precise type */ ulint len, /* in: length */ @@ -95,14 +96,15 @@ Creates an index memory object. */ dict_index_t* dict_mem_index_create( /*==================*/ - /* out, own: index object */ - char* table_name, /* in: table name */ - char* index_name, /* in: index name */ - ulint space, /* in: space where the index tree is placed, - ignored if the index is of the clustered - type */ - ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ - ulint n_fields); /* in: number of fields */ + /* out, own: index object */ + const char* table_name, /* in: table name */ + const char* index_name, /* in: index name */ + ulint space, /* in: space where the index tree is + placed, ignored if the index is of + the clustered type */ + ulint type, /* in: DICT_UNIQUE, + DICT_CLUSTERED, ... ORed */ + ulint n_fields); /* in: number of fields */ /************************************************************************** Adds a field definition to an index. NOTE: does not take a copy of the column name if the field is a column. The memory occupied @@ -112,7 +114,7 @@ void dict_mem_index_add_field( /*=====================*/ dict_index_t* index, /* in: index */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint order, /* in: order criterion; 0 means an ascending order */ ulint prefix_len); /* in: 0 or the column prefix length @@ -142,7 +144,7 @@ struct dict_col_struct{ clustered index */ ulint ord_part;/* count of how many times this column appears in ordering fields of an index */ - char* name; /* name */ + const char* name; /* name */ dtype_t type; /* data type */ dict_table_t* table; /* back pointer to table of this column */ ulint aux; /* this is used as an auxiliary variable @@ -154,7 +156,7 @@ struct dict_col_struct{ /* Data structure for a field in an index */ struct dict_field_struct{ dict_col_t* col; /* pointer to the table column */ - char* name; /* name of the column */ + const char* name; /* name of the column */ ulint order; /* flags for ordering this field: DICT_DESCEND, ... */ ulint prefix_len; /* 0 or the length of the column @@ -197,8 +199,8 @@ struct dict_index_struct{ dulint id; /* id of the index */ mem_heap_t* heap; /* memory heap */ ulint type; /* index type */ - char* name; /* index name */ - char* table_name; /* table name */ + const char* name; /* index name */ + const char* table_name; /* table name */ dict_table_t* table; /* back pointer to table */ ulint space; /* space where the index tree is placed */ ulint page_no;/* page number of the index tree root */ @@ -254,12 +256,12 @@ struct dict_foreign_struct{ or DICT_FOREIGN_ON_DELETE_SET_NULL */ char* foreign_table_name;/* foreign table name */ dict_table_t* foreign_table; /* table where the foreign key is */ - char** foreign_col_names;/* names of the columns in the + const char** foreign_col_names;/* names of the columns in the foreign key */ char* referenced_table_name;/* referenced table name */ dict_table_t* referenced_table;/* table where the referenced key is */ - char** referenced_col_names;/* names of the referenced + const char** referenced_col_names;/* names of the referenced columns in the referenced table */ ulint n_fields; /* number of indexes' first fields for which the the foreign key @@ -295,7 +297,7 @@ struct dict_table_struct{ dulint id; /* id of the table or cluster */ ulint type; /* DICT_TABLE_ORDINARY, ... */ mem_heap_t* heap; /* memory heap */ - char* name; /* table name */ + const char* name; /* table name */ ulint space; /* space where the clustered index of the table is placed */ ibool ibd_file_missing;/* TRUE if this is in a single-table @@ -363,7 +365,7 @@ struct dict_table_struct{ byte mix_id_buf[12]; /* mix id of a mixed table written in a compressed form */ - char* cluster_name; /* if the table is a member in a + const char* cluster_name; /* if the table is a member in a cluster, this is the name of the cluster */ /*----------------------*/ ibool does_not_fit_in_memory; diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index f7cdeb7f195..b750e9b38f2 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -132,11 +132,12 @@ Appends a new file to the chain of files of a space. File must be closed. */ void fil_node_create( /*============*/ - char* name, /* in: file name (file must be closed) */ - ulint size, /* in: file size in database blocks, rounded downwards - to an integer */ - ulint id, /* in: space id where to append */ - ibool is_raw);/* in: TRUE if a raw device or a raw disk partition */ + const char* name, /* in: file name (file must be closed) */ + ulint size, /* in: file size in database blocks, rounded + downwards to an integer */ + ulint id, /* in: space id where to append */ + ibool is_raw);/* in: TRUE if a raw device or + a raw disk partition */ /******************************************************************** Drops files from the start of a file space, so that its size is cut by the amount given. */ @@ -155,10 +156,10 @@ there is an error, prints an error message to the .err log. */ ibool fil_space_create( /*=============*/ - /* out: TRUE if success */ - char* name, /* in: space name */ - ulint id, /* in: space id */ - ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */ + /* out: TRUE if success */ + const char* name, /* in: space name */ + ulint id, /* in: space id */ + ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */ /*********************************************************************** Frees a space object from a the tablespace memory cache. Closes the files in the chain but does not delete them. */ @@ -327,14 +328,15 @@ tablespace memory cache. */ ibool fil_rename_tablespace( /*==================*/ - /* out: TRUE if success */ - char* old_name, /* in: old table name in the standard - databasename/tablename format of InnoDB, or - NULL if we do the rename based on the space - id only */ - ulint id, /* in: space id */ - char* new_name); /* in: new table name in the standard - databasename/tablename format of InnoDB */ + /* out: TRUE if success */ + const char* old_name, /* in: old table name in the standard + databasename/tablename format of + InnoDB, or NULL if we do the rename + based on the space id only */ + ulint id, /* in: space id */ + const char* new_name); /* in: new table name in the standard + databasename/tablename format + of InnoDB */ /*********************************************************************** Creates a new single-table tablespace to a database directory of MySQL. Database directories are under the 'datadir' of MySQL. The datadir is the @@ -344,14 +346,16 @@ path '.'. */ ulint fil_create_new_single_table_tablespace( /*===================================*/ - /* out: DB_SUCCESS or error code */ - ulint* space_id, /* in/out: space id; if this is != 0, then - this is an input parameter, otherwise - output */ - char* tablename, /* in: the table name in the usual - databasename/tablename format of InnoDB */ - ulint size); /* in: the initial size of the tablespace file - in pages, must be > 0 */ + /* out: DB_SUCCESS or error code */ + ulint* space_id, /* in/out: space id; if this is != 0, + then this is an input parameter, + otherwise output */ + const char* tablename, /* in: the table name in the usual + databasename/tablename format + of InnoDB */ + ulint size); /* in: the initial size of the + tablespace file in pages, + must be >= FIL_IBD_FILE_INITIAL_SIZE */ /************************************************************************ Tries to open a single-table tablespace and checks the space id is right in it. If does not succeed, prints an error message to the .err log. This @@ -362,10 +366,10 @@ protection of the dictionary mutex, so that two users cannot race here. */ ibool fil_open_single_table_tablespace( /*=============================*/ - /* out: TRUE if success */ - ulint id, /* in: space id */ - char* name); /* in: table name in the databasename/tablename - format */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + const char* name); /* in: table name in the + databasename/tablename format */ /************************************************************************ It is possible, though very improbable, that the lsn's in the tablespace to be imported have risen above the current system lsn, if a lengthy purge, ibuf @@ -379,12 +383,12 @@ lsn's just by looking at that flush lsn. */ ibool fil_reset_too_high_lsns( /*====================*/ - /* out: TRUE if success */ - char* name, /* in: table name in the databasename/tablename - format */ - dulint current_lsn); /* in: reset lsn's if the lsn stamped to - FIL_PAGE_FILE_FLUSH_LSN in the first page is - too high */ + /* out: TRUE if success */ + const char* name, /* in: table name in the + databasename/tablename format */ + dulint current_lsn); /* in: reset lsn's if the lsn stamped + to FIL_PAGE_FILE_FLUSH_LSN in the + first page is too high */ /************************************************************************ At the server startup, if we need crash recovery, scans the database directories under the MySQL datadir, looking for .ibd files. Those files are @@ -436,20 +440,22 @@ there may be many tablespaces which are not yet in the memory cache. */ ibool fil_space_for_table_exists_in_mem( /*==============================*/ - /* out: TRUE if a matching tablespace - exists in the memory cache */ - ulint id, /* in: space id */ - char* name, /* in: table name in the standard - 'databasename/tablename' format */ - ibool mark_space, /* in: in crash recovery, at database startup - we mark all spaces which have an associated - table in the InnoDB data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist); - /* in: print detailed error information to - the .err log if a matching tablespace is - not found from memory */ + /* out: TRUE if a matching tablespace + exists in the memory cache */ + ulint id, /* in: space id */ + const char* name, /* in: table name in the standard + 'databasename/tablename' format */ + ibool mark_space, /* in: in crash recovery, at database + startup we mark all spaces which have + an associated table in the InnoDB + data dictionary, so that + we can print a warning about orphaned + tablespaces */ + ibool print_error_if_does_not_exist); + /* in: print detailed error + information to the .err log if a + matching tablespace is not found from + memory */ /************************************************************************** Tries to extend a data file so that it would accommodate the number of pages given. The tablespace must be cached in the memory cache. If the space is big diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 3eccfcd3be5..930390241d3 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -177,13 +177,15 @@ and '..' items at the start of the directory listing. */ os_file_dir_t os_file_opendir( /*============*/ - /* out: directory stream, NULL if error */ - char* dirname, /* in: directory name; it must not contain - a trailing '\' or '/' */ - ibool error_is_fatal);/* in: TRUE if we should treat an error as a - fatal error; if we try to open symlinks then - we do not wish a fatal error if it happens - not to be a directory */ + /* out: directory stream, NULL if + error */ + const char* dirname, /* in: directory name; it must not + contain a trailing '\' or '/' */ + ibool error_is_fatal);/* in: TRUE if we should treat an + error as a fatal error; if we try to + open symlinks then we do not wish a + fatal error if it happens not to be + a directory */ /*************************************************************************** Closes a directory stream. */ @@ -201,7 +203,7 @@ os_file_readdir_next_file( /*======================*/ /* out: 0 if ok, -1 if error, 1 if at the end of the directory */ - char* dirname,/* in: directory name or path */ + const char* dirname,/* in: directory name or path */ os_file_dir_t dir, /* in: directory stream */ os_file_stat_t* info); /* in/out: buffer where the info is returned */ /********************************************************************* @@ -213,81 +215,89 @@ fail_if_exists arguments is true. */ ibool os_file_create_directory( /*=====================*/ - /* out: TRUE if call succeeds, FALSE on - error */ - char* pathname, /* in: directory name as null-terminated - string */ - ibool fail_if_exists);/* in: if TRUE, pre-existing directory is - treated as an error. */ + /* out: TRUE if call succeeds, + FALSE on error */ + const char* pathname, /* in: directory name as + null-terminated string */ + ibool fail_if_exists);/* in: if TRUE, pre-existing directory + is treated as an error. */ /******************************************************************** A simple function to open or create a file. */ os_file_t os_file_create_simple( /*==================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), or - OS_FILE_CREATE_PATH if new file (if exists, error) and - subdirectories along its path are created (if needed)*/ - ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file is + opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), or + OS_FILE_CREATE_PATH if new file + (if exists, error) and subdirectories along + its path are created (if needed)*/ + ulint access_type,/* in: OS_FILE_READ_ONLY or + OS_FILE_READ_WRITE */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /******************************************************************** A simple function to open or create a file. */ os_file_t os_file_create_simple_no_error_handling( /*====================================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error) */ - ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is used by - a backup program reading the file */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error) */ + ulint access_type,/* in: OS_FILE_READ_ONLY, + OS_FILE_READ_WRITE, or + OS_FILE_READ_ALLOW_DELETE; the last option is + used by a backup program reading the file */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /******************************************************************** Opens an existing file or creates a new. */ os_file_t os_file_create( /*===========*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), OS_FILE_OVERWRITE - if a new file is created or an old overwritten; - OS_FILE_OPEN_RAW, if a raw device or disk partition - should be opened */ - ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file; - NOTE that it also depends on type, os_aio_.. and srv_.. - variables whether we really use async i/o or - unbuffered i/o: look in the function source code for - the exact rules */ - ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), + OS_FILE_OVERWRITE if a new file is created + or an old overwritten; + OS_FILE_OPEN_RAW, if a raw device or disk + partition should be opened */ + ulint purpose,/* in: OS_FILE_AIO, if asynchronous, + non-buffered i/o is desired, + OS_FILE_NORMAL, if any normal file; + NOTE that it also depends on type, os_aio_.. + and srv_.. variables whether we really use + async i/o or unbuffered i/o: look in the + function source code for the exact rules */ + ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /*************************************************************************** Deletes a file. The file has to be closed before calling this. */ ibool os_file_delete( /*===========*/ - /* out: TRUE if success */ - char* name); /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name); /* in: file path as a null-terminated string */ /*************************************************************************** Deletes a file if it exists. The file has to be closed before calling this. */ @@ -295,8 +305,8 @@ Deletes a file if it exists. The file has to be closed before calling this. */ ibool os_file_delete_if_exists( /*=====================*/ - /* out: TRUE if success */ - char* name); /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name); /* in: file path as a null-terminated string */ /*************************************************************************** Renames a file (can also move it to another directory). It is safest that the file is closed before calling this function. */ @@ -304,10 +314,10 @@ file is closed before calling this function. */ ibool os_file_rename( /*===========*/ - /* out: TRUE if success */ - char* oldpath, /* in: old file path as a null-terminated - string */ - char* newpath); /* in: new file path */ + /* out: TRUE if success */ + const char* oldpath, /* in: old file path as a + null-terminated string */ + const char* newpath); /* in: new file path */ /*************************************************************************** Closes a file handle. In case of error, error number can be retrieved with os_file_get_last_error. */ @@ -351,7 +361,7 @@ ibool os_file_set_size( /*=============*/ /* out: TRUE if success */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ ulint size, /* in: least significant 32 bits of file @@ -426,10 +436,10 @@ os_file_write( /*==========*/ /* out: TRUE if request was successful, FALSE if fail */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from which to write */ + const void* buf, /* in: buffer from which to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high,/* in: most significant 32 bits of @@ -442,8 +452,8 @@ ibool os_file_status( /*===========*/ /* out: TRUE if call succeeded */ - char * path, /* in: pathname of the file */ - ibool * exists, /* out: TRUE if file exists */ + const char* path, /* in: pathname of the file */ + ibool* exists, /* out: TRUE if file exists */ os_file_type_t* type); /* out: type of the file (if it exists) */ /******************************************************************** The function os_file_dirname returns a directory component of a @@ -478,7 +488,7 @@ os_file_dirname( /*============*/ /* out, own: directory component of the pathname */ - char* path); /* in: pathname */ + const char* path); /* in: pathname */ /******************************************************************** Creates all missing subdirectories along the given path. */ @@ -487,7 +497,7 @@ os_file_create_subdirs_if_needed( /*=============================*/ /* out: TRUE if call succeeded FALSE otherwise */ - char* path); /* in: path name */ + const char* path); /* in: path name */ /**************************************************************************** Initializes the asynchronous io system. Creates separate aio array for non-ibuf read and write, a third aio array for the ibuf i/o, with just one @@ -527,7 +537,7 @@ os_aio( because i/os are not actually handled until all have been posted: use with great caution! */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read or from which diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index e1cf263216e..d27b1676f1b 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -87,9 +87,9 @@ explicitly by calling sync_os_reset_event. */ os_event_t os_event_create( /*============*/ - /* out: the event handle */ - char* name); /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name); /* in: the name of the event, if NULL + the event is created without a name */ #ifdef __WIN__ /************************************************************* Creates an auto-reset event semaphore, i.e., an event which is automatically @@ -98,9 +98,9 @@ reset when a single thread is released. Works only in Windows. */ os_event_t os_event_create_auto( /*=================*/ - /* out: the event handle */ - char* name); /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name); /* in: the name of the event, if NULL + the event is created without a name */ #endif /************************************************************** Sets an event semaphore to the signaled state: lets waiting threads @@ -171,9 +171,9 @@ mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */ os_mutex_t os_mutex_create( /*============*/ - /* out: the mutex handle */ - char* name); /* in: the name of the mutex, if NULL - the mutex is created without a name */ + /* out: the mutex handle */ + const char* name); /* in: the name of the mutex, if NULL + the mutex is created without a name */ /************************************************************** Acquires ownership of a mutex semaphore. */ diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index c260557c424..28985e2f9d0 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -74,8 +74,8 @@ Parses an SQL string returning the query graph. */ que_t* pars_sql( /*=====*/ - /* out, own: the query graph */ - char* str); /* in: SQL string */ + /* out, own: the query graph */ + const char* str); /* in: SQL string */ /***************************************************************** Retrieves characters to the lexical analyzer. */ diff --git a/innobase/include/pars0sym.h b/innobase/include/pars0sym.h index 3060fd06c8f..a40523861dd 100644 --- a/innobase/include/pars0sym.h +++ b/innobase/include/pars0sym.h @@ -122,7 +122,7 @@ struct sym_node_struct{ SYM_IMPLICIT_VAR, SYM_LIT, SYM_TABLE, SYM_CURSOR, ... */ - char* name; /* name of an id */ + const char* name; /* name of an id */ ulint name_len; /* id name length */ dict_table_t* table; /* table definition if a table id or a @@ -150,7 +150,7 @@ struct sym_tab_struct{ que_t* query_graph; /* query graph generated by the parser */ - char* sql_string; + const char* sql_string; /* SQL string to parse */ int string_len; /* SQL string length */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 0b9f34dda1e..af6d8969cfc 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -316,15 +316,16 @@ fields than mentioned in the constraint. */ int row_table_add_foreign_constraints( /*==============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2 */ - char* name); /* in: table full name in the normalized form - database_name/table_name */ + table2 can be written also with the + database name before it: test.table2 */ + const char* name); /* in: table full name in the + normalized form + database_name/table_name */ /************************************************************************* The master thread in srv0srv.c calls this regularly to drop tables which we must drop in background after queries to them have ended. Such lazy @@ -351,10 +352,10 @@ output by the master thread. */ int row_drop_table_for_mysql( /*=====================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx, /* in: transaction handle */ - ibool drop_db);/* in: TRUE=dropping whole database */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db);/* in: TRUE=dropping whole database */ /************************************************************************* Discards the tablespace of a table which stored in an .ibd file. Discarding @@ -382,9 +383,9 @@ discard ongoing operations. */ int row_discard_tablespace_for_mysql( /*=============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /********************************************************************* Imports a tablespace. The space id in the .ibd file must match the space id of the table in the data dictionary. */ @@ -392,28 +393,28 @@ of the table in the data dictionary. */ int row_import_tablespace_for_mysql( /*============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Drops a database for MySQL. */ int row_drop_database_for_mysql( /*========================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: database name which ends to '/' */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: database name which ends to '/' */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Renames a table for MySQL. */ int row_rename_table_for_mysql( /*=======================*/ - /* out: error code or DB_SUCCESS */ - char* old_name, /* in: old table name */ - char* new_name, /* in: new table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* old_name, /* in: old table name */ + const char* new_name, /* in: new table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Checks a table for corruption. */ diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h index a35d588ad08..0be224eb255 100644 --- a/innobase/include/row0sel.h +++ b/innobase/include/row0sel.h @@ -144,11 +144,11 @@ consistent read result, or store it to the query cache. */ ibool row_search_check_if_query_cache_permitted( /*======================================*/ - /* out: TRUE if storing or retrieving from - the query cache is permitted */ - trx_t* trx, /* in: transaction object */ - char* norm_name); /* in: concatenation of database name, '/' - char, table name */ + /* out: TRUE if storing or retrieving + from the query cache is permitted */ + trx_t* trx, /* in: transaction object */ + const char* norm_name); /* in: concatenation of database name, + '/' char, table name */ /* A structure for caching column values for prefetched rows */ diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h index 0d7126c9c57..6004551f456 100644 --- a/innobase/include/trx0roll.h +++ b/innobase/include/trx0roll.h @@ -193,7 +193,7 @@ trx_rollback_to_savepoint_for_mysql( DB_NO_SAVEPOINT, otherwise DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong* mysql_binlog_cache_pos);/* out: the MySQL binlog cache position corresponding to this savepoint; MySQL needs this @@ -211,7 +211,7 @@ trx_savepoint_for_mysql( /*====================*/ /* out: always DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong binlog_cache_pos); /* in: MySQL binlog cache position corresponding to this connection at the time of the diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index 9987955ec76..7d20455ffdf 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -258,7 +258,7 @@ replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - char* file_name,/* in: MySQL log file name */ + const char* file_name,/* in: MySQL log file name */ ib_longlong offset, /* in: position in that log file */ ulint field, /* in: offset of the MySQL log info field in the trx sys header */ diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 71269cb1e4e..a8c1df534da 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -275,13 +275,15 @@ trx_commit_step( que_thr_t* thr); /* in: query thread */ /************************************************************************** Prints info about a transaction to the standard output. The caller must -own the kernel mutex. */ +own the kernel mutex and must have called +innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or +InnoDB cannot meanwhile change the info printed here. */ void trx_print( /*======*/ FILE* f, /* in: output stream */ - trx_t* trx); /* in: transaction */ + trx_t* trx); /* in: transaction */ /* Signal to a transaction */ @@ -313,7 +315,7 @@ struct trx_struct{ ulint magic_n; /* All the next fields are protected by the kernel mutex, except the undo logs which are protected by undo_mutex */ - char* op_info; /* English text describing the + const char* op_info; /* English text describing the current operation, or an empty string */ ulint type; /* TRX_USER, TRX_PURGE */ @@ -356,7 +358,7 @@ struct trx_struct{ char** mysql_query_str;/* pointer to the field in mysqld_thd which contains the pointer to the current SQL query string */ - char* mysql_log_file_name; + const char* mysql_log_file_name; /* if MySQL binlog is used, this field contains a pointer to the latest file name; this is NULL if binlog is not @@ -364,7 +366,7 @@ struct trx_struct{ ib_longlong mysql_log_offset;/* if MySQL binlog is used, this field contains the end offset of the binlog entry */ - char* mysql_master_log_file_name; + const char* mysql_master_log_file_name; /* if the database server is a MySQL replication slave, we have here the master binlog name up to which diff --git a/innobase/include/ut0rnd.h b/innobase/include/ut0rnd.h index c8ef0dd4001..aeec5d2f6eb 100644 --- a/innobase/include/ut0rnd.h +++ b/innobase/include/ut0rnd.h @@ -92,17 +92,17 @@ UNIV_INLINE ulint ut_fold_string( /*===========*/ - /* out: folded value */ - char* str); /* in: null-terminated string */ + /* out: folded value */ + const char* str); /* in: null-terminated string */ /***************************************************************** Folds a binary string. */ UNIV_INLINE ulint ut_fold_binary( /*===========*/ - /* out: folded value */ - byte* str, /* in: string of bytes */ - ulint len); /* in: length */ + /* out: folded value */ + const byte* str, /* in: string of bytes */ + ulint len); /* in: length */ /*************************************************************** Looks for a prime number slightly greater than the given argument. The prime is chosen so that it is not near any power of 2. */ diff --git a/innobase/include/ut0rnd.ic b/innobase/include/ut0rnd.ic index 5493c37404a..06d7012f60b 100644 --- a/innobase/include/ut0rnd.ic +++ b/innobase/include/ut0rnd.ic @@ -173,8 +173,8 @@ UNIV_INLINE ulint ut_fold_string( /*===========*/ - /* out: folded value */ - char* str) /* in: null-terminated string */ + /* out: folded value */ + const char* str) /* in: null-terminated string */ { #ifdef UNIV_DEBUG ulint i = 0; @@ -203,9 +203,9 @@ UNIV_INLINE ulint ut_fold_binary( /*===========*/ - /* out: folded value */ - byte* str, /* in: string of bytes */ - ulint len) /* in: length */ + /* out: folded value */ + const byte* str, /* in: string of bytes */ + ulint len) /* in: length */ { ulint i; ulint fold = 0; diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 6c173f5cba9..f4a682c57ec 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -17,53 +17,6 @@ Created 1/20/1994 Heikki Tuuri typedef time_t ib_time_t; - -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_printf( -/*======*/ - /* out: the number of characters written, or - negative in case of an error */ - const char* format, /* in: format of prints */ - ...); /* in: arguments to be printed */ -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_sprintf( -/*=======*/ - /* out: the number of characters written, or - negative in case of an error */ - char* buf, /* in: buffer where to print */ - const char* format, /* in: format of prints */ - ...); /* in: arguments to be printed */ -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_fprintf( -/*=======*/ - /* out: the number of characters written, or - negative in case of an error */ - FILE* stream, /* in: stream where to print */ - const char* format, /* in: format of prints */ - ...) /* in: arguments to be printed */ - __attribute__((__format__ (__printf__, 2, 3))); - /************************************************************ Gets the high 32 bits in a ulint. That is makes a shift >> 32, but since there seem to be compiler bugs in both gcc and Visual C++, diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 056d502e858..223d9af78d1 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -17,6 +17,32 @@ Created 5/7/1996 Heikki Tuuri #include "dict0mem.h" #include "trx0sys.h" + +/* 2 function prototypes copied from ha_innodb.cc: */ + +/***************************************************************** +If you want to print a thd that is not associated with the current thread, +you must call this function before reserving the InnoDB kernel_mutex, to +protect MySQL from setting thd->query NULL. If you print a thd of the current +thread, we know that MySQL cannot modify thd->query, and it is not necessary +to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release +the kernel_mutex. +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ + +void +innobase_mysql_prepare_print_arbitrary_thd(void); +/*============================================*/ + +/***************************************************************** +Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd(). +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ + +void +innobase_mysql_end_print_arbitrary_thd(void); +/*========================================*/ + /* Restricts the length of search we will do in the waits-for graph of transactions */ #define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000 @@ -1629,7 +1655,8 @@ lock_rec_enqueue_waiting( " InnoDB: Error: a record lock wait happens in a dictionary operation!\n" "InnoDB: Table name ", stderr); ut_print_name(stderr, index->table_name); - fputs(". Send a bug report to mysql@lists.mysql.com\n", + fputs(".\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } @@ -3269,7 +3296,8 @@ lock_table_enqueue_waiting( " InnoDB: Error: a table lock wait happens in a dictionary operation!\n" "InnoDB: Table name ", stderr); ut_print_name(stderr, table->name); - fputs(". Send a bug report to mysql@lists.mysql.com\n", + fputs(".\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } @@ -3975,6 +4003,11 @@ lock_print_info( ulint i; mtr_t mtr; + /* We must protect the MySQL thd->query field with a MySQL mutex, and + because the MySQL mutex must be reserved before the kernel_mutex of + InnoDB, we call innobase_mysql_prepare_print_arbitrary_thd() here. */ + + innobase_mysql_prepare_print_arbitrary_thd(); lock_mutex_enter_kernel(); if (lock_deadlock_found) { @@ -4038,6 +4071,7 @@ loop: if (trx == NULL) { lock_mutex_exit_kernel(); + innobase_mysql_end_print_arbitrary_thd(); ut_ad(lock_validate()); @@ -4102,6 +4136,7 @@ loop: if (load_page_first) { lock_mutex_exit_kernel(); + innobase_mysql_end_print_arbitrary_thd(); mtr_start(&mtr); @@ -4111,6 +4146,7 @@ loop: load_page_first = FALSE; + innobase_mysql_prepare_print_arbitrary_thd(); lock_mutex_enter_kernel(); goto loop; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 79185c30f79..5f5060c7464 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -70,7 +70,7 @@ struct os_aio_slot_struct{ bytes */ ulint offset_high; /* 32 high bits of file offset */ os_file_t file; /* file where to read or write */ - char* name; /* file name or path */ + const char* name; /* file name or path */ ibool io_already_done;/* used only in simulated aio: TRUE if the physical i/o already made and only the slot message @@ -387,15 +387,17 @@ os_file_lock( /*=========*/ /* out: 0 on success */ int fd, /* in: file descriptor */ - const char* name) /* in: file name */ + const char* name, /* in: file name */ + uint lock_type) /* in: lock_type */ { struct flock lk; - lk.l_type = F_WRLCK; + lk.l_type = lock_type; lk.l_whence = SEEK_SET; lk.l_start = lk.l_len = 0; if (fcntl(fd, F_SETLK, &lk) == -1) { fprintf(stderr, - "InnoDB: Unable to lock %s", name); + "InnoDB: Unable to lock %s with lock %d, error: %d", + name, lock_type, errno); perror (": fcntl"); close(fd); return(-1); @@ -413,7 +415,7 @@ os_file_handle_error_no_exit( /* out: TRUE if we should retry the operation */ os_file_t file, /* in: file pointer */ - char* name, /* in: name of a file or NULL */ + const char* name, /* in: name of a file or NULL */ const char* operation)/* in: operation */ { ulint err; @@ -491,13 +493,15 @@ and '..' items at the start of the directory listing. */ os_file_dir_t os_file_opendir( /*============*/ - /* out: directory stream, NULL if error */ - char* dirname, /* in: directory name; it must not contain - a trailing '\' or '/' */ - ibool error_is_fatal) /* in: TRUE if we should treat an error as a - fatal error; if we try to open symlinks then - we do not wish a fatal error if it happens - not to be a directory */ + /* out: directory stream, NULL if + error */ + const char* dirname, /* in: directory name; it must not + contain a trailing '\' or '/' */ + ibool error_is_fatal) /* in: TRUE if we should treat an + error as a fatal error; if we try to + open symlinks then we do not wish a + fatal error if it happens not to be + a directory */ { os_file_dir_t dir; #ifdef __WIN__ @@ -583,7 +587,7 @@ os_file_readdir_next_file( /*======================*/ /* out: 0 if ok, -1 if error, 1 if at the end of the directory */ - char* dirname,/* in: directory name or path */ + const char* dirname,/* in: directory name or path */ os_file_dir_t dir, /* in: directory stream */ os_file_stat_t* info) /* in/out: buffer where the info is returned */ { @@ -702,12 +706,12 @@ fail_if_exists arguments is true. */ ibool os_file_create_directory( /*=====================*/ - /* out: TRUE if call succeeds, FALSE on - error */ - char* pathname, /* in: directory name as null-terminated - string */ - ibool fail_if_exists) /* in: if TRUE, pre-existing directory is - treated as an error. */ + /* out: TRUE if call succeeds, + FALSE on error */ + const char* pathname, /* in: directory name as + null-terminated string */ + ibool fail_if_exists) /* in: if TRUE, pre-existing directory + is treated as an error. */ { #ifdef __WIN__ BOOL rcode; @@ -744,18 +748,21 @@ A simple function to open or create a file. */ os_file_t os_file_create_simple( /*==================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), or - OS_FILE_CREATE_PATH if new file (if exists, error) and - subdirectories along its path are created (if needed)*/ - ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file is + opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), or + OS_FILE_CREATE_PATH if new file + (if exists, error) and subdirectories along + its path are created (if needed)*/ + ulint access_type,/* in: OS_FILE_READ_ONLY or + OS_FILE_READ_WRITE */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -862,7 +869,7 @@ try_again: goto try_again; } #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name)) { + } else if (os_file_lock(file, name, F_WRLCK)) { *success = FALSE; file = -1; #endif @@ -880,18 +887,20 @@ A simple function to open or create a file. */ os_file_t os_file_create_simple_no_error_handling( /*====================================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error) */ - ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is used by - a backup program reading the file */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error) */ + ulint access_type,/* in: OS_FILE_READ_ONLY, + OS_FILE_READ_WRITE, or + OS_FILE_READ_ALLOW_DELETE; the last option is + used by a backup program reading the file */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -971,7 +980,7 @@ os_file_create_simple_no_error_handling( if (file == -1) { *success = FALSE; #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name)) { + } else if (os_file_lock(file, name, F_WRLCK)) { *success = FALSE; file = -1; #endif @@ -989,25 +998,28 @@ Opens an existing file or creates a new. */ os_file_t os_file_create( /*===========*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode, /* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), OS_FILE_OVERWRITE - if a new is created or an old overwritten, - OS_FILE_OPEN_RAW, if a raw device or disk partition - should be opened */ - ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file; - NOTE that it also depends on type, os_aio_.. and srv_.. - variables whether we really use async i/o or - unbuffered i/o: look in the function source code for - the exact rules */ - ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), + OS_FILE_OVERWRITE if a new file is created + or an old overwritten; + OS_FILE_OPEN_RAW, if a raw device or disk + partition should be opened */ + ulint purpose,/* in: OS_FILE_AIO, if asynchronous, + non-buffered i/o is desired, + OS_FILE_NORMAL, if any normal file; + NOTE that it also depends on type, os_aio_.. + and srv_.. variables whether we really use + async i/o or unbuffered i/o: look in the + function source code for the exact rules */ + ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -1182,7 +1194,7 @@ try_again: goto try_again; } #ifdef USE_FILE_LOCK - } else if (os_file_lock(file, name)) { + } else if (os_file_lock(file, name, F_WRLCK)) { *success = FALSE; file = -1; #endif @@ -1200,8 +1212,8 @@ Deletes a file if it exists. The file has to be closed before calling this. */ ibool os_file_delete_if_exists( /*=====================*/ - /* out: TRUE if success */ - char* name) /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name) /* in: file path as a null-terminated string */ { #ifdef __WIN__ BOOL ret; @@ -1261,8 +1273,8 @@ Deletes a file. The file has to be closed before calling this. */ ibool os_file_delete( /*===========*/ - /* out: TRUE if success */ - char* name) /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name) /* in: file path as a null-terminated string */ { #ifdef __WIN__ BOOL ret; @@ -1325,9 +1337,9 @@ ibool os_file_rename( /*===========*/ /* out: TRUE if success */ - char* oldpath, /* in: old file path as a null-terminated + const char* oldpath,/* in: old file path as a null-terminated string */ - char* newpath) /* in: new file path */ + const char* newpath)/* in: new file path */ { #ifdef __WIN__ BOOL ret; @@ -1338,7 +1350,7 @@ os_file_rename( return(TRUE); } - os_file_handle_error(NULL, oldpath, "delete"); + os_file_handle_error(NULL, oldpath, "rename"); return(FALSE); #else @@ -1383,6 +1395,9 @@ os_file_close( #else int ret; +#ifdef USE_FILE_LOCK + (void) os_file_lock(file, "unknown", F_UNLCK); +#endif ret = close(file); if (ret == -1) { @@ -1419,6 +1434,9 @@ os_file_close_no_error_handling( #else int ret; +#ifdef USE_FILE_LOCK + (void) os_file_lock(file, "unknown", F_UNLCK); +#endif ret = close(file); if (ret == -1) { @@ -1508,7 +1526,7 @@ ibool os_file_set_size( /*=============*/ /* out: TRUE if success */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ ulint size, /* in: least significant 32 bits of file @@ -1769,7 +1787,7 @@ os_file_pwrite( /*===========*/ /* out: number of bytes written, -1 if error */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from where to write */ + const void* buf, /* in: buffer from where to write */ ulint n, /* in: number of bytes to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ @@ -2049,10 +2067,10 @@ os_file_write( /*==========*/ /* out: TRUE if request was successful, FALSE if fail */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from which to write */ + const void* buf, /* in: buffer from which to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high, /* in: most significant 32 bits of @@ -2206,7 +2224,7 @@ ibool os_file_status( /*===========*/ /* out: TRUE if call succeeded */ - char* path, /* in: pathname of the file */ + const char* path, /* in: pathname of the file */ ibool* exists, /* out: TRUE if file exists */ os_file_type_t* type) /* out: type of the file (if it exists) */ { @@ -2311,7 +2329,7 @@ os_file_dirname( /*============*/ /* out, own: directory component of the pathname */ - char* path) /* in: pathname */ + const char* path) /* in: pathname */ { char* dir; int i, length, last_slash; @@ -2348,7 +2366,7 @@ os_file_create_subdirs_if_needed( /*=============================*/ /* out: TRUE if call succeeded FALSE otherwise */ - char* path) /* in: path name */ + const char* path) /* in: path name */ { char* subdir; static char rootdir[2] = { OS_FILE_PATH_SEPARATOR, 0 }; @@ -2745,7 +2763,7 @@ os_aio_array_reserve_slot( void* message2,/* in: message to be passed along with the aio operation */ os_file_t file, /* in: file handle */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ void* buf, /* in: buffer where to read or from which to write */ @@ -2992,7 +3010,7 @@ os_aio( because i/os are not actually handled until all have been posted: use with great caution! */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read or from which @@ -3535,6 +3553,7 @@ consecutive_loop: if (n_consecutive == 1) { /* We can use the buffer of the i/o request */ combined_buf = slot->buf; + combined_buf2 = NULL; } else { combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE); @@ -3630,7 +3649,7 @@ consecutive_loop: } } - if (n_consecutive > 1) { + if (combined_buf2) { ut_free(combined_buf2); } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index 7cbaf1f5123..c48c44a4c70 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -109,9 +109,9 @@ must be reset explicitly by calling sync_os_reset_event. */ os_event_t os_event_create( /*============*/ - /* out: the event handle */ - char* name) /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name) /* in: the name of the event, if NULL + the event is created without a name */ { #ifdef __WIN__ os_event_t event; @@ -166,9 +166,9 @@ reset when a single thread is released. Works only in Windows. */ os_event_t os_event_create_auto( /*=================*/ - /* out: the event handle */ - char* name) /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name) /* in: the name of the event, if NULL + the event is created without a name */ { os_event_t event; @@ -430,9 +430,9 @@ mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */ os_mutex_t os_mutex_create( /*============*/ - /* out: the mutex handle */ - char* name) /* in: the name of the mutex, if NULL - the mutex is created without a name */ + /* out: the mutex handle */ + const char* name) /* in: the name of the mutex, if NULL + the mutex is created without a name */ { #ifdef __WIN__ HANDLE mutex; diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 7e835d9ada1..12451b4d94d 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1729,8 +1729,8 @@ Parses an SQL string returning the query graph. */ que_t* pars_sql( /*=====*/ - /* out, own: the query graph */ - char* str) /* in: SQL string */ + /* out, own: the query graph */ + const char* str) /* in: SQL string */ { sym_node_t* sym_node; mem_heap_t* heap; diff --git a/innobase/pars/pars0sym.c b/innobase/pars/pars0sym.c index 1a0608ed142..194e6677183 100644 --- a/innobase/pars/pars0sym.c +++ b/innobase/pars/pars0sym.c @@ -217,13 +217,10 @@ sym_tab_add_id( node->common.type = QUE_NODE_SYMBOL; - node->name = mem_heap_alloc(sym_tab->heap, len + 1); node->resolved = FALSE; node->indirection = NULL; - ut_memcpy(node->name, name, len); - node->name[len] = '\0'; - + node->name = mem_heap_strdupl(sym_tab->heap, name, len + 1); node->name_len = len; UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node); diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index a3f883b49c6..062f21369a7 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -803,8 +803,7 @@ row_ins_foreign_check_on_constraint( "InnoDB: clustered record ", stderr); rec_print(stderr, clust_rec); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); err = DB_SUCCESS; diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 5432add37f7..61be3a7248e 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -714,7 +714,7 @@ run_again: trx_start_if_not_started(trx); - err = lock_table(0, prebuilt->table, prebuilt->select_lock_type, thr); + err = lock_table(0, prebuilt->table, LOCK_AUTO_INC, thr); trx->error_state = err; @@ -1686,15 +1686,16 @@ constraints which reference this table are ok. */ int row_table_add_foreign_constraints( /*==============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2 */ - char* name) /* in: table full name in the normalized form - database_name/table_name */ + table2 can be written also with the + database name before it: test.table2 */ + const char* name) /* in: table full name in the + normalized form + database_name/table_name */ { ulint err; @@ -1940,9 +1941,9 @@ discard ongoing operations. */ int row_discard_tablespace_for_mysql( /*=============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx) /* in: transaction handle */ { dulint new_id; dict_table_t* table; @@ -2071,9 +2072,9 @@ of the table in the data dictionary. */ int row_import_tablespace_for_mysql( /*============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; ibool success; @@ -2177,10 +2178,10 @@ the corresponding monitor output by the master thread. */ int row_drop_table_for_mysql( /*=====================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx, /* in: transaction handle */ - ibool drop_db)/* in: TRUE=dropping whole database */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db)/* in: TRUE=dropping whole database */ { dict_foreign_t* foreign; dict_table_t* table; @@ -2519,17 +2520,18 @@ Drops a database for MySQL. */ int row_drop_database_for_mysql( /*========================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: database name which ends to '/' */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: database name which ends to '/' */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; char* table_name; int err = DB_SUCCESS; + ulint namelen = strlen(name); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(name != NULL); - ut_a(name[strlen(name) - 1] == '/'); + ut_a(name[namelen - 1] == '/'); trx->op_info = (char *) "dropping database"; @@ -2538,7 +2540,7 @@ loop: row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { - ut_a(strcmp(table_name, name) == 0); + ut_a(memcmp(table_name, name, namelen) == 0); table = dict_table_get_low(table_name); @@ -2610,10 +2612,10 @@ Renames a table for MySQL. */ int row_rename_table_for_mysql( /*=======================*/ - /* out: error code or DB_SUCCESS */ - char* old_name, /* in: old table name */ - char* new_name, /* in: new table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* old_name, /* in: old table name */ + const char* new_name, /* in: new table name */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; que_thr_t* thr; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 4c43f75125c..ff9b697c02f 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2410,8 +2410,7 @@ row_sel_get_clust_rec_for_mysql( trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } clust_rec = NULL; @@ -3586,11 +3585,11 @@ consistent read result, or store it to the query cache. */ ibool row_search_check_if_query_cache_permitted( /*======================================*/ - /* out: TRUE if storing or retrieving from - the query cache is permitted */ - trx_t* trx, /* in: transaction object */ - char* norm_name) /* in: concatenation of database name, '/' - char, table name */ + /* out: TRUE if storing or retrieving + from the query cache is permitted */ + trx_t* trx, /* in: transaction object */ + const char* norm_name) /* in: concatenation of database name, + '/' char, table name */ { dict_table_t* table; ibool ret = FALSE; diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 3c181ed5493..d47227166f3 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -441,8 +441,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( putc('\n', stderr); trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } else { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 82eb112fc77..724e7bf91e7 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -1236,8 +1236,7 @@ row_upd_sec_index_entry( trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } else { /* Delete mark the old index record; it can already be delete marked if we return after a lock wait in diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 16f9f3d093d..382f723a05c 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -823,17 +823,16 @@ trx_undo_update_rec_get_update( if (field_no >= dict_index_get_n_fields(index)) { fprintf(stderr, - "InnoDB: Error: trying to access" - " update undo rec field %lu in ", (ulong) field_no); +"InnoDB: Error: trying to access update undo rec field %lu in ", (ulong) field_no); dict_index_name_print(stderr, index); fprintf(stderr, "\n" - "InnoDB: but index has only %lu fields\n" - "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n" - "InnoDB: Run also CHECK TABLE ", +"InnoDB: but index has only %lu fields\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" +"InnoDB: Run also CHECK TABLE ", (ulong) dict_index_get_n_fields(index)); ut_print_name(stderr, index->table_name); fprintf(stderr, "\n" - "InnoDB: n_fields = %lu, i = %lu, ptr %p\n", +"InnoDB: n_fields = %lu, i = %lu, ptr %p\n", (ulong) n_fields, (ulong) i, ptr); return(NULL); } @@ -1271,8 +1270,7 @@ trx_undo_prev_version_build( " update undo rec for non-clustered ", stderr); dict_index_name_print(stderr, index); fputs("\n" - "InnoDB: Send a detailed bug report to" - " mysql@lists.mysql.com\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: index record ", stderr); rec_print(stderr, index_rec); fputs("\n" @@ -1320,11 +1318,9 @@ trx_undo_prev_version_build( " update undo rec for table ", stderr); ut_print_name(stderr, index->table_name); fputs("\n" - "InnoDB: but the table id in the" - " undo record is wrong\n" - "InnoDB: Send a detailed bug report to " - "mysql@lists.mysql.com\n" - "InnoDB: Run also CHECK TABLE ", stderr); +"InnoDB: but the table id in the undo record is wrong\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" +"InnoDB: Run also CHECK TABLE ", stderr); ut_print_name(stderr, index->table_name); putc('\n', stderr); } diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 5c01a5371aa..e2e4f24b82e 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -200,7 +200,7 @@ trx_rollback_to_savepoint_for_mysql( DB_NO_SAVEPOINT, otherwise DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong* mysql_binlog_cache_pos) /* out: the MySQL binlog cache position corresponding to this savepoint; MySQL needs this @@ -265,7 +265,7 @@ trx_savepoint_for_mysql( /*====================*/ /* out: always DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong binlog_cache_pos) /* in: MySQL binlog cache position corresponding to this connection at the time of the diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index ef068d8d523..87abcbefa52 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -569,7 +569,7 @@ replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - char* file_name,/* in: MySQL log file name */ + const char* file_name,/* in: MySQL log file name */ ib_longlong offset, /* in: position in that log file */ ulint field, /* in: offset of the MySQL log info field in the trx sys header */ diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index fc0a67278d2..8128c8de13e 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1564,7 +1564,9 @@ trx_mark_sql_stat_end( /************************************************************************** Prints info about a transaction to the standard output. The caller must -own the kernel mutex. */ +own the kernel mutex and must have called +innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or +InnoDB cannot meanwhile change the info printed here. */ void trx_print( diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c index 3697e31050f..65703ec1c86 100644 --- a/innobase/ut/ut0dbg.c +++ b/innobase/ut/ut0dbg.c @@ -23,7 +23,7 @@ const char* ut_dbg_msg_assert_fail = "InnoDB: Assertion failure in thread %lu in file %s line %lu\n"; const char* ut_dbg_msg_trap = "InnoDB: We intentionally generate a memory trap.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com.\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com.\n" "InnoDB: If you get repeated assertion failures or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. See section 6.1 of\n" diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index 21677e98318..39850227162 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -30,227 +30,6 @@ mysql_get_identifier_quote_char(void); used in SQL identifiers */ /************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_printf( -/*======*/ - /* out: the number of characters written, or - negative in case of an error */ - const char* format, /* in: format of prints */ - ...) /* in: arguments to be printed */ -{ - va_list args; - ulint len; - char* format_end; - char* newformat; - char* ptr; - char* newptr; - int ret; - char format_buf_in_stack[500]; - - len = strlen(format); - - if (len > 250) { - newformat = malloc(2 * len); - } else { - newformat = format_buf_in_stack; - } - - format_end = (char*)format + len; - - ptr = (char*)format; - newptr = newformat; - -#if defined(__WIN__) && (defined(WIN64) || defined(_WIN64)) - /* Replace %l with %I64 if it is not preceded with '\' */ - - while (ptr < format_end) { - if (*ptr == '%' && *(ptr + 1) == 'l' - && (ptr == format || *(ptr - 1) != '\\')) { - - memcpy(newptr, "%I64", 4); - ptr += 2; - newptr += 4; - } else { - *newptr = *ptr; - ptr++; - newptr++; - } - } - - *newptr = '\0'; - - ut_a(newptr < newformat + 2 * len); -#else - strcpy(newformat, format); -#endif - va_start(args, format); - - ret = vprintf((const char*)newformat, args); - - va_end(args); - - if (newformat != format_buf_in_stack) { - free(newformat); - } - - return(ret); -} - -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_sprintf( -/*=======*/ - /* out: the number of characters written, or - negative in case of an error */ - char* buf, /* in: buffer where to print */ - const char* format, /* in: format of prints */ - ...) /* in: arguments to be printed */ -{ - va_list args; - ulint len; - char* format_end; - char* newformat; - char* ptr; - char* newptr; - int ret; - char format_buf_in_stack[500]; - - len = strlen(format); - - if (len > 250) { - newformat = malloc(2 * len); - } else { - newformat = format_buf_in_stack; - } - - format_end = (char*)format + len; - - ptr = (char*)format; - newptr = newformat; - -#if defined(__WIN__) && (defined(WIN64) || defined(_WIN64)) - /* Replace %l with %I64 if it is not preceded with '\' */ - - while (ptr < format_end) { - if (*ptr == '%' && *(ptr + 1) == 'l' - && (ptr == format || *(ptr - 1) != '\\')) { - - memcpy(newptr, "%I64", 4); - ptr += 2; - newptr += 4; - } else { - *newptr = *ptr; - ptr++; - newptr++; - } - } - - *newptr = '\0'; - - ut_a(newptr < newformat + 2 * len); -#else - strcpy(newformat, format); -#endif - va_start(args, format); - - ret = vsprintf(buf, (const char*)newformat, args); - - va_end(args); - - if (newformat != format_buf_in_stack) { - free(newformat); - } - - return(ret); -} - -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_fprintf( -/*=======*/ - /* out: the number of characters written, or - negative in case of an error */ - FILE* stream, /* in: stream where to print */ - const char* format, /* in: format of prints */ - ...) /* in: arguments to be printed */ -{ - va_list args; - ulint len; - char* format_end; - char* newformat; - char* ptr; - char* newptr; - int ret; - char format_buf_in_stack[500]; - - len = strlen(format); - - if (len > 250) { - newformat = malloc(2 * len); - } else { - newformat = format_buf_in_stack; - } - - format_end = (char*)format + len; - - ptr = (char*)format; - newptr = newformat; - -#if defined(__WIN__) && (defined(WIN64) || defined(_WIN64)) - /* Replace %l with %I64 if it is not preceded with '\' */ - - while (ptr < format_end) { - if (*ptr == '%' && *(ptr + 1) == 'l' - && (ptr == format || *(ptr - 1) != '\\')) { - - memcpy(newptr, "%I64", 4); - ptr += 2; - newptr += 4; - } else { - *newptr = *ptr; - ptr++; - newptr++; - } - } - - *newptr = '\0'; - - ut_a(newptr < newformat + 2 * len); -#else - strcpy(newformat, format); -#endif - va_start(args, format); - - ret = vfprintf(stream, (const char*)newformat, args); - - va_end(args); - - if (newformat != format_buf_in_stack) { - free(newformat); - } - - return(ret); -} - -/************************************************************ Gets the high 32 bits in a ulint. That is makes a shift >> 32, but since there seem to be compiler bugs in both gcc and Visual C++, we do this by a special conversion. */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a467b7fc9fd..2214ca68c81 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3729,28 +3729,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) mysql= mysql->last_used_con; - if (stmt->update_max_length && !stmt->bind_result_done) - { - /* - We must initalize the bind structure to be able to calculate - max_length - */ - MYSQL_BIND *bind, *end; - MYSQL_FIELD *field; - bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count); - - for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields; - bind < end ; - bind++, field++) - { - bind->buffer_type= field->type; - bind->buffer_length=1; - } - - mysql_stmt_bind_result(stmt, stmt->bind); - stmt->bind_result_done= 0; /* No normal bind done */ - } - while ((pkt_len= net_safe_read(mysql)) != packet_error) { cp= net->read_pos; @@ -3768,8 +3746,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) memcpy((char *) cur->data, (char *) cp+1, pkt_len-1); cur->length= pkt_len; /* To allow us to do sanity checks */ result->rows++; - if (stmt->update_max_length) - stmt_update_metadata(stmt, cur); } else { @@ -3814,6 +3790,29 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) result->rows= 0; stmt->data_cursor= NULL; } + + if (stmt->update_max_length && !stmt->bind_result_done) + { + /* + We must initalize the bind structure to be able to calculate + max_length + */ + MYSQL_BIND *bind, *end; + MYSQL_FIELD *field; + bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count); + + for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields; + bind < end ; + bind++, field++) + { + bind->buffer_type= field->type; + bind->buffer_length=1; + } + + mysql_stmt_bind_result(stmt, stmt->bind); + stmt->bind_result_done= 0; /* No normal bind done */ + } + if ((*mysql->methods->read_binary_rows)(stmt)) { free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); @@ -3822,6 +3821,13 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } + if (stmt->update_max_length) + { + MYSQL_ROWS *cur= result->data; + for(; cur; cur=cur->next) + stmt_update_metadata(stmt, cur); + } + stmt->data_cursor= result->data; mysql->affected_rows= stmt->affected_rows= result->rows; stmt->read_row_func= stmt_read_row_buffered; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 137af80313a..2bbca220db9 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -204,6 +204,8 @@ static int emb_stmt_execute(MYSQL_STMT *stmt) set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } + stmt->affected_rows= stmt->mysql->affected_rows; + stmt->insert_id= stmt->mysql->insert_id; DBUG_RETURN(0); } @@ -612,13 +614,14 @@ bool Protocol::send_fields(List<Item> *list, uint flag) if (!(res=item->val_str(&tmp))) { - client_field->def= strdup_root(field_alloc, ""); client_field->def_length= 0; + client_field->def= strmake_root(field_alloc, "",0); } else { - client_field->def= strdup_root(field_alloc, res->ptr()); client_field->def_length= res->length(); + client_field->def= strmake_root(field_alloc, res->ptr(), + client_field->def_length); } } else diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index 9b42d51ab55..c9caf4f39af 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -90,8 +90,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) /* Skip rows inserted by current inserted */ for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ; - (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && - !r && info->lastpos >= info->state->data_file_length ; + !r && + (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && + info->lastpos >= info->state->data_file_length ; r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, SEARCH_BIGGER, key_root)) ; diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 30a4762abe0..f64e774810d 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -311,7 +311,7 @@ static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block, DBUG_RETURN(1); /* Wrong delete link */ } } - return 0; + DBUG_RETURN(0); } /* Delete datarecord from database */ diff --git a/myisam/rt_test.c b/myisam/rt_test.c index c1126c1939a..41cc56d4d78 100644 --- a/myisam/rt_test.c +++ b/myisam/rt_test.c @@ -39,7 +39,7 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) } -int run_test(const char *filename) +static int run_test(const char *filename) { MI_INFO *file; MI_UNIQUEDEF uniquedef; diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 81e2cd03d1a..dd4c32403b5 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -94,11 +94,13 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 2 DERIVED t1 ALL NULL NULL NULL NULL 4 3 UNION t1 ALL NULL NULL NULL NULL 4 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL explain select * from (select * from t1 union all select * from t1) a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 2 DERIVED t1 ALL NULL NULL NULL NULL 4 3 UNION t1 ALL NULL NULL NULL NULL 4 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL CREATE TABLE t2 (a int not null); insert into t2 values(1); select * from (select * from t1 where t1.a=(select a from t2 where t2.a=t1.a)) a; @@ -246,8 +248,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 4 DERIVED t1 ALL NULL NULL NULL NULL 2 5 UNION t1 ALL NULL NULL NULL NULL 2 +NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL 2 DERIVED t1 ALL NULL NULL NULL NULL 2 3 UNION t1 ALL NULL NULL NULL NULL 2 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL drop table t1; CREATE TABLE `t1` ( `N` int(11) unsigned NOT NULL default '0', diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index f93f7401081..3106602e718 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -142,6 +142,8 @@ a b MySQL has now support for full-text search select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); a b +select * from t1 where MATCH a,b AGAINST ('"xt indexes"' IN BOOLEAN MODE); +a b select * from t1 where MATCH a,b AGAINST ('+(support collections) +foobar*' IN BOOLEAN MODE); a b select * from t1 where MATCH a,b AGAINST ('+(+(support collections)) +foobar*' IN BOOLEAN MODE); diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 700fe1a4111..981ef23c779 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -467,7 +467,7 @@ ERROR 23000: Duplicate entry 'test2' for key 2 select * from t1; id ggid email passwd 1 this will work -4 test2 this will work +3 test2 this will work select * from t1 where id=1; id ggid email passwd 1 this will work diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 5edffdacc98..694dc26bcde 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -89,10 +89,10 @@ create table t1 ( pk int primary key, name varchar(255) not null, number v insert into t1 values (1, 'Gamma', '123'), (2, 'Gamma Ext', '123a'), (3, 'Alpha', '001'), (4, 'Beta', '200c'); select distinct t1.name as 'Building Name',t1.number as 'Building Number' from t1 order by t1.name asc; Building Name Building Number -Gamma 123 -Gamma Ext 123a Alpha 001 Beta 200c +Gamma 123 +Gamma Ext 123a drop table t1; create table t1 (id int not null,col1 int not null,col2 int not null,index(col1)); insert into t1 values(1,2,2),(2,2,1),(3,1,2),(4,1,1),(5,1,4),(6,2,3),(7,3,1),(8,2,4); diff --git a/mysql-test/r/rpl_server_id2.result b/mysql-test/r/rpl_server_id2.result index fde7251497a..82ab1ff85a7 100644 --- a/mysql-test/r/rpl_server_id2.result +++ b/mysql-test/r/rpl_server_id2.result @@ -4,9 +4,6 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -drop table if exists t1; -Warnings: -Note 1051 Unknown table 't1' create table t1 (n int); reset master; stop slave; diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result index ad0fb9e5022..085a2937584 100644 --- a/mysql-test/r/rpl_trunc_binlog.result +++ b/mysql-test/r/rpl_trunc_binlog.result @@ -10,4 +10,4 @@ reset slave; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log. 0 79 326 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log. 0 79 # None 0 No # diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 8fe447c59fd..9ad3a5a9cf2 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -16,6 +16,7 @@ explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1249 Select 2 was reduced during optimisation Note 1249 Select 4 was reduced during optimisation @@ -28,6 +29,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL Warnings: Note 1249 Select 2 was reduced during optimisation Note 1003 select (select 0 AS `0` union select 0 AS `0`) AS `(SELECT (SELECT 0 UNION SELECT 0))` @@ -182,6 +184,7 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using filesort 3 UNION t4 ALL NULL NULL NULL NULL 3 Using where; Using filesort 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1003 (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.b = (select test.t3.a AS `a` from test.t3 order by test.t3.a desc limit 1))) union (select test.t4.a AS `a`,test.t4.b AS `b` from test.t4 where (test.t4.b = (select (max(test.t2.a) * 4) AS `max(t2.a)*4` from test.t2)) order by test.t4.a) select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; @@ -306,6 +309,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 Using where +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1276 Field or reference 't2.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 't2.a' of SELECT #3 was resolved in SELECT #1 @@ -413,6 +417,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL topic 3 NULL 2 Using index 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1003 select 1 AS `1` from test.t1 drop table t1; @@ -727,6 +732,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL id 5 NULL 2 Using where; Using index 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL Warnings: Note 1003 select test.t2.id AS `id` from test.t2 where <in_optimizer>(test.t2.id,<exists>(select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(1)) union select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(3)))) SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3); @@ -1536,11 +1542,14 @@ e select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); s1 e -explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); +explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 SUBQUERY t1 system NULL NULL NULL NULL 1 3 UNION t1 system NULL NULL NULL NULL 1 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +Warnings: +Note 1003 select test.t1.s1 AS `s1` from test.t1 drop table t1; CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874'); diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index cc29c676283..66eb744e7ce 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -35,6 +35,12 @@ Table Op Msg_type Msg_text test.t1 check status OK delete from t1; insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460"); +Warnings: +Warning 1264 Data truncated, out of range for column 't' at row 14 +Warning 1264 Data truncated, out of range for column 't' at row 15 +Warning 1264 Data truncated, out of range for column 't' at row 16 +Warning 1264 Data truncated, out of range for column 't' at row 17 +Warning 1264 Data truncated, out of range for column 't' at row 18 select * from t1; t 2000-01-01 00:00:00 diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 71ac229601d..f044ced2342 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -70,6 +70,21 @@ select min(a) from t1; min(a) -0.010 drop table t1; +create table t1 (c1 double, c2 varchar(20)); +insert t1 values (121,"16"); +select c1 + c1 * (c2 / 100) as col from t1; +col +140.36 +create table t2 select c1 + c1 * (c2 / 100) as col from t1; +select * from t2; +col +140.36 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `col` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2; create table t1 (a float); insert into t1 values (1); select max(a),min(a),avg(a) from t1; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index c85b59be38c..0735ea4dc40 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -86,6 +86,7 @@ explain extended (select a,b from t1 limit 2) union all (select a,b from t2 ord id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 2 UNION t2 ALL NULL NULL NULL NULL 4 Using filesort +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort Warnings: Note 1003 (select test.t1.a AS `a`,test.t1.b AS `b` from test.t1 limit 2) union all (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 order by test.t2.a limit 1) order by b desc (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; @@ -106,21 +107,15 @@ explain select a,b from t1 union all select a,b from t2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 2 UNION t2 ALL NULL NULL NULL NULL 4 +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL explain select xx from t1 union select 1; ERROR 42S22: Unknown column 'xx' in 'field list' explain select a,b from t1 union select 1; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +ERROR 21000: The used SELECT statements have a different number of columns explain select 1 union select a,b from t1 union select 1; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 UNION t1 ALL NULL NULL NULL NULL 4 -3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +ERROR 21000: The used SELECT statements have a different number of columns explain select a,b from t1 union select 1 limit 0; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 UNION NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +ERROR 21000: The used SELECT statements have a different number of columns select a,b from t1 into outfile 'skr' union select a,b from t2; ERROR HY000: Wrong usage of UNION and INTO select a,b from t1 order by a union select a,b from t2; @@ -475,6 +470,7 @@ explain extended (select * from t1 where a=1) union (select * from t2 where a=1) id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 2 UNION t2 const PRIMARY PRIMARY 4 const 1 +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Warnings: Note 1003 (select test.t1.a AS `a`,test.t1.b AS `b` from test.t1 where (test.t1.a = 1)) union (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.a = 1)) (select * from t1 where a=5) union (select * from t2 where a=1); @@ -497,10 +493,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index 2 UNION t2 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL explain (select * from t1 where a=1) union (select * from t1 where b=1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 2 UNION t1 ref b b 5 const 1 Using where +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL drop table t1,t2; create table t1 ( id int not null auto_increment, primary key (id) ,user_name text ); create table t2 ( id int not null auto_increment, primary key (id) ,group_name text ); @@ -950,3 +948,8 @@ a 1 drop table t1, t2; set sql_select_limit=default; +CREATE TABLE t1 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); +CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); +explain (select * from t1) union (select * from t2) order by not_existing_column; +ERROR 42S22: Unknown column 'not_existing_column' in 'order clause' +drop table t1, t2; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 50a3d522e3d..ac88125965a 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -63,6 +63,7 @@ select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOL select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"xt indexes"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('+(support collections) +foobar*' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('+(+(support collections)) +foobar*' IN BOOLEAN MODE); diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index 38e0d1bff6c..b0119526deb 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -12,7 +12,7 @@ show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT --replace_column 1 # 33 # show slave status; --replace_result $MASTER_MYPORT MASTER_PORT diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index 4e4e79adf67..0062a67ff1a 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -14,7 +14,7 @@ connection slave; sync_with_master; # The port number is different when doing the release build with # Do-compile, hence we have to replace the port number here accordingly ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; # check that the table has been ignored, because otherwise the test is nonsense diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index 7ae0a4dc3c2..8fdccdd068d 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -89,11 +89,11 @@ connection slave; start slave; sync_with_master; show binary logs; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION +--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.000001' from 4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION +--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.000002' from 4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index 2e54c98c014..a40736577c8 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -4,7 +4,7 @@ source include/master-slave.inc; show master status; sync_slave_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; stop slave; @@ -14,19 +14,19 @@ sleep 5; stop slave; change master to master_log_pos=73; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; start slave; sleep 5; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; stop slave; change master to master_log_pos=173; start slave; sleep 2; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; connection master; diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index a28aed52ec8..cbcc115a942 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -28,7 +28,7 @@ set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; stop slave; @@ -37,7 +37,7 @@ set global max_relay_log_size=(5*4096); select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; stop slave; @@ -46,7 +46,7 @@ set global max_relay_log_size=0; select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; @@ -57,7 +57,7 @@ reset slave; # test of relay log rotation when the slave is stopped # (to make sure it does not crash). flush logs; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; @@ -73,7 +73,7 @@ create table t1 (a int); save_master_pos; connection slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; # one more rotation, to be sure Relay_Log_Space is correctly updated @@ -83,7 +83,7 @@ drop table t1; save_master_pos; connection slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index 0d447b8d1a3..da4d5f0bce1 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -31,14 +31,14 @@ system chmod 600 var/slave-data/master.info; # init_strvar_from_file() in init_master_info()). --error 1201 start slave; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT # CHANGE MASTER will fail because it first parses master.info before changing # it (so when master.info is bad, people have to use RESET SLAVE first). --error 1201 eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; reset slave; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; connection master; reset master; @@ -54,7 +54,7 @@ insert into temp_table values ("testing temporary tables"); create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); sync_slave_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; select * from t1; @@ -107,7 +107,7 @@ purge master logs before now(); show binary logs; insert into t2 values (65); sync_slave_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; select * from t2; @@ -139,7 +139,7 @@ connection slave; sync_with_master; select * from t4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # show slave status; # because of concurrent insert, the table may not be up to date diff --git a/mysql-test/t/rpl_server_id2.test b/mysql-test/t/rpl_server_id2.test index dc8f733b7ed..7bbac358ada 100644 --- a/mysql-test/t/rpl_server_id2.test +++ b/mysql-test/t/rpl_server_id2.test @@ -3,7 +3,6 @@ source include/master-slave.inc; connection slave; -drop table if exists t1; create table t1 (n int); reset master; # replicate ourselves diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test index 32052af9184..2ade41ee96d 100644 --- a/mysql-test/t/rpl_trunc_binlog.test +++ b/mysql-test/t/rpl_trunc_binlog.test @@ -21,5 +21,5 @@ start slave; # can't sync_with_master so we must sleep sleep 3; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 23 # 33 # show slave status; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 94389963ae6..0f461ba5277 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -974,7 +974,7 @@ create table t1 (s1 char); insert into t1 values ('e'); select * from t1 where 'f' > any (select s1 from t1); select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); -explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); +explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); drop table t1; # diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 7d3b90aabeb..d3ddecfc314 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -31,6 +31,14 @@ select a from t1 order by a; select min(a) from t1; drop table t1; +create table t1 (c1 double, c2 varchar(20)); +insert t1 values (121,"16"); +select c1 + c1 * (c2 / 100) as col from t1; +create table t2 select c1 + c1 * (c2 / 100) as col from t1; +select * from t2; +show create table t2; +drop table t1,t2; + # Bug #1022: When a table contains a 'float' field, # and one of the functions MAX, MIN, or AVG is used on that field, # the system crashes. diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index d9e19571f81..f6006a87d47 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -39,8 +39,11 @@ explain select a,b from t1 union all select a,b from t2; --error 1054 explain select xx from t1 union select 1; +--error 1222 explain select a,b from t1 union select 1; +--error 1222 explain select 1 union select a,b from t1 union select 1; +--error 1222 explain select a,b from t1 union select 1 limit 0; --error 1221 @@ -515,3 +518,12 @@ SET SQL_SELECT_LIMIT=1; select a from t1 union select a from t2 order by a; drop table t1, t2; set sql_select_limit=default; + +# +# nonexisting column in global ORDER BY +# +CREATE TABLE t1 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); +CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); +--error 1054 +explain (select * from t1) union (select * from t2) order by not_existing_column; +drop table t1, t2; diff --git a/ndb/src/kernel/ndb-main/Main.cpp b/ndb/src/kernel/ndb-main/Main.cpp index ef33802cab6..1515a108e35 100644 --- a/ndb/src/kernel/ndb-main/Main.cpp +++ b/ndb/src/kernel/ndb-main/Main.cpp @@ -228,16 +228,25 @@ systemInfo(const Configuration & config, const LogLevel & logLevel){ void catchsigs(bool ignore){ #if ! defined NDB_SOFTOSE && !defined NDB_OSE + +#if defined SIGRTMIN + #define MAX_SIG_CATCH SIGRTMIN +#elif defined NSIG + #define MAX_SIG_CATCH NSIG +#else + #error "neither SIGRTMIN or NSIG is defined on this platform, please report bug at bugs.mysql.com" +#endif + // Makes the main process catch process signals, eg installs a // handler named "handler". "handler" will then be called is instead // of the defualt process signal handler) if(ignore){ - for(int i = 1; i<100; i++){ + for(int i = 1; i < MAX_SIG_CATCH; i++){ if(i != SIGCHLD) signal(i, SIG_IGN); - } + } } else { - for(int i = 1; i<100; i++){ + for(int i = 1; i < MAX_SIG_CATCH; i++){ signal(i, handler); } } diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 3261ec309d4..da83e195943 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -224,6 +224,7 @@ $CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/* $CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r if [ $BASE_SYSTEM != "netware" ] ; then + chmod a+x $BASE/bin/* $CP scripts/* $BASE/bin $BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ \@pkgdatadir\@ ./support-files < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db $BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server diff --git a/sql/examples/ha_example.h b/sql/examples/ha_example.h index ffc4f5b941c..2228f04284a 100644 --- a/sql/examples/ha_example.h +++ b/sql/examples/ha_example.h @@ -114,10 +114,8 @@ public: int reset(void); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); - ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, + key_range *max_key); int delete_table(const char *from); int rename_table(const char * from, const char * to); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); diff --git a/sql/field.cc b/sql/field.cc index 1ad7e039363..944f18080f6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3930,6 +3930,11 @@ void Field_newdate::sql_type(String &res) const int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { longlong tmp=str_to_datetime(from,len,1); + if (tmp < 0) + { + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + tmp= 0; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 9915dc90dc1..c375614ac95 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -375,7 +375,7 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, min_key->length != key->key_length || min_key->flag != HA_READ_KEY_EXACT || max_key->flag != HA_READ_AFTER_KEY) - return HA_POS_ERROR; // Can't only use exact keys + return HA_POS_ERROR; // Can only use exact keys return 10; // Good guess } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index ff491a95043..8a40af90541 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -325,6 +325,35 @@ convert_error_code_to_mysql( } /***************************************************************** +If you want to print a thd that is not associated with the current thread, +you must call this function before reserving the InnoDB kernel_mutex, to +protect MySQL from setting thd->query NULL. If you print a thd of the current +thread, we know that MySQL cannot modify thd->query, and it is not necessary +to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release +the kernel_mutex. +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ +extern "C" +void +innobase_mysql_prepare_print_arbitrary_thd(void) +/*============================================*/ +{ + VOID(pthread_mutex_lock(&LOCK_thread_count)); +} + +/***************************************************************** +Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd(). +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ +extern "C" +void +innobase_mysql_end_print_arbitrary_thd(void) +/*========================================*/ +{ + VOID(pthread_mutex_unlock(&LOCK_thread_count)); +} + +/***************************************************************** Prints info of a THD object (== user session thread) to the standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain the prototype for this function! */ @@ -335,9 +364,11 @@ innobase_mysql_print_thd( FILE* f, /* in: output stream */ void* input_thd)/* in: pointer to a MySQL THD object */ { - THD* thd; + const THD* thd; + const char* s; + char buf[301]; - thd = (THD*) input_thd; + thd = (const THD*) input_thd; fprintf(f, "MySQL thread id %lu, query id %lu", thd->thread_id, thd->query_id); @@ -356,14 +387,31 @@ innobase_mysql_print_thd( fputs(thd->user, f); } - if (thd->proc_info) { + if ((s = thd->proc_info)) { putc(' ', f); - fputs(thd->proc_info, f); + fputs(s, f); } - if (thd->query) { - putc(' ', f); - fputs(thd->query, f); + if ((s = thd->query)) { + /* determine the length of the query string */ + uint32 i, len; + + len = thd->query_length; + + if (len > 300) { + len = 300; /* ADDITIONAL SAFETY: print at most + 300 chars to reduce the probability of + a seg fault if there is a race in + thd->query_length in MySQL; after + May 14, 2004 probably no race any more, + but better be safe */ + } + + /* Use strmake to reduce the timeframe + for a race, compared to fwrite() */ + i= (uint) (strmake(buf, s, len) - buf); + putc('\n', f); + fwrite(buf, 1, i, f); } putc('\n', f); diff --git a/sql/handler.cc b/sql/handler.cc index f8eca1b93ef..9acd55db0b1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -103,15 +103,16 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", enum db_type ha_resolve_by_name(const char *name, uint namelen) { - if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { - return(enum db_type) current_thd->variables.table_type; + THD *thd=current_thd; + if (thd && !my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { + return (enum db_type) thd->variables.table_type; } show_table_type_st *types; for (types= sys_table_types; types->type; types++) { if (!my_strcasecmp(&my_charset_latin1, name, types->type)) - return(enum db_type)types->db_type; + return (enum db_type) types->db_type; } return DB_TYPE_UNKNOWN; } diff --git a/sql/item.cc b/sql/item.cc index 11a9e88bdd6..700d9482815 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -369,9 +369,14 @@ const char *Item_ident::full_name() const } else { - tmp=(char*) sql_alloc((uint) strlen(table_name)+ - (uint) strlen(field_name)+2); - strxmov(tmp,table_name,".",field_name,NullS); + if (table_name[0]) + { + tmp= (char*) sql_alloc((uint) strlen(table_name) + + (uint) strlen(field_name) + 2); + strxmov(tmp, table_name, ".", field_name, NullS); + } + else + tmp= (char*) field_name; } return tmp; } @@ -641,6 +646,7 @@ void Item_param::set_null() DBUG_ENTER("Item_param::set_null"); /* These are cleared after each execution by reset() method */ null_value= value_is_set= 1; + max_length= 0; DBUG_VOID_RETURN; } @@ -651,6 +657,7 @@ void Item_param::set_int(longlong i) item_type= INT_ITEM; value_is_set= 1; maybe_null= 0; + max_length= 11; DBUG_PRINT("info", ("integer: %lld", int_value)); DBUG_VOID_RETURN; } @@ -662,6 +669,8 @@ void Item_param::set_double(double value) item_type= REAL_ITEM; value_is_set= 1; maybe_null= 0; + decimals= NOT_FIXED_DEC; + max_length= DBL_DIG + 8;; DBUG_PRINT("info", ("double: %lg", real_value)); DBUG_VOID_RETURN; } @@ -674,6 +683,7 @@ void Item_param::set_value(const char *str, uint length) item_type= STRING_ITEM; value_is_set= 1; maybe_null= 0; + max_length= length; DBUG_PRINT("info", ("string: %s", str_value.ptr())); DBUG_VOID_RETURN; } @@ -699,6 +709,20 @@ void Item_param::set_time(TIME *tm, timestamp_type type) item_type= STRING_ITEM; value_is_set= 1; maybe_null= 0; + switch(type) + { + case TIMESTAMP_DATE: + max_length= 10; + break; + case TIMESTAMP_DATETIME: + max_length= 19; + break; + case TIMESTAMP_TIME: + max_length= 8; + break; + default: + DBUG_ASSERT(0); // it should be impossible + } } diff --git a/sql/item_func.cc b/sql/item_func.cc index aaea676fee1..f221e0dcc5c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -612,6 +612,7 @@ longlong Item_func_div::val_int() void Item_func_div::fix_length_and_dec() { decimals=max(args[0]->decimals,args[1]->decimals)+2; + set_if_smaller(decimals, NOT_FIXED_DEC); max_length=args[0]->max_length - args[0]->decimals + decimals; uint tmp=float_length(decimals); set_if_smaller(max_length,tmp); diff --git a/sql/log_event.cc b/sql/log_event.cc index b3ec1f0fe55..abbccb32034 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1058,6 +1058,7 @@ end: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; // prevent db from being freed thd->query= 0; // just to be sure + thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); // assume no convert for next query unless set explictly #ifdef TO_BE_REMOVED @@ -1674,6 +1675,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, thd->db= (char*) rewrite_db(db); DBUG_ASSERT(thd->query == 0); thd->query= 0; // Should not be needed + thd->query_length= 0; // Should not be needed thd->query_error= 0; clear_all_errors(thd, rli); if (!use_rli_only_for_errors) diff --git a/sql/slave.cc b/sql/slave.cc index 12fec28ec49..4ce8d5939bc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3156,6 +3156,7 @@ err: IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + thd->query_length = 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { @@ -3321,6 +3322,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ err: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + thd->query_length = 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 14a54a410a2..e3fbfb2d0e3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2103,7 +2103,9 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, => we have to check presence of name before compare */ if (item_field->name && - !my_strcasecmp(system_charset_info, item_field->name, field_name)) + (!my_strcasecmp(system_charset_info, item_field->name, field_name) || + !my_strcasecmp(system_charset_info, + item_field->field_name, field_name))) { if (!table_name) { diff --git a/sql/sql_class.h b/sql/sql_class.h index e602b7d6d5f..f32f07797f3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -598,7 +598,24 @@ public: struct rand_struct rand; // used for authentication struct system_variables variables; // Changeable local variables pthread_mutex_t LOCK_delete; // Locked before thd is deleted - + /* + Note that (A) if we set query = NULL, we must at the same time set + query_length = 0, and protect the whole operation with the + LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a + non-NULL value if its previous value is NULL. We do not need to protect + operation (B) with any mutex. To avoid crashes in races, if we do not + know that thd->query cannot change at the moment, one should print + thd->query like this: + (1) reserve the LOCK_thread_count mutex; + (2) check if thd->query is NULL; + (3) if not NULL, then print at most thd->query_length characters from + it. We will see the query_length field as either 0, or the right value + for it. + Assuming that the write and read of an n-bit memory field in an n-bit + computer is atomic, we can avoid races in the above way. + This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB + STATUS. + */ /* all prepared statements and cursors of this connection */ Statement_map stmt_map; /* @@ -1152,7 +1169,6 @@ class select_union :public select_result { TABLE *table; COPY_INFO info; TMP_TABLE_PARAM tmp_table_param; - bool not_describe; select_union(TABLE *table_par); ~select_union(); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1bf95b8bded..3aa0e9511a7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -411,7 +411,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) info.deleted+info.updated, (ulong) thd->cuted_fields); + (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff); } free_underlaid_joins(thd, &thd->lex->select_lex); @@ -1582,7 +1582,7 @@ bool select_insert::send_eof() (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) info.deleted+info.updated, (ulong) thd->cuted_fields); + (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,last_insert_id,buff); DBUG_RETURN(0); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1038066f6ef..0d3ab196aa5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1007,6 +1007,7 @@ void st_select_lex_unit::init_query() fake_select_lex= 0; cleaned= 0; item_list.empty(); + describe= 0; } void st_select_lex::init_query() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 557c037c799..2df2c998ff0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -339,6 +339,7 @@ public: st_select_lex *fake_select_lex; st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */ + bool describe; /* union exec() called for EXPLAIN */ void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e949d40625d..373f3c82ff3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1475,9 +1475,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, packet++; length--; } + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_length= length; thd->query= packet; - VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id= query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); #ifndef EMBEDDED_LIBRARY @@ -1493,7 +1493,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_rest.length(length); } else - thd->query_rest.copy(length); + thd->query_rest.copy(packet, length, thd->query_rest.charset()); break; #endif /*EMBEDDED_LIBRARY*/ } @@ -1768,6 +1768,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->proc_info=0; thd->command=COM_SLEEP; thd->query=0; + thd->query_length=0; thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory @@ -1807,6 +1808,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) packet_length--; } /* We must allocate some extra memory for query cache */ + thd->query_length= 0; // Extra safety: Avoid races if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), packet_length, thd->db_length+ 1 + @@ -4611,7 +4613,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, mysql_bin_log.new_file(1); mysql_slow_log.new_file(1); #ifdef HAVE_REPLICATION - if (expire_logs_days) + if (mysql_bin_log.is_open() && expire_logs_days) { long purge_time= time(0) - expire_logs_days*24*60*60; if (purge_time >= 0) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 61e5b778b64..a8e2cabe44b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -256,8 +256,11 @@ void set_param_short(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 2) return; -#endif int16 value= sint2korr(*pos); +#else + int16 value; + shortget(value, *pos); +#endif param->set_int(param->unsigned_flag ? (longlong) ((uint16) value) : (longlong) value); *pos+= 2; @@ -268,8 +271,11 @@ void set_param_int32(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 4) return; -#endif int32 value= sint4korr(*pos); +#else + int32 value; + longget(value, *pos); +#endif param->set_int(param->unsigned_flag ? (longlong) ((uint32) value) : (longlong) value); *pos+= 4; @@ -280,9 +286,13 @@ void set_param_int64(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 8) return; -#endif param->set_int((longlong)sint8korr(*pos)); *pos+= 8; +#else + longlong value; + longlongget(value, *pos); + param->set_int(value); +#endif } void set_param_float(Item_param *param, uchar **pos, ulong len) @@ -309,6 +319,7 @@ void set_param_double(Item_param *param, uchar **pos, ulong len) *pos+= 8; } +#ifndef EMBEDDED_LIBRARY void set_param_time(Item_param *param, uchar **pos, ulong len) { ulong length; @@ -386,6 +397,62 @@ void set_param_date(Item_param *param, uchar **pos, ulong len) *pos+= length; } +#else/*!EMBEDDED_LIBRARY*/ +void set_param_time(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.hour= to->hour; + tm.minute= to->minute; + tm.second= to->second; + + tm.year= tm.month= 0; + tm.neg= to->neg; + + param->set_time(&tm, TIMESTAMP_TIME); +} + +void set_param_datetime(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.hour= to->hour; + tm.minute= to->minute; + tm.second= to->second; + tm.year= to->year; + tm.month= to->month; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_DATETIME); +} + +void set_param_date(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.year= to->year; + tm.month= to->month; + tm.neg= 0; + tm.hour= tm.minute= tm.second= 0; + tm.second_part= 0; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_DATE); +} +#endif /*!EMBEDDED_LIBRARY*/ + void set_param_str(Item_param *param, uchar **pos, ulong len) { ulong length= get_param_length(pos, len); @@ -568,6 +635,7 @@ static bool emb_insert_params(Prepared_statement *stmt) { Item_param *param= *it; setup_one_conversion_function(param, client_param->buffer_type); + param->unsigned_flag= client_param->is_unsigned; if (!param->long_data_supplied) { if (*client_param->is_null) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4325edc3502..6da778f6196 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9132,7 +9132,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (message) { - item_list.push_back(new Item_int((int32) join->select_lex->select_number)); + item_list.push_back(new Item_int((int32) + join->select_lex->select_number)); item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), cs)); for (uint i=0 ; i < 7; i++) @@ -9141,6 +9142,70 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (result->send_data(item_list)) join->error= 1; } + else if (join->select_lex == join->unit->fake_select_lex) + { + /* + here we assume that the query will return at least two rows, so we + show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong + and no filesort will be actually done, but executing all selects in + the UNION to provide precise EXPLAIN information will hardly be + appreciated :) + */ + char table_name_buffer[NAME_LEN]; + item_list.empty(); + /* id */ + item_list.push_back(new Item_null); + /* select_type */ + item_list.push_back(new Item_string(join->select_lex->type, + strlen(join->select_lex->type), + cs)); + /* table */ + { + SELECT_LEX *sl= join->unit->first_select(); + uint len= 6, lastop= 0; + memcpy(table_name_buffer, "<union", 6); + for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select()) + { + len+= lastop; + lastop= my_snprintf(table_name_buffer + len, NAME_LEN - len, + "%u,", sl->select_number); + } + if (sl || len + lastop >= NAME_LEN) + { + memcpy(table_name_buffer + len, "...>", 5); + len+= 4; + } + else + { + len+= lastop; + table_name_buffer[len - 1]= '>'; // change ',' to '>' + } + item_list.push_back(new Item_string(table_name_buffer, len, cs)); + } + /* type */ + item_list.push_back(new Item_string(join_type_str[JT_ALL], + strlen(join_type_str[JT_ALL]), + cs)); + /* possible_keys */ + item_list.push_back(item_null); + /* key*/ + item_list.push_back(item_null); + /* key_len */ + item_list.push_back(item_null); + /* ref */ + item_list.push_back(item_null); + /* rows */ + item_list.push_back(item_null); + /* extra */ + if (join->unit->global_parameters->order_list.first) + item_list.push_back(new Item_string("Using filesort", + 14, cs)); + else + item_list.push_back(new Item_string("", 0, cs)); + + if (result->send_data(item_list)) + join->error= 1; + } else { table_map used_tables=0; @@ -9150,36 +9215,41 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, TABLE *table=tab->table; char buff[512],*buff_ptr=buff; char buff1[512], buff2[512]; - char derived_name[64]; + char table_name_buffer[NAME_LEN]; String tmp1(buff1,sizeof(buff1),cs); String tmp2(buff2,sizeof(buff2),cs); tmp1.length(0); tmp2.length(0); item_list.empty(); - item_list.push_back(new Item_int((int32) + /* id */ + item_list.push_back(new Item_uint((uint32) join->select_lex->select_number)); + /* select_type */ item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), cs)); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; + /* table */ if (table->derived_select_number) { /* Derived table name generation */ - int len= my_snprintf(derived_name, sizeof(derived_name)-1, + int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, "<derived%u>", table->derived_select_number); - item_list.push_back(new Item_string(derived_name, len, cs)); + item_list.push_back(new Item_string(table_name_buffer, len, cs)); } else item_list.push_back(new Item_string(table->table_name, strlen(table->table_name), cs)); + /* type */ item_list.push_back(new Item_string(join_type_str[tab->type], strlen(join_type_str[tab->type]), cs)); uint j; + /* possible_keys */ if (!tab->keys.is_clear_all()) { for (j=0 ; j < table->keys ; j++) @@ -9196,6 +9266,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs)); else item_list.push_back(item_null); + /* key key_len ref */ if (tab->ref.key_parts) { KEY *key_info=table->key_info+ tab->ref.key; @@ -9234,9 +9305,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(item_null); item_list.push_back(item_null); } + /* rows */ item_list.push_back(new Item_int((longlong) (ulonglong) join->best_positions[i]. records_read, 21)); + /* extra */ my_bool key_read=table->key_read; if ((tab->type == JT_NEXT || tab->type == JT_CONST) && table->used_keys.is_set(tab->index)) @@ -9301,32 +9374,53 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) DBUG_ENTER("mysql_explain_union"); int res= 0; SELECT_LEX *first= unit->first_select(); + for (SELECT_LEX *sl= first; sl; sl= sl->next_select()) { // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); - - res= mysql_explain_select(thd, sl, - (((&thd->lex->select_lex)==sl)? - ((thd->lex->all_selects_list != sl) ? - primary_key_name : "SIMPLE"): - ((sl == first)? - ((sl->linkage == DERIVED_TABLE_TYPE) ? - "DERIVED": - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT SUBQUERY": - (uncacheable?"UNCACHEABLE SUBQUERY": - "SUBQUERY"))): - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT UNION": - uncacheable?"UNCACHEABLE UNION": - "UNION"))), - result); - if (res) - break; - + sl->type= (((&thd->lex->select_lex)==sl)? + ((thd->lex->all_selects_list != sl) ? + primary_key_name : "SIMPLE"): + ((sl == first)? + ((sl->linkage == DERIVED_TABLE_TYPE) ? + "DERIVED": + ((uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT SUBQUERY": + (uncacheable?"UNCACHEABLE SUBQUERY": + "SUBQUERY"))): + ((uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT UNION": + uncacheable?"UNCACHEABLE UNION": + "UNION"))); + sl->options|= SELECT_DESCRIBE; + } + if (first->next_select()) + { + unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization + unit->fake_select_lex->type= "UNION RESULT"; + unit->fake_select_lex->options|= SELECT_DESCRIBE; + if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) + res= unit->exec(); + res|= unit->cleanup(); + } + else + { + thd->lex->current_select= first; + res= mysql_select(thd, &first->ref_pointer_array, + (TABLE_LIST*) first->table_list.first, + first->with_wild, first->item_list, + first->where, + first->order_list.elements + + first->group_list.elements, + (ORDER*) first->order_list.first, + (ORDER*) first->group_list.first, + first->having, + (ORDER*) thd->lex->proc_list.first, + 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 @@ -9334,30 +9428,6 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) } -int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, - select_result *result) -{ - DBUG_ENTER("mysql_explain_select"); - DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type)) - select_lex->type= type; - thd->lex->current_select= select_lex; - SELECT_LEX_UNIT *unit= select_lex->master_unit(); - int res= mysql_select(thd, &select_lex->ref_pointer_array, - (TABLE_LIST*) select_lex->table_list.first, - select_lex->with_wild, select_lex->item_list, - select_lex->where, - select_lex->order_list.elements + - select_lex->group_list.elements, - (ORDER*) select_lex->order_list.first, - (ORDER*) select_lex->group_list.first, - select_lex->having, - (ORDER*) thd->lex->proc_list.first, - select_lex->options | thd->options | SELECT_DESCRIBE, - result, unit, select_lex); - DBUG_RETURN(res); -} - - void st_select_lex::print(THD *thd, String *str) { if (!thd) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 51b44af63ec..80634c68ac7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1597,10 +1597,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->query=0; if (tmp->query) { - /* query_length is always set before tmp->query */ + /* + query_length is always set to 0 when we set query = NULL; see + the comment in sql_class.h why this prevents crashes in possible + races with query_length + */ uint length= min(max_query_length, tmp->query_length); - thd_info->query=(char*) thd->memdup(tmp->query,length+1); - thd_info->query[length]=0; + thd_info->query=(char*) thd->strmake(tmp->query,length); } thread_infos.append(thd_info); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index de3eeec0db0..e56dd4b476e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, ***************************************************************************/ select_union::select_union(TABLE *table_par) - :table(table_par), not_describe(0) + :table(table_par) { bzero((char*) &info,sizeof(info)); /* @@ -120,7 +120,7 @@ bool select_union::flush() ulong st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) { - ulong options_tmp= thd->options; + ulong options_tmp= thd->options | fake_select_lex->options; thd->lex->current_select= fake_select_lex; offset_limit_cnt= global_parameters->offset_limit; select_limit_cnt= global_parameters->select_limit + @@ -149,6 +149,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, select_result *tmp_result; DBUG_ENTER("st_select_lex_unit::prepare"); + describe= test(additional_options & SELECT_DESCRIBE); + /* result object should be reassigned even if preparing already done for max/min subquery (ALL/ANY optimization) @@ -156,7 +158,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, result= sel_result; if (prepared) + { + if (describe) + { + /* fast reinit for EXPLAIN */ + for (sl= first_select_in_union(); sl; sl= sl->next_select()) + { + sl->join->result= result; + select_limit_cnt= HA_POS_ERROR; + offset_limit_cnt= 0; + if (!sl->join->procedure && + result->prepare(sl->join->fields_list, this)) + { + DBUG_RETURN(1); + } + sl->join->select_options|= SELECT_DESCRIBE; + sl->join->reinit(); + } + } DBUG_RETURN(0); + } prepared= 1; res= 0; @@ -169,8 +190,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (!(tmp_result= union_result= new select_union(0))) goto err; - union_result->not_describe= 1; union_result->tmp_table_param.init(); + if (describe) + tmp_result= sel_result; } else { @@ -327,11 +349,11 @@ int st_select_lex_unit::exec() ulonglong add_rows=0; DBUG_ENTER("st_select_lex_unit::exec"); - if (executed && !uncacheable) + if (executed && !uncacheable && !describe) DBUG_RETURN(0); executed= 1; - if (uncacheable || !item || !item->assigned()) + if (uncacheable || !item || !item->assigned() || describe) { if (optimized && item && item->assigned()) { @@ -339,8 +361,9 @@ int st_select_lex_unit::exec() item->reset(); table->file->delete_all_rows(); } - if (union_distinct) // for subselects - table->file->extra(HA_EXTRA_CHANGE_KEY_TO_UNIQUE); + if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL) && + !describe) + DBUG_RETURN(1); // For sub-selects for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { ha_rows records_at_start= 0; @@ -350,7 +373,7 @@ int st_select_lex_unit::exec() res= sl->join->reinit(); else { - if (sl != global_parameters) + if (sl != global_parameters && !describe) { offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; @@ -362,7 +385,7 @@ int st_select_lex_unit::exec() We can't use LIMIT at this stage if we are using ORDER BY for the whole query */ - if (sl->order_list.first) + if (sl->order_list.first || describe) select_limit_cnt= HA_POS_ERROR; else select_limit_cnt= sl->select_limit+sl->offset_limit; @@ -392,7 +415,11 @@ int st_select_lex_unit::exec() records_at_start= table->file->records; sl->join->exec(); if (sl == union_distinct) - table->file->extra(HA_EXTRA_CHANGE_KEY_TO_DUP); + { + if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) + DBUG_RETURN(1); + table->no_keyread=1; + } res= sl->join->error; offset_limit_cnt= sl->offset_limit; if (!res && union_result->flush()) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d7ef1fc8d7f..45e8e6e67e2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1153,7 +1153,6 @@ merge_insert_types: opt_select_from: opt_limit_clause {} - | FROM DUAL_SYM {} | select_from select_lock_type; udf_func_type: @@ -2296,17 +2295,19 @@ select_part2: select_into: opt_limit_clause {} - | FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM - clause, and DUAL is system table without fields. - Is "SELECT 1 FROM DUAL" any better than - "SELECT 1" ? Hmmm :) */ | into | select_from | into select_from | select_from into; select_from: - FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause; + FROM join_table_list where_clause group_clause having_clause + opt_order_clause opt_limit_clause procedure_clause + | FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM + clause, and DUAL is system table without fields. + Is "SELECT 1 FROM DUAL" any better than + "SELECT 1" ? Hmmm :) */ + ; select_options: /* empty*/ @@ -4929,7 +4930,6 @@ keyword: | DIRECTORY_SYM {} | DISCARD {} | DO_SYM {} - | DUAL_SYM {} | DUMPFILE {} | DUPLICATE_SYM {} | DYNAMIC_SYM {} diff --git a/sql/time.cc b/sql/time.cc index 7fb466f6b97..db05d606292 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -663,11 +663,25 @@ time_t str_to_timestamp(const char *str,uint length) } +/* + Convert a string to datetime. + + SYNOPSIS + str_to_datetime() + str String to parse (see str_to_TIME() synopsis) + length Length of str + fuzzy_date Flags (see str_to_TIME() synopsis) + + RETURN + -1 if error + datetime value otherwise +*/ + longlong str_to_datetime(const char *str,uint length, uint fuzzy_date) { TIME l_time; if (str_to_TIME(str,length,&l_time,fuzzy_date) <= TIMESTAMP_DATETIME_ERROR) - return(0); + return -1; return (longlong) (l_time.year*LL(10000000000) + l_time.month*LL(100000000)+ l_time.day*LL(1000000)+ diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 2bde29ecc47..ccb8d07e786 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -223,7 +223,7 @@ static uint16 big5strokexfrm(uint16 i) static int my_strnncoll_big5_internal(const uchar **a_res, const uchar **b_res, uint length) { - const char *a= *a_res, *b= *b_res; + const uchar *a= *a_res, *b= *b_res; while (length--) { @@ -236,10 +236,10 @@ static int my_strnncoll_big5_internal(const uchar **a_res, b+= 2; length--; } - else if (sort_order_big5[(uchar) *a++] != - sort_order_big5[(uchar) *b++]) - return ((int) sort_order_big5[(uchar) a[-1]] - - (int) sort_order_big5[(uchar) b[-1]]); + else if (sort_order_big5[*a++] != + sort_order_big5[*b++]) + return ((int) sort_order_big5[a[-1]] - + (int) sort_order_big5[b[-1]]); } *a_res= a; *b_res= b; diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 1990060e67b..577f8a33275 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2585,7 +2585,7 @@ static uint16 gbksortorder(uint16 i) int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res, uint length) { - const char *a= *a_res, *b= *b_res; + const uchar *a= *a_res, *b= *b_res; uint a_char,b_char; while (length--) @@ -2601,9 +2601,9 @@ int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res, b+= 2; length--; } - else if (sort_order_gbk[(uchar) *a++] != sort_order_gbk[(uchar) *b++]) - return ((int) sort_order_gbk[(uchar) a[-1]] - - (int) sort_order_gbk[(uchar) b[-1]]); + else if (sort_order_gbk[*a++] != sort_order_gbk[*b++]) + return ((int) sort_order_gbk[a[-1]] - + (int) sort_order_gbk[b[-1]]); } *a_res= a; *b_res= b; diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index ed772a68845..9b02cd3b3da 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -283,7 +283,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, while (pos) { - if ((mblen= cs->cset->mb_wc(cs, &wc, b, e)) <0) + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0) break; b+= mblen; pos--; diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index ac805bf0a5a..72c28d92ca8 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -6750,8 +6750,8 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs, int s_res; int t_res; - slen= cs->cset->lengthsp(cs, s, slen); - tlen= cs->cset->lengthsp(cs, t, tlen); + slen= cs->cset->lengthsp(cs, (char*) s, slen); + tlen= cs->cset->lengthsp(cs, (char*) t, tlen); my_uca_scanner_init(&sscanner, cs, s, slen); my_uca_scanner_init(&tscanner, cs, t, tlen); @@ -6796,7 +6796,7 @@ static void my_hash_sort_uca(CHARSET_INFO *cs, int s_res; my_uca_scanner scanner; - slen= cs->cset->lengthsp(cs, s, slen); + slen= cs->cset->lengthsp(cs, (char*) s, slen); my_uca_scanner_init(&scanner, cs, s, slen); while ((s_res= my_uca_scanner_next(&scanner)) >0) diff --git a/tests/client_test.c b/tests/client_test.c index c244274a2e7..8225eb17707 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -2400,7 +2400,8 @@ static void test_long_data_str() MYSQL_STMT *stmt; int rc, i; char data[255]; - long length, length1; + long length; + ulong length1; MYSQL_RES *result; MYSQL_BIND bind[2]; my_bool is_null[2]; @@ -2495,8 +2496,8 @@ static void test_long_data_str1() MYSQL_STMT *stmt; int rc, i; char data[255]; - long length, length1; - ulong max_blob_length, blob_length; + long length; + ulong max_blob_length, blob_length, length1; my_bool true_value; MYSQL_RES *result; MYSQL_BIND bind[2]; @@ -3084,7 +3085,7 @@ static void test_bind_result_ext() char szData[20], bData[20]; ulong szLength, bLength; MYSQL_BIND bind[8]; - long length[8]; + ulong length[8]; my_bool is_null[8]; myheader("test_bind_result_ext"); @@ -5376,7 +5377,7 @@ static void test_store_result2() MYSQL_STMT *stmt; int rc; int nData; - long length; + ulong length; MYSQL_BIND bind[1]; myheader("test_store_result2"); @@ -8094,7 +8095,7 @@ static void test_ts() MYSQL_TIME ts; MYSQL_RES *prep_res; char strts[30]; - long length; + ulong length; int rc, field_count; char name; @@ -8974,7 +8975,8 @@ static void test_multi() char *query; MYSQL_BIND bind[1]; int rc, i; - long param= 1, length= 1; + long param= 1; + ulong length= 1; myheader("test_multi"); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -9100,7 +9102,7 @@ static void test_bind_nagative() int rc; MYSQL_BIND bind[1]; long my_val = 0L; - long my_length = 0L; + ulong my_length = 0L; long my_null = 0L; myheader("test_insert_select"); @@ -9141,7 +9143,7 @@ static void test_derived() int rc, i; MYSQL_BIND bind[1]; long my_val = 0L; - long my_length = 0L; + ulong my_length = 0L; long my_null = 0L; const char *query= "select count(1) from (select f.id from t1 f where f.id=?) as x"; @@ -9638,6 +9640,47 @@ group by b "); } +static void test_union_param() +{ + MYSQL_STMT *stmt; + char *query; + int rc, i; + MYSQL_BIND bind[2]; + char my_val[4]; + ulong my_length = 3L; + long my_null = 0L; + myheader("test_union_param"); + + strcpy(my_val, "abc"); + + query= (char*)"select ? as my_col union distinct select ?"; + stmt= mysql_prepare(mysql, query, strlen(query)); + check_stmt(stmt); + + /* bind parameters */ + bind[0].buffer_type= FIELD_TYPE_STRING; + bind[0].buffer= &my_val; + bind[0].buffer_length= 4; + bind[0].length= &my_length; + bind[0].is_null= (char*)&my_null; + bind[1].buffer_type= FIELD_TYPE_STRING; + bind[1].buffer= &my_val; + bind[1].buffer_length= 4; + bind[1].length= &my_length; + bind[1].is_null= (char*)&my_null; + + rc= mysql_bind_param(stmt, bind); + check_execute(stmt,rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt,rc); + assert(1 == my_process_stmt_result(stmt)); + } + + mysql_stmt_close(stmt); +} /* Read and parse arguments and MySQL options from my.cnf */ @@ -9782,6 +9825,7 @@ int main(int argc, char **argv) start_time= time((time_t *)0); + test_union_param(); client_query(); /* simple client query test */ #if NOT_YET_WORKING /* Used for internal new development debugging */ @@ -9871,7 +9915,10 @@ int main(int argc, char **argv) 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(); /* to 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 */ |