diff --git a/VC++Files/libmysqltest/mytest.c b/VC++Files/libmysqltest/mytest.c index 9af8c486e40..a1dc13db39f 100644 --- a/VC++Files/libmysqltest/mytest.c +++ b/VC++Files/libmysqltest/mytest.c @@ -91,6 +91,7 @@ main( int argc, char * argv[] ) mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, NULL, 0 ) ) { + myData->reconnect= 1; if ( mysql_select_db( myData, szDB ) < 0 ) { printf( "Can't select the %s database !\n", szDB ) ; mysql_close( myData ) ; diff --git a/VC++Files/mysqlmanager/mysqlmanagerview.cpp b/VC++Files/mysqlmanager/mysqlmanagerview.cpp index 1d4756e7d7a..f39e0a9963e 100644 --- a/VC++Files/mysqlmanager/mysqlmanagerview.cpp +++ b/VC++Files/mysqlmanager/mysqlmanagerview.cpp @@ -551,6 +551,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES); return; } + mysql.reconnect= 1; if (!(result=mysql_list_processes(&mysql))) { return; @@ -576,6 +577,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) ); return; } + mysql.reconnect= 1; if (!(result=mysql_list_dbs(&mysql,0))) { } @@ -603,6 +605,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) ); return; } + mysql.reconnect= 1; CResourceDatabase* pRes = (CResourceDatabase*) pResource; CString strDB = pResource->GetDisplayName(); strDB.TrimRight(); @@ -641,6 +644,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) ); return; } + mysql.reconnect= 1; HTREEITEM hParent = m_pTree->GetParentItem(hItem); memset( &item, 0, sizeof(TV_ITEM) ); item.hItem = hParent; @@ -714,6 +718,7 @@ void CMySqlManagerView::OnRefresh() { return; } + mysql.reconnect= 1; memset( &item, 0, sizeof(TV_ITEM) ); item.hItem = hParent; item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ; diff --git a/VC++Files/test1/mysql_thr.c b/VC++Files/test1/mysql_thr.c index fac5c37a9af..c2743cb8e4c 100644 --- a/VC++Files/test1/mysql_thr.c +++ b/VC++Files/test1/mysql_thr.c @@ -167,6 +167,7 @@ pthread_handler_decl(test_thread,arg) perror(""); goto end; } + mysql.reconnect= 1; if (mysql_query(&mysql,"select 1") < 0) { fprintf(stderr,"Query failed (%s)\n",mysql_error(&mysql)); diff --git a/VC++Files/winmysqladmin/main.cpp b/VC++Files/winmysqladmin/main.cpp index dfb2004a780..150bc669c74 100644 --- a/VC++Files/winmysqladmin/main.cpp +++ b/VC++Files/winmysqladmin/main.cpp @@ -1337,6 +1337,7 @@ void __fastcall TForm1::IsMySQLInit(void) } } + MySQL->reconnect= 1; } @@ -1348,6 +1349,7 @@ void __fastcall TForm1::IsMySQLInit(void) MySQL = mysql_init(MySQL); if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0)) IsConnect = true; + MySQL->reconnect= 1; } } } diff --git a/client/mysql.cc b/client/mysql.cc index 8e9dd84c8f0..cb3a56972fa 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2792,6 +2792,8 @@ sql_real_connect(char *host,char *database,char *user,char *password, connected=1; #ifndef EMBEDDED_LIBRARY mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens +#else + mysql.reconnect= 1; #endif #ifdef HAVE_READLINE build_completion_hash(rehash, 1); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 924af3a9977..21e8f6ab3e4 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -425,6 +425,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, unix_port, 0)) { + mysql->reconnect= 1; if (info) { fputs("\n",stderr); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 1c10ece92dd..7036deab2fe 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -753,6 +753,7 @@ static MYSQL* safe_connect() mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0)) die("failed on connect: %s", mysql_error(local_mysql)); + local_mysql->reconnect= 1; return local_mysql; } diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index c670b84db44..980046fe6e6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -628,6 +628,7 @@ static int dbConnect(char *host, char *user, char *passwd) DBerror(&mysql_connection, "when trying to connect"); return 1; } + mysql_connection.reconnect= 1; return 0; } /* dbConnect */ diff --git a/client/mysqldump.c b/client/mysqldump.c index 9d35de2c953..8fb48753a8c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1935,6 +1935,10 @@ static int dump_databases(char **db_names) static int init_dumping(char *database) { + if (mysql_get_server_version(sock) >= 50003 && + !my_strcasecmp(&my_charset_latin1, database, "information_schema")) + return 1; + if (mysql_select_db(sock, database)) { DBerror(sock, "when selecting the database"); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index fae84be610a..3552f03fb27 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -388,6 +388,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd) ignore_errors=0; /* NO RETURN FROM db_error */ db_error(&mysql_connection); } + mysql_connection.reconnect= 0; if (verbose) fprintf(stdout, "Selecting database %s\n", database); if (mysql_select_db(sock, database)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index ee478058cdc..8171cb95268 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -125,6 +125,7 @@ int main(int argc, char **argv) fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql)); exit(1); } + mysql.reconnect= 1; switch (argc) { diff --git a/client/mysqltest.c b/client/mysqltest.c index bc99d4d38f3..e28737030b8 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1627,6 +1627,7 @@ int safe_connect(MYSQL* con, const char* host, const char* user, } sleep(CON_RETRY_SLEEP); } + con->reconnect= 1; /* TODO: change this to 0 in future versions */ return con_error; } diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index c911124e705..9da422e927f 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -567,7 +567,8 @@ btr_page_get_father_for_rec( btr_cur_t cursor; rec_t* node_ptr; dict_index_t* index; - ulint* offsets; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); @@ -591,7 +592,8 @@ btr_page_get_father_for_rec( BTR_CONT_MODIFY_TREE, &cursor, 0, mtr); node_ptr = btr_cur_get_rec(&cursor); - offsets = rec_get_offsets(node_ptr, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != buf_frame_get_page_no(page)) { @@ -609,13 +611,13 @@ btr_page_get_father_for_rec( (ulong) btr_node_ptr_get_child_page_no(node_ptr, offsets), (ulong) buf_frame_get_page_no(page)); - offsets = rec_reget_offsets(page_rec_get_next( + offsets = rec_get_offsets(page_rec_get_next( page_get_infimum_rec(page)), index, - offsets, ULINT_UNDEFINED, heap); + offsets, ULINT_UNDEFINED, &heap); page_rec_print(page_rec_get_next(page_get_infimum_rec(page)), offsets); - offsets = rec_reget_offsets(node_ptr, index, offsets, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(node_ptr, offsets); fputs( @@ -1231,7 +1233,7 @@ btr_page_get_sure_split_rec( ins_rec = btr_cur_get_rec(cursor); rec = page_get_infimum_rec(page); - heap = mem_heap_create(100); + heap = NULL; offsets = NULL; /* We start to include records to the left half, and when the @@ -1256,8 +1258,8 @@ btr_page_get_sure_split_rec( /* Include tuple */ incl_data += insert_size; } else { - offsets = rec_reget_offsets(rec, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, + offsets, ULINT_UNDEFINED, &heap); incl_data += rec_offs_size(offsets); } @@ -1280,12 +1282,16 @@ btr_page_get_sure_split_rec( next_rec = page_rec_get_next(rec); } if (next_rec != page_get_supremum_rec(page)) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(next_rec); } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(rec); } } @@ -1367,8 +1373,8 @@ btr_page_insert_fits( /* In this loop we calculate the amount of reserved space after rec is removed from page. */ - offs = rec_reget_offsets(rec, cursor->index, offs, - ULINT_UNDEFINED, heap); + offs = rec_get_offsets(rec, cursor->index, offs, + ULINT_UNDEFINED, &heap); total_data -= rec_offs_size(offs); total_n_recs--; @@ -1459,7 +1465,7 @@ btr_attach_half_pages( ut_a(page_is_comp(page) == page_is_comp(new_page)); /* Create a memory heap where the data tuple is stored */ - heap = mem_heap_create(100); + heap = mem_heap_create(1024); /* Based on split direction, decide upper and lower pages */ if (direction == FSP_DOWN) { @@ -1478,7 +1484,7 @@ btr_attach_half_pages( btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets(node_ptr, UT_LIST_GET_FIRST(tree->tree_indexes), - ULINT_UNDEFINED, heap), + NULL, ULINT_UNDEFINED, &heap), lower_page_no, mtr); mem_heap_empty(heap); } else { @@ -1656,8 +1662,8 @@ func_start: thus reducing the tree latch contention. */ if (split_rec) { - offsets = rec_reget_offsets(split_rec, cursor->index, - offsets, n_uniq, heap); + offsets = rec_get_offsets(split_rec, cursor->index, offsets, + n_uniq, &heap); insert_will_fit = btr_page_insert_fits(cursor, split_rec, offsets, tuple, heap); @@ -1700,8 +1706,8 @@ func_start: insert_page = right_page; } else { - offsets = rec_reget_offsets(first_rec, cursor->index, - offsets, n_uniq, heap); + offsets = rec_get_offsets(first_rec, cursor->index, + offsets, n_uniq, &heap); if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) { @@ -2091,14 +2097,18 @@ btr_compress( if (is_left) { btr_node_ptr_delete(tree, page, mtr); } else { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; /* Replace the address of the old child node (= page) with the address of the merge page to the right */ btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets(node_ptr, cursor->index, - ULINT_UNDEFINED, heap), right_page_no, mtr); - mem_heap_free(heap); + offsets_, ULINT_UNDEFINED, &heap), + right_page_no, mtr); + if (heap) { + mem_heap_free(heap); + } btr_node_ptr_delete(tree, merge_page, mtr); } @@ -2312,8 +2322,8 @@ btr_print_recursive( page_t* page, /* in: index page */ ulint width, /* in: print this many entries from start and end */ - mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ - ulint** offsets,/* in/out: buffer for rec_reget_offsets() */ + mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */ + ulint** offsets,/* in/out: buffer for rec_get_offsets() */ mtr_t* mtr) /* in: mtr */ { page_cur_t cursor; @@ -2350,8 +2360,8 @@ btr_print_recursive( node_ptr = page_cur_get_rec(&cursor); - *offsets = rec_reget_offsets(node_ptr, index, - *offsets, ULINT_UNDEFINED, heap); + *offsets = rec_get_offsets(node_ptr, index, *offsets, + ULINT_UNDEFINED, heap); child = btr_node_ptr_get_child(node_ptr, *offsets, &mtr2); btr_print_recursive(tree, child, width, @@ -2362,8 +2372,6 @@ btr_print_recursive( page_cur_move_to_next(&cursor); i++; } - - mem_heap_free(heap); } /****************************************************************** @@ -2378,8 +2386,10 @@ btr_print_tree( { mtr_t mtr; page_t* root; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] + = { 100, }; + ulint* offsets = offsets_; fputs("--------------------------\n" "INDEX TREE PRINT\n", stderr); @@ -2388,8 +2398,10 @@ btr_print_tree( root = btr_root_get(tree, &mtr); - btr_print_recursive(tree, root, width, heap, &offsets, &mtr); - mem_heap_free(heap); + btr_print_recursive(tree, root, width, &heap, &offsets, &mtr); + if (heap) { + mem_heap_free(heap); + } mtr_commit(&mtr); @@ -2435,7 +2447,7 @@ btr_check_node_ptr( ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr, rec_get_offsets(node_ptr, dict_tree_find_index(tree, node_ptr), - ULINT_UNDEFINED, heap)) == 0); + NULL, ULINT_UNDEFINED, &heap)) == 0); mem_heap_free(heap); @@ -2476,8 +2488,10 @@ btr_index_rec_validate( ulint n; ulint i; page_t* page; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] + = { 100, }; + ulint* offsets = offsets_; page = buf_frame_align(rec); @@ -2496,22 +2510,17 @@ btr_index_rec_validate( fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", (ulong) rec_get_n_fields_old(rec), (ulong) n); - if (!dump_on_error) { + if (dump_on_error) { + buf_page_print(page); - return(FALSE); + fputs("InnoDB: corrupt record ", stderr); + rec_print_old(stderr, rec); + putc('\n', stderr); } - - buf_page_print(page); - - fputs("InnoDB: corrupt record ", stderr); - rec_print_old(stderr, rec); - putc('\n', stderr); - return(FALSE); } - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); for (i = 0; i < n; i++) { dtype_t* type = dict_index_get_nth_type(index, i); @@ -2536,23 +2545,23 @@ btr_index_rec_validate( "InnoDB: field %lu len is %lu, should be %lu\n", (ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type)); - if (!dump_on_error) { - mem_heap_free(heap); - return(FALSE); + if (dump_on_error) { + buf_page_print(page); + + fputs("InnoDB: corrupt record ", stderr); + rec_print_new(stderr, rec, offsets); + putc('\n', stderr); + } + if (heap) { + mem_heap_free(heap); } - - buf_page_print(page); - - fputs("InnoDB: corrupt record ", stderr); - rec_print(stderr, rec, offsets); - putc('\n', stderr); - - mem_heap_free(heap); return(FALSE); } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } @@ -2677,8 +2686,8 @@ btr_validate_level( page_cur_move_to_next(&cursor); node_ptr = page_cur_get_rec(&cursor); - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); page = btr_node_ptr_get_child(node_ptr, offsets, &mtr); } @@ -2722,10 +2731,10 @@ loop: rec = page_rec_get_prev(page_get_supremum_rec(page)); right_rec = page_rec_get_next( page_get_infimum_rec(right_page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - offsets2 = rec_reget_offsets(right_rec, index, - offsets2, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, + offsets, ULINT_UNDEFINED, &heap); + offsets2 = rec_get_offsets(right_rec, index, + offsets2, ULINT_UNDEFINED, &heap); if (cmp_rec_rec(rec, right_rec, offsets, offsets2, dict_index_get_n_fields(index), index) >= 0) { @@ -2740,16 +2749,12 @@ loop: fputs("InnoDB: record ", stderr); rec = page_rec_get_prev(page_get_supremum_rec(page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); fputs("InnoDB: record ", stderr); rec = page_rec_get_next(page_get_infimum_rec( right_page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); ret = FALSE; @@ -2768,8 +2773,8 @@ loop: node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr); father_page = buf_frame_align(node_ptr); - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, + offsets, ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != buf_frame_get_page_no(page) @@ -2785,7 +2790,7 @@ loop: buf_page_print(page); fputs("InnoDB: node ptr ", stderr); - rec_print(stderr, node_ptr, offsets); + rec_print_new(stderr, node_ptr, offsets); fprintf(stderr, "\n" "InnoDB: node ptr child page n:o %lu\n", @@ -2796,9 +2801,7 @@ loop: rec = btr_page_get_father_for_rec(tree, page, page_rec_get_prev(page_get_supremum_rec(page)), &mtr); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); ret = FALSE; @@ -2806,8 +2809,8 @@ loop: } if (btr_page_get_level(page, &mtr) > 0) { - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, + offsets, ULINT_UNDEFINED, &heap); node_ptr_tuple = dict_tree_build_node_ptr( tree, @@ -2829,11 +2832,9 @@ loop: fputs("InnoDB: Error: node ptrs differ" " on levels > 0\n" "InnoDB: node ptr ", stderr); - rec_print(stderr, node_ptr, offsets); + rec_print_new(stderr, node_ptr, offsets); fputs("InnoDB: first rec ", stderr); - offsets = rec_reget_offsets(first_rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, first_rec, offsets); + rec_print(stderr, first_rec, index); putc('\n', stderr); ret = FALSE; diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index f5e146172ed..a3083e0e545 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -274,8 +274,9 @@ btr_cur_search_to_nth_level( #ifdef BTR_CUR_ADAPT btr_search_t* info; #endif - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; /* Currently, PAGE_CUR_LE is the only search mode used for searches ending to upper levels */ @@ -395,8 +396,6 @@ btr_cur_search_to_nth_level( break; } - heap = mem_heap_create(100); - offsets = NULL; /* Loop and search until we arrive at the desired level */ for (;;) { @@ -431,7 +430,9 @@ retry_page_get: cursor->thr)) { /* Insertion to the insert buffer succeeded */ cursor->flag = BTR_CUR_INSERT_TO_IBUF; - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return; } @@ -517,13 +518,15 @@ retry_page_get: guess = NULL; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (level == 0) { cursor->low_match = low_match; @@ -574,8 +577,9 @@ btr_cur_open_at_index_side( rec_t* node_ptr; ulint estimate; ulint savepoint; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; estimate = latch_mode & BTR_ESTIMATE; latch_mode = latch_mode & ~BTR_ESTIMATE; @@ -600,7 +604,6 @@ btr_cur_open_at_index_side( page_no = dict_tree_get_page(tree); height = ULINT_UNDEFINED; - heap = mem_heap_create(100); for (;;) { page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, @@ -670,13 +673,15 @@ btr_cur_open_at_index_side( height--; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /************************************************************************** @@ -697,8 +702,9 @@ btr_cur_open_at_rnd_pos( ulint space; ulint height; rec_t* node_ptr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; tree = index->tree; @@ -747,13 +753,15 @@ btr_cur_open_at_rnd_pos( height--; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*==================== B-TREE INSERT =========================*/ @@ -1242,11 +1250,14 @@ btr_cur_upd_lock_and_undo( err = DB_SUCCESS; if (!(flags & BTR_NO_LOCKING_FLAG)) { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; err = lock_clust_rec_modify_check_and_lock(flags, rec, index, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), - thr); - mem_heap_free(heap); + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), thr); + if (heap) { + mem_heap_free(heap); + } if (err != DB_SUCCESS) { return(err); @@ -1374,7 +1385,7 @@ btr_cur_parse_update_in_place( /* We do not need to reserve btr_search_latch, as the page is only being recovered, and there cannot be a hash index to it. */ - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_rec_sys_fields_in_recovery(rec, offsets, @@ -1413,18 +1424,19 @@ btr_cur_update_in_place( dulint roll_ptr = ut_dulint_zero; trx_t* trx; ibool was_delete_marked; - mem_heap_t* heap; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; rec = btr_cur_get_rec(cursor); index = cursor->index; trx = thr_get_trx(thr); heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(trx, index, "update "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } /* Do lock checking and undo logging */ @@ -1432,7 +1444,9 @@ btr_cur_update_in_place( thr, &roll_ptr); if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -1477,7 +1491,9 @@ btr_cur_update_in_place( btr_cur_unmark_extern_fields(rec, mtr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -1526,11 +1542,11 @@ btr_cur_optimistic_update( index = cursor->index; heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), index, "update "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), @@ -1646,8 +1662,8 @@ btr_cur_optimistic_update( /* The new inserted record owns its possible externally stored fields */ - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); btr_cur_unmark_extern_fields(rec, mtr, offsets); } @@ -1801,7 +1817,7 @@ btr_cur_pessimistic_update( } heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); trx = thr_get_trx(thr); @@ -1836,8 +1852,8 @@ btr_cur_pessimistic_update( ext_vect = mem_heap_alloc(heap, sizeof(ulint) * dict_index_get_n_fields(index)); ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update); if (rec_get_converted_size(index, new_entry) >= @@ -1877,8 +1893,8 @@ btr_cur_pessimistic_update( ut_a(rec || optim_err != DB_UNDERFLOW); if (rec) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); lock_rec_restore_from_page_infimum(rec, page); rec_set_field_extern_bits(rec, index, @@ -1918,8 +1934,7 @@ btr_cur_pessimistic_update( ut_a(dummy_big_rec == NULL); rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { /* The new inserted record owns its possible externally @@ -2048,12 +2063,15 @@ btr_cur_parse_del_mark_set_clust_rec( rec = page + offset; if (!(flags & BTR_KEEP_SYS_FLAG)) { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; row_upd_rec_sys_fields_in_recovery(rec, - rec_get_offsets(rec, index, - ULINT_UNDEFINED, heap), + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), pos, trx_id, roll_ptr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /* We do not need to reserve btr_search_latch, as the page @@ -2089,17 +2107,17 @@ btr_cur_del_mark_set_clust_rec( ulint err; rec_t* rec; trx_t* trx; - mem_heap_t* heap; - const ulint* offsets; - + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + rec = btr_cur_get_rec(cursor); index = cursor->index; - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), index, "del mark "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } ut_ad(index->type & DICT_CLUSTERED); @@ -2110,7 +2128,9 @@ btr_cur_del_mark_set_clust_rec( if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2119,7 +2139,9 @@ btr_cur_del_mark_set_clust_rec( &roll_ptr); if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2143,7 +2165,9 @@ btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, roll_ptr, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -2246,12 +2270,9 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { - mem_heap_t* heap = mem_heap_create(100); btr_cur_trx_report(thr_get_trx(thr), cursor->index, "del mark "); - rec_print(stderr, rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap)); - mem_heap_free(heap); + rec_print(stderr, rec, cursor->index); } err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, @@ -2375,9 +2396,10 @@ btr_cur_optimistic_delete( { page_t* page; ulint max_ins_size; - mem_heap_t* heap; rec_t* rec; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)), MTR_MEMO_PAGE_X_FIX)); @@ -2387,9 +2409,9 @@ btr_cur_optimistic_delete( ut_ad(btr_page_get_level(page, mtr) == 0); - heap = mem_heap_create(100); rec = btr_cur_get_rec(cursor); - offsets = rec_get_offsets(rec, cursor->index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); if (!rec_offs_any_extern(offsets) && btr_cur_can_delete_without_compress( @@ -2406,11 +2428,15 @@ btr_cur_optimistic_delete( ibuf_update_free_bits_low(cursor->index, page, max_ins_size, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(FALSE); } @@ -2487,8 +2513,9 @@ btr_cur_pessimistic_delete( : !rec_get_1byte_offs_flag(rec)) { btr_rec_free_externally_stored_fields(cursor->index, rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), + NULL, ULINT_UNDEFINED, &heap), in_rollback, mtr); + mem_heap_empty(heap); } if ((page_get_n_recs(page) < 2) @@ -2772,13 +2799,14 @@ btr_estimate_number_of_different_key_vals( ulint j; ulint add_on; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets1 = 0; - ulint* offsets2 = 0; + mem_heap_t* heap = NULL; + ulint offsets1_[100] = { 100, }; + ulint offsets2_[100] = { 100, }; + ulint* offsets1 = offsets1_; + ulint* offsets2 = offsets2_; n_cols = dict_index_get_n_unique(index); - heap = mem_heap_create(100); n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong)); for (j = 0; j <= n_cols; j++) { @@ -2813,10 +2841,10 @@ btr_estimate_number_of_different_key_vals( rec_t* next_rec = page_rec_get_next(rec); matched_fields = 0; matched_bytes = 0; - offsets1 = rec_reget_offsets(rec, index, - offsets1, ULINT_UNDEFINED, heap); - offsets2 = rec_reget_offsets(next_rec, index, - offsets2, n_cols, heap); + offsets1 = rec_get_offsets(rec, index, offsets1, + ULINT_UNDEFINED, &heap); + offsets2 = rec_get_offsets(next_rec, index, offsets2, + n_cols, &heap); cmp_rec_rec_with_match(rec, next_rec, offsets1, offsets2, @@ -2856,8 +2884,8 @@ btr_estimate_number_of_different_key_vals( } } - offsets1 = rec_reget_offsets(rec, index, - offsets1, ULINT_UNDEFINED, heap); + offsets1 = rec_get_offsets(rec, index, offsets1, + ULINT_UNDEFINED, &heap); total_external_size += btr_rec_get_externally_stored_len(rec, offsets1); @@ -2901,7 +2929,9 @@ btr_estimate_number_of_different_key_vals( } mem_free(n_diff); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/ diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c index 7df8e53cd07..ad7613e0655 100644 --- a/innobase/btr/btr0pcur.c +++ b/innobase/btr/btr0pcur.c @@ -262,9 +262,10 @@ btr_pcur_restore_position( heap = mem_heap_create(256); offsets1 = rec_get_offsets(cursor->old_rec, - index, ULINT_UNDEFINED, heap); - offsets2 = rec_get_offsets(rec, - index, ULINT_UNDEFINED, heap); + index, NULL, + cursor->old_n_fields, &heap); + offsets2 = rec_get_offsets(rec, index, NULL, + cursor->old_n_fields, &heap); ut_ad(cmp_rec_rec(cursor->old_rec, rec, offsets1, offsets2, @@ -310,7 +311,7 @@ btr_pcur_restore_position( && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), rec_get_offsets(btr_pcur_get_rec(cursor), btr_pcur_get_btr_cur(cursor)->index, - ULINT_UNDEFINED, heap))) { + NULL, ULINT_UNDEFINED, &heap))) { /* We have to store the NEW value for the modify clock, since the cursor can now be on a different page! But we can retain diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index c18fa9a923d..dc712f650e7 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -419,7 +419,9 @@ btr_search_update_hash_ref( && (block->curr_n_fields == info->n_fields) && (block->curr_n_bytes == info->n_bytes) && (block->curr_side == info->side)) { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + rec = btr_cur_get_rec(cursor); if (!page_rec_is_user_rec(rec)) { @@ -428,11 +430,13 @@ btr_search_update_hash_ref( } tree_id = ((cursor->index)->tree)->id; - heap = mem_heap_create(100); fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), block->curr_n_fields, + offsets_, ULINT_UNDEFINED, &heap), + block->curr_n_fields, block->curr_n_bytes, tree_id); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ @@ -547,8 +551,10 @@ btr_search_check_guess( ulint match; ulint bytes; int cmp; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ibool success = FALSE; n_unique = dict_index_get_n_unique_in_tree(cursor->index); @@ -560,47 +566,43 @@ btr_search_check_guess( match = 0; bytes = 0; - offsets = rec_get_offsets(rec, cursor->index, n_unique, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &match, &bytes); if (mode == PAGE_CUR_GE) { if (cmp == 1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->up_match = match; if (match >= n_unique) { - mem_heap_free(heap); - return(TRUE); + success = TRUE; + goto exit_func; } } else if (mode == PAGE_CUR_LE) { if (cmp == -1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->low_match = match; } else if (mode == PAGE_CUR_G) { if (cmp != -1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } } else if (mode == PAGE_CUR_L) { if (cmp != 1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } } if (can_only_compare_to_cursor_rec) { /* Since we could not determine if our guess is right just by looking at the record under the cursor, return FALSE */ - mem_heap_free(heap); - return(FALSE); + goto exit_func; } match = 0; @@ -613,28 +615,21 @@ btr_search_check_guess( prev_rec = page_rec_get_prev(rec); if (prev_rec == page_get_infimum_rec(page)) { - mem_heap_free(heap); - return(btr_page_get_prev(page, mtr) == FIL_NULL); + success = btr_page_get_prev(page, mtr) == FIL_NULL; + goto exit_func; } - offsets = rec_reget_offsets(prev_rec, cursor->index, - offsets, n_unique, heap); + offsets = rec_get_offsets(prev_rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec, offsets, &match, &bytes); - mem_heap_free(heap); if (mode == PAGE_CUR_GE) { - if (cmp != 1) { - - return(FALSE); - } + success = cmp == 1; } else { - if (cmp == -1) { - - return(FALSE); - } + success = cmp != -1; } - return(TRUE); + goto exit_func; } ut_ad(rec != page_get_supremum_rec(page)); @@ -642,39 +637,30 @@ btr_search_check_guess( next_rec = page_rec_get_next(rec); if (next_rec == page_get_supremum_rec(page)) { - mem_heap_free(heap); - if (btr_page_get_next(page, mtr) == FIL_NULL) { cursor->up_match = 0; - - return(TRUE); + success = TRUE; } - return(FALSE); + goto exit_func; } - offsets = rec_reget_offsets(next_rec, cursor->index, - offsets, n_unique, heap); + offsets = rec_get_offsets(next_rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &match, &bytes); - mem_heap_free(heap); - if (mode == PAGE_CUR_LE) { - if (cmp != -1) { - - return(FALSE); - } - + success = cmp == -1; cursor->up_match = match; } else { - if (cmp == 1) { - - return(FALSE); - } + success = cmp != 1; } - - return(TRUE); +exit_func: + if (heap) { + mem_heap_free(heap); + } + return(success); } /********************************************************************** @@ -997,14 +983,14 @@ btr_search_drop_page_hash_index( prev_fold = 0; - heap = mem_heap_create(100); + heap = NULL; offsets = NULL; while (rec != sup) { /* FIXME: in a mixed tree, not all records may have enough ordering fields: */ - offsets = rec_reget_offsets(rec, block->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, block->index, + offsets, n_fields + (n_bytes > 0), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); if (fold == prev_fold && prev_fold != 0) { @@ -1022,7 +1008,9 @@ next_rec: prev_fold = fold; } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } rw_lock_x_lock(&btr_search_latch); @@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index( ulint* folds; rec_t** recs; ulint i; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(index); @@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index( folds = mem_alloc(n_recs * sizeof(ulint)); recs = mem_alloc(n_recs * sizeof(rec_t*)); - heap = mem_heap_create(100); n_cached = 0; @@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); - offsets = rec_get_offsets(rec, index, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, index, offsets, + n_fields + (n_bytes > 0), &heap); if (rec != sup) { ut_a(n_fields <= rec_offs_n_fields(offsets)); @@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index( break; } - offsets = rec_reget_offsets(next_rec, index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(next_rec, index, offsets, + n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, tree_id); @@ -1260,7 +1249,9 @@ exit_func: mem_free(folds); mem_free(recs); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /************************************************************************ @@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete( ulint fold; dulint tree_id; ibool found; - mem_heap_t* heap; + ulint offsets_[100] = { 100, }; + mem_heap_t* heap = NULL; rec = btr_cur_get_rec(cursor); @@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete( table = btr_search_sys->hash_index; tree_id = cursor->index->tree->id; - heap = mem_heap_create(100); - fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), block->curr_n_fields, + fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_, + ULINT_UNDEFINED, &heap), block->curr_n_fields, block->curr_n_bytes, tree_id); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } rw_lock_x_lock(&btr_search_latch); found = ha_search_and_delete_if_found(table, fold, rec); @@ -1457,9 +1450,10 @@ btr_search_update_hash_on_insert( ulint n_fields; ulint n_bytes; ulint side; - ibool locked = FALSE; - mem_heap_t* heap; - ulint* offsets; + ibool locked = FALSE; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; table = btr_search_sys->hash_index; @@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert( next_rec = page_rec_get_next(ins_rec); page = buf_frame_align(rec); - heap = mem_heap_create(100); - offsets = rec_get_offsets(ins_rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(ins_rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id); if (next_rec != page_get_supremum_rec(page)) { - offsets = rec_reget_offsets(next_rec, cursor->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(next_rec, cursor->index, offsets, + n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, tree_id); } if (rec != page_get_infimum_rec(page)) { - offsets = rec_reget_offsets(rec, cursor->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + n_fields + (n_bytes > 0), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); } else { if (side == BTR_SEARCH_LEFT_SIDE) { @@ -1575,7 +1568,9 @@ check_next_rec: } function_exit: - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (locked) { rw_lock_x_unlock(&btr_search_latch); } @@ -1595,8 +1590,9 @@ btr_search_validate(void) ulint n_page_dumps = 0; ibool ok = TRUE; ulint i; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; rw_lock_x_lock(&btr_search_latch); @@ -1606,10 +1602,10 @@ btr_search_validate(void) while (node != NULL) { block = buf_block_align(node->data); page = buf_frame_align(node->data); - offsets = rec_reget_offsets((rec_t*) node->data, + offsets = rec_get_offsets((rec_t*) node->data, block->index, offsets, block->curr_n_fields - + (block->curr_n_bytes > 0), heap); + + (block->curr_n_bytes > 0), &heap); if (!block->is_hashed || node->fold != rec_fold((rec_t*)(node->data), @@ -1635,7 +1631,8 @@ btr_search_validate(void) btr_page_get_index_id(page))); fputs("InnoDB: Record ", stderr); - rec_print(stderr, (rec_t*)node->data, offsets); + rec_print_new(stderr, (rec_t*)node->data, + offsets); fprintf(stderr, "\nInnoDB: on that page." "Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n" "side %lu\n", @@ -1659,7 +1656,9 @@ btr_search_validate(void) } rw_lock_x_unlock(&btr_search_latch); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(ok); } diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index b99359fe998..e533ac08545 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -345,6 +345,33 @@ lock_clust_rec_read_check_and_lock( LOCK_REC_NOT_GAP */ que_thr_t* thr); /* in: query thread */ /************************************************************************* +Checks if locks of other transactions prevent an immediate read, or passing +over by a read cursor, of a clustered index record. If they do, first tests +if the query thread should anyway be suspended for some reason; if not, then +puts the transaction and the query thread to the lock wait state and inserts a +waiting request for a record lock to the lock queue. Sets the requested mode +lock on the record. This is an alternative version of +lock_clust_rec_read_check_and_lock() that does not require the parameter +"offsets". */ + +ulint +lock_clust_rec_read_check_and_lock_alt( +/*===================================*/ + /* out: DB_SUCCESS, DB_LOCK_WAIT, + DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, + does nothing */ + rec_t* rec, /* in: user record or page supremum record + which should be read or passed over by a read + cursor */ + dict_index_t* index, /* in: clustered index */ + ulint mode, /* in: mode of the lock which the read cursor + should set on records: LOCK_S or LOCK_X; the + latter is possible in SELECT FOR UPDATE */ + ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or + LOCK_REC_NOT_GAP */ + que_thr_t* thr); /* in: query thread */ +/************************************************************************* Checks that a record is seen in a consistent read. */ ibool diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h index d450df82311..ab89b912523 100644 --- a/innobase/include/rem0rec.h +++ b/innobase/include/rem0rec.h @@ -67,6 +67,16 @@ rec_get_n_fields_old( /* out: number of data fields */ rec_t* rec); /* in: physical record */ /********************************************************** +The following function is used to get the number of fields +in a record. */ +UNIV_INLINE +ulint +rec_get_n_fields( +/*=============*/ + /* out: number of data fields */ + rec_t* rec, /* in: physical record */ + dict_index_t* index); /* in: record descriptor */ +/********************************************************** The following function is used to get the number of records owned by the previous directory record. */ UNIV_INLINE @@ -188,45 +198,28 @@ rec_get_1byte_offs_flag( rec_t* rec); /* in: physical record */ /********************************************************** The following function determines the offsets to each field -in the record. The offsets are returned in an array of -ulint, with [0] being the number of fields (n), [1] being the -extra size (if REC_OFFS_COMPACT is set, the record is in the new -format), and [2]..[n+1] being the offsets past the end of -fields 0..n, or to the beginning of fields 1..n+1. When the -high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL), -the field n is NULL. When the second high-order bit of the offset -at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored -externally. */ +in the record. It can reuse a previously allocated array. */ ulint* -rec_get_offsets( -/*============*/ - /* out: the offsets */ - rec_t* rec, /* in: physical record */ - dict_index_t* index, /* in: record descriptor */ - ulint n_fields,/* in: maximum number of initialized fields - (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap); /* in: memory heap */ -/********************************************************** -The following function determines the offsets to each field -in the record. It differs from rec_get_offsets() by trying to -reuse a previously returned array. */ - -ulint* -rec_reget_offsets( -/*==============*/ +rec_get_offsets_func( +/*=================*/ /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array of offsets - from rec_get_offsets() - or rec_reget_offsets(), or NULL */ + ulint* offsets,/* in: array consisting of offsets[0] + allocated elements, or an array from + rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap); /* in: memory heap */ + mem_heap_t** heap, /* in/out: memory heap */ + const char* file, /* in: file name where called */ + ulint line); /* in: line number where called */ + +#define rec_get_offsets(rec,index,offsets,n,heap) \ + rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__) /**************************************************************** -Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ +Validates offsets returned by rec_get_offsets(). */ UNIV_INLINE ibool rec_offs_validate( @@ -234,8 +227,7 @@ rec_offs_validate( /* out: TRUE if valid */ rec_t* rec, /* in: record or NULL */ dict_index_t* index, /* in: record descriptor or NULL */ - const ulint* offsets);/* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + const ulint* offsets);/* in: array returned by rec_get_offsets() */ /**************************************************************** Updates debug data in offsets, in order to avoid bogus rec_offs_validate() failures. */ @@ -243,10 +235,9 @@ UNIV_INLINE void rec_offs_make_valid( /*================*/ - const rec_t* rec, /* in: record */ - const dict_index_t* index,/* in: record descriptor */ - ulint* offsets);/* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + rec_t* rec, /* in: record */ + dict_index_t* index,/* in: record descriptor */ + ulint* offsets);/* in: array returned by rec_get_offsets() */ /**************************************************************** The following function is used to get a pointer to the nth @@ -551,7 +542,15 @@ rec_print_old( /*==========*/ FILE* file, /* in: file where to print */ rec_t* rec); /* in: physical record */ +/******************************************************************* +Prints a physical record. */ +void +rec_print_new( +/*==========*/ + FILE* file, /* in: file where to print */ + rec_t* rec, /* in: physical record */ + const ulint* offsets);/* in: array returned by rec_get_offsets() */ /******************************************************************* Prints a physical record. */ @@ -560,7 +559,7 @@ rec_print( /*======*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ - const ulint* offsets);/* in: array returned by rec_get_offsets() */ + dict_index_t* index); /* in: record descriptor */ #define REC_INFO_BITS 6 /* This is single byte bit-field */ diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 8443b5fa07d..db938aa9fa5 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -681,9 +681,11 @@ rec_2_get_field_end_info( } #ifdef UNIV_DEBUG -# define REC_OFFS_HEADER_SIZE 3 +/* Length of the rec_get_offsets() header */ +# define REC_OFFS_HEADER_SIZE 4 #else /* UNIV_DEBUG */ -# define REC_OFFS_HEADER_SIZE 1 +/* Length of the rec_get_offsets() header */ +# define REC_OFFS_HEADER_SIZE 2 #endif /* UNIV_DEBUG */ /* Get the base address of offsets. The extra_size is stored at @@ -691,8 +693,40 @@ this position, and following positions hold the end offsets of the fields. */ #define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE) +/************************************************************** +The following function returns the number of allocated elements +for an array of offsets. */ +UNIV_INLINE +ulint +rec_offs_get_n_alloc( +/*=================*/ + /* out: number of elements */ + const ulint* offsets)/* in: array for rec_get_offsets() */ +{ + ulint n_alloc; + ut_ad(offsets); + n_alloc = offsets[0]; + ut_ad(n_alloc > 0); + return(n_alloc); +} + +/************************************************************** +The following function sets the number of allocated elements +for an array of offsets. */ +UNIV_INLINE +void +rec_offs_set_n_alloc( +/*=================*/ + ulint* offsets, /* in: array for rec_get_offsets() */ + ulint n_alloc) /* in: number of elements */ +{ + ut_ad(offsets); + ut_ad(n_alloc > 0); + offsets[0] = n_alloc; +} + /**************************************************************** -Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ +Validates offsets returned by rec_get_offsets(). */ UNIV_INLINE ibool rec_offs_validate( @@ -705,16 +739,16 @@ rec_offs_validate( ulint i = rec_offs_n_fields(offsets); ulint last = ULINT_MAX; ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0; - ut_a(offsets); + if (rec) { - ut_ad((ulint) rec == offsets[1]); + ut_ad((ulint) rec == offsets[2]); if (!comp) { ut_a(rec_get_n_fields_old(rec) >= i); } } if (index) { ulint max_n_fields; - ut_ad((ulint) index == offsets[2]); + ut_ad((ulint) index == offsets[3]); max_n_fields = ut_max( dict_index_get_n_fields(index), dict_index_get_n_unique_in_tree(index) + 1); @@ -734,7 +768,9 @@ rec_offs_validate( ut_error; } } - ut_a(i <= max_n_fields); + /* index->n_def == 0 for dummy indexes if !comp */ + ut_a(!comp || index->n_def); + ut_a(!index->n_def || i <= max_n_fields); } while (i--) { ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK; @@ -750,17 +786,17 @@ UNIV_INLINE void rec_offs_make_valid( /*================*/ - const rec_t* rec __attribute__((unused)), + rec_t* rec __attribute__((unused)), /* in: record */ - const dict_index_t* index __attribute__((unused)), + dict_index_t* index __attribute__((unused)), /* in: record descriptor */ ulint* offsets __attribute__((unused))) - /* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + /* in: array returned by rec_get_offsets() */ { #ifdef UNIV_DEBUG - offsets[1] = (ulint) rec; - offsets[2] = (ulint) index; + ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets)); + offsets[2] = (ulint) rec; + offsets[3] = (ulint) index; #endif /* UNIV_DEBUG */ } @@ -1146,12 +1182,31 @@ rec_offs_n_fields( { ulint n_fields; ut_ad(offsets); - n_fields = offsets[0]; + n_fields = offsets[1]; ut_ad(n_fields > 0); ut_ad(n_fields <= REC_MAX_N_FIELDS); + ut_ad(n_fields + REC_OFFS_HEADER_SIZE + <= rec_offs_get_n_alloc(offsets)); return(n_fields); } +/************************************************************** +The following function sets the number of fields in offsets. */ +UNIV_INLINE +void +rec_offs_set_n_fields( +/*==================*/ + ulint* offsets, /* in: array returned by rec_get_offsets() */ + ulint n_fields) /* in: number of fields */ +{ + ut_ad(offsets); + ut_ad(n_fields > 0); + ut_ad(n_fields <= REC_MAX_N_FIELDS); + ut_ad(n_fields + REC_OFFS_HEADER_SIZE + <= rec_offs_get_n_alloc(offsets)); + offsets[1] = n_fields; +} + /************************************************************** The following function returns the data size of a physical record, that is the sum of field lengths. SQL null fields diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index d2d16a1ae4e..70075019389 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -424,7 +424,7 @@ lock_check_trx_id_sanity( /* out: TRUE if ok */ dulint trx_id, /* in: trx id */ rec_t* rec, /* in: user record */ - dict_index_t* index, /* in: clustered index */ + dict_index_t* index, /* in: index */ const ulint* offsets, /* in: rec_get_offsets(rec, index) */ ibool has_kernel_mutex)/* in: TRUE if the caller owns the kernel mutex */ @@ -445,7 +445,7 @@ lock_check_trx_id_sanity( fputs(" InnoDB: Error: transaction id associated" " with record\n", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fputs("InnoDB: in ", stderr); dict_index_name_print(stderr, NULL, index); fprintf(stderr, "\n" @@ -4073,10 +4073,9 @@ lock_rec_print( ulint page_no; ulint i; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; - - heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -4157,9 +4156,9 @@ lock_rec_print( if (page) { rec_t* rec = page_find_rec_with_heap_no(page, i); - offsets = rec_reget_offsets(rec, lock->index, - offsets, ULINT_UNDEFINED, heap); - rec_print(file, rec, offsets); + offsets = rec_get_offsets(rec, lock->index, + offsets, ULINT_UNDEFINED, &heap); + rec_print_new(file, rec, offsets); } putc('\n', file); @@ -4167,9 +4166,11 @@ lock_rec_print( } mtr_commit(&mtr); - mem_heap_free(heap); -} - + if (heap) { + mem_heap_free(heap); + } +} + /************************************************************************* Calculates the number of record lock structs in the record lock hash table. */ static @@ -4562,12 +4563,13 @@ lock_rec_validate_page( page_t* page; lock_t* lock; rec_t* rec; - ulint nth_lock = 0; - ulint nth_bit = 0; + ulint nth_lock = 0; + ulint nth_bit = 0; ulint i; mtr_t mtr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; #ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); @@ -4607,8 +4609,8 @@ loop: index = lock->index; rec = page_find_rec_with_heap_no(page, i); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); fprintf(stderr, "Validating %lu %lu\n", (ulong) space, (ulong) page_no); @@ -4635,7 +4637,9 @@ function_exit: mtr_commit(&mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } @@ -4811,11 +4815,15 @@ lock_rec_insert_check_and_lock( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - const ulint* offsets = rec_get_offsets(next_rec, index, - ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + const ulint* offsets = rec_get_offsets( + next_rec, index, offsets_, + ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate(next_rec, index, offsets)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ @@ -4954,11 +4962,14 @@ lock_sec_rec_modify_check_and_lock( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - const ulint* offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + const ulint* offsets = rec_get_offsets( + rec, index, offsets_, ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate(rec, index, offsets)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ @@ -5067,7 +5078,6 @@ lock_clust_rec_read_check_and_lock( ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP || gap_mode == LOCK_REC_NOT_GAP); - ut_ad(index->type & DICT_CLUSTERED); ut_ad(rec_offs_validate(rec, index, offsets)); if (flags & BTR_NO_LOCKING_FLAG) { @@ -5095,3 +5105,45 @@ lock_clust_rec_read_check_and_lock( return(err); } +/************************************************************************* +Checks if locks of other transactions prevent an immediate read, or passing +over by a read cursor, of a clustered index record. If they do, first tests +if the query thread should anyway be suspended for some reason; if not, then +puts the transaction and the query thread to the lock wait state and inserts a +waiting request for a record lock to the lock queue. Sets the requested mode +lock on the record. This is an alternative version of +lock_clust_rec_read_check_and_lock() that does not require the parameter +"offsets". */ + +ulint +lock_clust_rec_read_check_and_lock_alt( +/*===================================*/ + /* out: DB_SUCCESS, DB_LOCK_WAIT, + DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, + does nothing */ + rec_t* rec, /* in: user record or page supremum record + which should be read or passed over by a read + cursor */ + dict_index_t* index, /* in: clustered index */ + ulint mode, /* in: mode of the lock which the read cursor + should set on records: LOCK_S or LOCK_X; the + latter is possible in SELECT FOR UPDATE */ + ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or + LOCK_REC_NOT_GAP */ + que_thr_t* thr) /* in: query thread */ +{ + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ulint ret; + + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); + ret = lock_clust_rec_read_check_and_lock(flags, rec, index, + offsets, mode, gap_mode, thr); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } + return(ret); +} diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 8def8474d9a..53c3c573b8e 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -29,6 +29,7 @@ UNIV_INLINE ibool page_cur_try_search_shortcut( /*=========================*/ + /* out: TRUE on success */ page_t* page, /* in: index page */ dict_index_t* index, /* in: record descriptor */ dtuple_t* tuple, /* in: data tuple */ @@ -56,14 +57,15 @@ page_cur_try_search_shortcut( #ifdef UNIV_SEARCH_DEBUG page_cur_t cursor2; #endif - mem_heap_t* heap; - ulint* offsets; + ibool success = FALSE; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(dtuple_check_typed(tuple)); rec = page_header_get_ptr(page, PAGE_LAST_INSERT); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, - dtuple_get_n_fields(tuple), heap); + offsets = rec_get_offsets(rec, index, offsets, + dtuple_get_n_fields(tuple), &heap); ut_ad(rec); ut_ad(page_rec_is_user_rec(rec)); @@ -78,21 +80,17 @@ page_cur_try_search_shortcut( cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes); if (cmp == -1) { - - mem_heap_free(heap); - return(FALSE); + goto exit_func; } next_rec = page_rec_get_next(rec); - offsets = rec_reget_offsets(next_rec, index, offsets, - dtuple_get_n_fields(tuple), heap); + offsets = rec_get_offsets(next_rec, index, offsets, + dtuple_get_n_fields(tuple), &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes); if (cmp != -1) { - - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->rec = rec; @@ -127,8 +125,12 @@ page_cur_try_search_shortcut( #ifdef UNIV_SEARCH_PERF_STAT page_cur_short_succ++; #endif - mem_heap_free(heap); - return(TRUE); + success = TRUE; +exit_func: + if (heap) { + mem_heap_free(heap); + } + return(success); } #endif @@ -226,8 +228,9 @@ page_cur_search_with_match( ulint dbg_matched_fields; ulint dbg_matched_bytes; #endif - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes && ilow_matched_fields && ilow_matched_bytes && cursor); @@ -262,8 +265,6 @@ page_cur_search_with_match( /*#endif */ #endif - heap = mem_heap_create(100); - /* The following flag does not work for non-latin1 char sets because cmp_full_field does not tell how many bytes matched */ ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); @@ -298,8 +299,8 @@ page_cur_search_with_match( low_matched_fields, low_matched_bytes, up_matched_fields, up_matched_bytes); - offsets = rec_reget_offsets(mid_rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, @@ -310,8 +311,8 @@ page_cur_search_with_match( low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, @@ -353,8 +354,8 @@ page_cur_search_with_match( low_matched_fields, low_matched_bytes, up_matched_fields, up_matched_bytes); - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, @@ -365,8 +366,8 @@ page_cur_search_with_match( low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, @@ -398,8 +399,8 @@ page_cur_search_with_match( dbg_matched_fields = 0; dbg_matched_bytes = 0; - offsets = rec_reget_offsets(low_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(low_rec, index, offsets, + ULINT_UNDEFINED, &heap); dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets, &dbg_matched_fields, &dbg_matched_bytes); @@ -422,8 +423,8 @@ page_cur_search_with_match( dbg_matched_fields = 0; dbg_matched_bytes = 0; - offsets = rec_reget_offsets(up_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(up_rec, index, offsets, + ULINT_UNDEFINED, &heap); dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets, &dbg_matched_fields, &dbg_matched_bytes); @@ -453,7 +454,9 @@ page_cur_search_with_match( *iup_matched_bytes = up_matched_bytes; *ilow_matched_fields = low_matched_fields; *ilow_matched_bytes = low_matched_bytes; - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*************************************************************** @@ -519,22 +522,26 @@ page_cur_insert_rec_write_log( ut_a(rec_size < UNIV_PAGE_SIZE); { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint cur_offs_[100] = { 100, }; + ulint ins_offs_[100] = { 100, }; + ulint* cur_offs; ulint* ins_offs; - heap = mem_heap_create(100); - cur_offs = rec_get_offsets(cursor_rec, index, - ULINT_UNDEFINED, heap); - ins_offs = rec_get_offsets(insert_rec, index, - ULINT_UNDEFINED, heap); + cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_, + ULINT_UNDEFINED, &heap); + ins_offs = rec_get_offsets(insert_rec, index, ins_offs_, + ULINT_UNDEFINED, &heap); extra_size = rec_offs_extra_size(ins_offs); cur_extra_size = rec_offs_extra_size(cur_offs); ut_ad(rec_size == rec_offs_size(ins_offs)); cur_rec_size = rec_offs_size(cur_offs); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } ins_ptr = insert_rec - extra_size; @@ -668,8 +675,9 @@ page_cur_parse_insert_rec( byte* ptr2 = ptr; ulint info_bits = 0; /* remove warning */ page_cur_t cursor; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; if (!is_short) { /* Read the cursor rec offset as a 2-byte ulint */ @@ -756,8 +764,8 @@ page_cur_parse_insert_rec( cursor_rec = page + offset; } - heap = mem_heap_create(100); - offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cursor_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (extra_info_yes == 0) { info_bits = rec_get_info_bits(cursor_rec, index->table->comp); @@ -816,6 +824,10 @@ page_cur_parse_insert_rec( mem_free(buf); } + if (heap) { + mem_heap_free(heap); + } + return(ptr + end_seg_len); } @@ -850,8 +862,9 @@ page_cur_insert_rec_low( inserted record */ rec_t* owner_rec; ulint n_owned; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ibool comp = index->table->comp; ut_ad(cursor && mtr); @@ -865,14 +878,12 @@ page_cur_insert_rec_low( ut_ad(cursor->rec != page_get_supremum_rec(page)); - heap = mem_heap_create(100); - /* 1. Get the size of the physical record in the page */ if (tuple != NULL) { - offsets = NULL; rec_size = rec_get_converted_size(index, tuple); } else { - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); rec_size = rec_offs_size(offsets); } @@ -880,7 +891,9 @@ page_cur_insert_rec_low( insert_buf = page_mem_alloc(page, rec_size, index, &heap_no); if (insert_buf == NULL) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(NULL); } @@ -888,13 +901,15 @@ page_cur_insert_rec_low( if (tuple != NULL) { insert_rec = rec_convert_dtuple_to_rec(insert_buf, index, tuple); + offsets = rec_get_offsets(insert_rec, index, offsets, + ULINT_UNDEFINED, &heap); } else { insert_rec = rec_copy(insert_buf, rec, offsets); + ut_ad(rec_offs_validate(rec, index, offsets)); + rec_offs_make_valid(insert_rec, index, offsets); } ut_ad(insert_rec); - offsets = rec_reget_offsets(insert_rec, index, - offsets, ULINT_UNDEFINED, heap); ut_ad(rec_size == rec_offs_size(offsets)); /* 4. Insert the record in the linked list of records */ @@ -966,7 +981,9 @@ page_cur_insert_rec_low( page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec, index, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(insert_rec); } @@ -1068,9 +1085,10 @@ page_copy_rec_list_end_to_created_page( ulint log_mode; byte* log_ptr; ulint log_data_len; - ibool comp = page_is_comp(page); - mem_heap_t* heap; - ulint* offsets = NULL; + ibool comp = page_is_comp(page); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(page_dir_get_n_heap(new_page) == 2); ut_ad(page != new_page); @@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page( /* should be do ... until, comment by Jani */ while (rec != page_get_supremum_rec(page)) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); insert_rec = rec_copy(heap_top, rec, offsets); rec_set_next_offs(prev_rec, comp, insert_rec - new_page); @@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page( slot_index--; } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len; diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 38b1e503c8f..67c7bd936d1 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -227,10 +227,12 @@ page_mem_alloc( rec = page_header_get_ptr(page, PAGE_FREE); if (rec) { - mem_heap_t* heap - = mem_heap_create(100); - const ulint* offsets - = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (rec_offs_size(offsets) >= need) { page_header_set_ptr(page, PAGE_FREE, @@ -245,11 +247,15 @@ page_mem_alloc( *heap_no = rec_get_heap_no(rec, page_is_comp(page)); block = rec_get_start(rec, offsets); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(block); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /* Could not find space from the free list, try top of heap */ @@ -374,7 +380,8 @@ page_create( rec_set_n_owned(infimum_rec, comp, 1); rec_set_heap_no(infimum_rec, comp, 0); - offsets = rec_get_offsets(infimum_rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(infimum_rec, index, NULL, + ULINT_UNDEFINED, &heap); heap_top = rec_get_end(infimum_rec, offsets); @@ -396,8 +403,8 @@ page_create( rec_set_n_owned(supremum_rec, comp, 1); rec_set_heap_no(supremum_rec, comp, 1); - offsets = rec_reget_offsets(supremum_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(supremum_rec, index, offsets, + ULINT_UNDEFINED, &heap); heap_top = rec_get_end(supremum_rec, offsets); ut_ad(heap_top == @@ -711,8 +718,9 @@ page_delete_rec_list_end( last_rec = page_rec_get_prev(sup); if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) { - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; /* Calculate the sum of sizes and the number of records */ size = 0; n_recs = 0; @@ -720,8 +728,8 @@ page_delete_rec_list_end( while (rec2 != sup) { ulint s; - offsets = rec_reget_offsets(rec2, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec2, index, offsets, + ULINT_UNDEFINED, &heap); s = rec_offs_size(offsets); ut_ad(rec2 - page + s - rec_offs_extra_size(offsets) < UNIV_PAGE_SIZE); @@ -732,7 +740,9 @@ page_delete_rec_list_end( rec2 = page_rec_get_next(rec2); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } ut_ad(size < UNIV_PAGE_SIZE); @@ -1213,7 +1223,7 @@ page_rec_print( ibool comp = page_is_comp(buf_frame_align(rec)); ut_a(comp == rec_offs_comp(offsets)); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fprintf(stderr, " n_owned: %lu; heap_no: %lu; next rec: %lu\n", (ulong) rec_get_n_owned(rec, comp), @@ -1276,11 +1286,11 @@ page_print_list( page_cur_t cur; ulint count; ulint n_recs; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(page_is_comp(page) == index->table->comp); - heap = mem_heap_create(100); fprintf(stderr, "--------------------------------\n" @@ -1292,8 +1302,8 @@ page_print_list( page_cur_set_before_first(page, &cur); count = 0; for (;;) { - offsets = rec_reget_offsets(cur.rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cur.rec, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(cur.rec, offsets); if (count == pr_n) { @@ -1314,8 +1324,8 @@ page_print_list( page_cur_move_to_next(&cur); if (count + pr_n >= n_recs) { - offsets = rec_reget_offsets(cur.rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cur.rec, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(cur.rec, offsets); } count++; @@ -1326,7 +1336,9 @@ page_print_list( "--------------------------------\n", (ulong) (count + 1)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /******************************************************************* @@ -1680,7 +1692,7 @@ page_validate( goto func_exit2; } - heap = mem_heap_create(UNIV_PAGE_SIZE); + heap = mem_heap_create(UNIV_PAGE_SIZE + 200); /* The following buffer is used to check that the records in the page record heap do not overlap */ @@ -1720,8 +1732,8 @@ page_validate( for (;;) { rec = cur.rec; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (comp && page_rec_is_user_rec(rec) && rec_get_node_ptr_flag(rec) @@ -1744,9 +1756,9 @@ page_validate( (ulong) buf_frame_get_page_no(page)); dict_index_name_print(stderr, NULL, index); fputs("\nInnoDB: previous record ", stderr); - rec_print(stderr, old_rec, old_offsets); + rec_print_new(stderr, old_rec, old_offsets); fputs("\nInnoDB: record ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); goto func_exit; @@ -1852,8 +1864,8 @@ page_validate( rec = page_header_get_ptr(page, PAGE_FREE); while (rec != NULL) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (!page_rec_validate(rec, offsets)) { goto func_exit; diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c index e4fa213480f..74876ad9402 100644 --- a/innobase/rem/rem0rec.c +++ b/innobase/rem/rem0rec.c @@ -284,86 +284,25 @@ rec_init_offsets( /********************************************************** The following function determines the offsets to each field -in the record. The offsets are returned in an array of -ulint, with [0] being the number of fields (n), [1] being the -extra size (if REC_OFFS_COMPACT is set, the record is in the new -format), and [2]..[n+1] being the offsets past the end of -fields 0..n, or to the beginning of fields 1..n+1. When the -high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL), -the field n is NULL. When the second high-order bit of the offset -at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored -externally. */ +in the record. It can reuse a previously returned array. */ ulint* -rec_get_offsets( -/*============*/ - /* out: the offsets */ - rec_t* rec, /* in: physical record */ - dict_index_t* index, /* in: record descriptor */ - ulint n_fields,/* in: maximum number of initialized fields - (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap) /* in: memory heap */ -{ - ulint* offsets; - ulint n; - - ut_ad(rec); - ut_ad(index); - ut_ad(heap); - - if (index->table->comp) { - switch (rec_get_status(rec)) { - case REC_STATUS_ORDINARY: - n = dict_index_get_n_fields(index); - break; - case REC_STATUS_NODE_PTR: - n = dict_index_get_n_unique_in_tree(index) + 1; - break; - case REC_STATUS_INFIMUM: - case REC_STATUS_SUPREMUM: - /* infimum or supremum record */ - n = 1; - break; - default: - ut_error; - return(NULL); - } - } else { - n = rec_get_n_fields_old(rec); - } - - if (n_fields < n) { - n = n_fields; - } - - offsets = mem_heap_alloc(heap, - (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint)); - - offsets[0] = n; - - rec_init_offsets(rec, index, offsets); - return(offsets); -} - -/********************************************************** -The following function determines the offsets to each field -in the record. It differs from rec_get_offsets() by trying to -reuse a previously returned array. */ - -ulint* -rec_reget_offsets( -/*==============*/ +rec_get_offsets_func( +/*=================*/ /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array of offsets - from rec_get_offsets() - or rec_reget_offsets(), or NULL */ + ulint* offsets,/* in: array consisting of offsets[0] + allocated elements, or an array from + rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap) /* in: memory heap */ + mem_heap_t** heap, /* in/out: memory heap */ + const char* file, /* in: file name where called */ + ulint line) /* in: line number where called */ { ulint n; + ulint size; ut_ad(rec); ut_ad(index); @@ -394,13 +333,18 @@ rec_reget_offsets( n = n_fields; } - if (!offsets || rec_offs_n_fields(offsets) < n) { - offsets = mem_heap_alloc(heap, - (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint)); + size = (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint); + + if (!offsets || rec_offs_get_n_alloc(offsets) < size) { + if (!*heap) { + *heap = mem_heap_create_func(size, + NULL, MEM_HEAP_DYNAMIC, file, line); + } + offsets = mem_heap_alloc(*heap, size); + rec_offs_set_n_alloc(offsets, size); } - offsets[0] = n; - + rec_offs_set_n_fields(offsets, n); rec_init_offsets(rec, index, offsets); return(offsets); } @@ -722,14 +666,16 @@ rec_get_size( rec_t* rec, /* in: physical record */ dict_index_t* index) /* in: record descriptor */ { - mem_heap_t* heap - = mem_heap_create(100); - ulint* offsets - = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); - ulint size - = rec_offs_size(offsets); + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + ulint* offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); + ulint size = rec_offs_size(offsets); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(size); } @@ -1032,10 +978,15 @@ rec_convert_dtuple_to_rec( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - ut_ad(rec_validate(rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap))); - mem_heap_free(heap); + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + const ulint* offsets = rec_get_offsets(rec, index, + offsets_, ULINT_UNDEFINED, &heap); + ut_ad(rec_validate(rec, offsets)); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ return(rec); @@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple( ulint len; byte* buf = NULL; ulint i; - ulint* offsets; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + ulint* offsets = offsets_; - offsets = rec_get_offsets(rec, index, n_fields, heap); + offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap); ut_ad(rec_validate(rec, offsets)); ut_ad(dtuple_check_typed(tuple)); @@ -1406,8 +1359,8 @@ rec_print_old( Prints a physical record. */ void -rec_print( -/*======*/ +rec_print_new( +/*==========*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */ @@ -1416,6 +1369,8 @@ rec_print( ulint len; ulint i; + ut_ad(rec_offs_validate(rec, NULL, offsets)); + if (!rec_offs_comp(offsets)) { rec_print_old(file, rec); return; @@ -1453,3 +1408,30 @@ rec_print( rec_validate(rec, offsets); } + +/******************************************************************* +Prints a physical record. */ + +void +rec_print( +/*======*/ + FILE* file, /* in: file where to print */ + rec_t* rec, /* in: physical record */ + dict_index_t* index) /* in: record descriptor */ +{ + ut_ad(index); + + if (!index->table->comp) { + rec_print_old(file, rec); + return; + } else { + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap)); + if (heap) { + mem_heap_free(heap); + } + } +} diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index a87a08fa3fe..8b19f9d9a11 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -590,16 +590,8 @@ row_ins_foreign_report_err( fputs(", in index ", ef); ut_print_name(ef, trx, foreign->foreign_index->name); if (rec) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, foreign->foreign_index, - ULINT_UNDEFINED, heap); - fputs(", there is a record:\n", ef); - rec_print(ef, rec, offsets); - mem_heap_free(heap); + rec_print(ef, rec, foreign->foreign_index); } else { fputs(", the record is not available\n", ef); } @@ -654,16 +646,7 @@ row_ins_foreign_report_add_err( } if (rec) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, foreign->foreign_index, - ULINT_UNDEFINED, heap); - - rec_print(ef, rec, offsets); - - mem_heap_free(heap); + rec_print(ef, rec, foreign->foreign_index); } putc('\n', ef); @@ -734,7 +717,6 @@ row_ins_foreign_check_on_constraint( ulint i; trx_t* trx; mem_heap_t* tmp_heap = NULL; - ulint* offsets; ut_a(thr && foreign && pcur && mtr); @@ -880,14 +862,10 @@ row_ins_foreign_check_on_constraint( fputs("\n" "InnoDB: record ", stderr); - offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, tmp_heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); fputs("\n" "InnoDB: clustered record ", stderr); - offsets = rec_reget_offsets(clust_rec, clust_index, - offsets, ULINT_UNDEFINED, tmp_heap); - rec_print(stderr, clust_rec, offsets); + rec_print(stderr, clust_rec, clust_index); fputs("\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); @@ -906,13 +884,8 @@ row_ins_foreign_check_on_constraint( we already have a normal shared lock on the appropriate gap if the search criterion was not unique */ - if (!tmp_heap) { - tmp_heap = mem_heap_create(256); - } - offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, tmp_heap); - err = lock_clust_rec_read_check_and_lock(0, clust_rec, - clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr); + err = lock_clust_rec_read_check_and_lock_alt(0, clust_rec, + clust_index, LOCK_X, LOCK_REC_NOT_GAP, thr); } if (err != DB_SUCCESS) { @@ -1152,11 +1125,10 @@ row_ins_check_foreign_constraint( ulint err; ulint i; mtr_t mtr; - trx_t* trx = thr_get_trx(thr); - mem_heap_t* heap; - ulint* offsets = NULL; - - heap = mem_heap_create(100); + trx_t* trx = thr_get_trx(thr); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; run_again: #ifdef UNIV_SYNC_DEBUG @@ -1168,8 +1140,7 @@ run_again: if (trx->check_foreigns == FALSE) { /* The user has suppressed foreign key checks currently for this session */ - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } /* If any of the foreign key fields in entry is SQL NULL, we @@ -1180,8 +1151,7 @@ run_again: if (UNIV_SQL_NULL == dfield_get_len( dtuple_get_nth_field(entry, i))) { - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } } @@ -1205,8 +1175,7 @@ run_again: another, and the user has problems predicting in which order they are performed. */ - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } } @@ -1219,8 +1188,6 @@ run_again: } if (check_table == NULL) { - mem_heap_free(heap); - if (check_ref) { FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); @@ -1242,10 +1209,10 @@ run_again: fputs(" does not currently exist!\n", ef); mutex_exit(&dict_foreign_err_mutex); - return(DB_NO_REFERENCED_ROW); + err = DB_NO_REFERENCED_ROW; } - return(DB_SUCCESS); + goto exit_func; } ut_a(check_table && check_index); @@ -1291,8 +1258,8 @@ run_again: goto next_rec; } - offsets = rec_reget_offsets(rec, check_index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, check_index, + offsets, ULINT_UNDEFINED, &heap); if (rec == page_get_supremum_rec(buf_frame_align(rec))) { @@ -1424,7 +1391,10 @@ do_possible_lock_wait: err = trx->error_state; } - mem_heap_free(heap); +exit_func: + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -1565,8 +1535,9 @@ row_ins_scan_sec_index_for_duplicate( ibool moved; mtr_t mtr; trx_t* trx; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; n_unique = dict_index_get_n_unique(index); @@ -1582,7 +1553,6 @@ row_ins_scan_sec_index_for_duplicate( } } - heap = mem_heap_create(100); mtr_start(&mtr); /* Store old value on n_fields_cmp */ @@ -1608,8 +1578,8 @@ row_ins_scan_sec_index_for_duplicate( trx = thr_get_trx(thr); ut_ad(trx); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (innobase_query_is_replace()) { @@ -1662,7 +1632,9 @@ next_rec: } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } mtr_commit(&mtr); /* Restore old value */ @@ -1692,7 +1664,11 @@ row_ins_duplicate_error_in_clust( rec_t* rec; page_t* page; ulint n_unique; - trx_t* trx = thr_get_trx(thr); + trx_t* trx = thr_get_trx(thr); + mem_heap_t*heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + UT_NOT_USED(mtr); @@ -1720,12 +1696,8 @@ row_ins_duplicate_error_in_clust( page = buf_frame_align(rec); if (rec != page_get_infimum_rec(page)) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* We set a lock on the possible duplicate: this is needed in logical logging of MySQL to make @@ -1750,17 +1722,15 @@ row_ins_duplicate_error_in_clust( } if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto func_exit; } if (row_ins_dupl_error_with_rec(rec, entry, cursor->index, offsets)) { trx->error_info = cursor->index; - mem_heap_free(heap); - return(DB_DUPLICATE_KEY); + err = DB_DUPLICATE_KEY; + goto func_exit; } - mem_heap_free(heap); } } @@ -1770,12 +1740,8 @@ row_ins_duplicate_error_in_clust( page = buf_frame_align(rec); if (rec != page_get_supremum_rec(page)) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key @@ -1795,15 +1761,14 @@ row_ins_duplicate_error_in_clust( } if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto func_exit; } if (row_ins_dupl_error_with_rec(rec, entry, cursor->index, offsets)) { trx->error_info = cursor->index; - mem_heap_free(heap); - return(DB_DUPLICATE_KEY); + err = DB_DUPLICATE_KEY; + goto func_exit; } mem_heap_free(heap); } @@ -1812,7 +1777,9 @@ row_ins_duplicate_error_in_clust( /* This should never happen */ } - return(DB_SUCCESS); + err = DB_SUCCESS; +func_exit: + return(err); } /******************************************************************* @@ -1894,8 +1861,9 @@ row_ins_index_entry_low( ulint n_unique; big_rec_t* big_rec = NULL; mtr_t mtr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; log_free_check(); @@ -2023,8 +1991,8 @@ function_exit: btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, &cursor, 0, &mtr); rec = btr_cur_get_rec(&cursor); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); err = btr_store_big_rec_extern_fields(index, rec, offsets, big_rec, &mtr); @@ -2038,7 +2006,9 @@ function_exit: mtr_commit(&mtr); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index fa584df15db..4a65cbff8b5 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -3215,18 +3215,19 @@ row_scan_and_check_index( ulint* n_rows) /* out: number of entries seen in the current consistent read */ { - mem_heap_t* heap; - dtuple_t* prev_entry = NULL; + dtuple_t* prev_entry = NULL; ulint matched_fields; ulint matched_bytes; byte* buf; ulint ret; rec_t* rec; - ibool is_ok = TRUE; + ibool is_ok = TRUE; int cmp; ibool contains_null; ulint i; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; *n_rows = 0; @@ -3268,8 +3269,8 @@ loop: matched_fields = 0; matched_bytes = 0; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets, &matched_fields, &matched_bytes); @@ -3299,7 +3300,7 @@ loop: dtuple_print(stderr, prev_entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); is_ok = FALSE; } else if ((index->type & DICT_UNIQUE) @@ -3313,7 +3314,7 @@ loop: } mem_heap_empty(heap); - offsets = NULL; + offsets = offsets_; prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 109d0f3b976..8897a1a872f 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low( ulint err; mtr_t mtr; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; index = dict_table_get_first_index(node->table); @@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low( } rec = btr_pcur_get_rec(pcur); - heap = mem_heap_create(100); if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(rec, index, rec_get_offsets( - rec, index, ULINT_UNDEFINED, heap)))) { - mem_heap_free(heap); + rec, index, offsets_, ULINT_UNDEFINED, &heap)))) { + if (heap) { + mem_heap_free(heap); + } /* Someone else has modified the record later: do not remove */ btr_pcur_commit_specify_mtr(pcur, &mtr); return(TRUE); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (mode == BTR_MODIFY_LEAF) { success = btr_cur_optimistic_delete(btr_cur, &mtr); diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 9cf285a519d..43d0cd41b0a 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -202,17 +202,16 @@ row_build( ulint row_len; byte* buf; ulint i; - mem_heap_t* tmp_heap; + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; ut_ad(index && rec && heap); ut_ad(index->type & DICT_CLUSTERED); if (!offsets) { - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &tmp_heap); } else { - tmp_heap = NULL; ut_ad(rec_offs_validate(rec, index, offsets)); } @@ -296,13 +295,14 @@ row_rec_to_index_entry( ulint len; ulint rec_len; byte* buf; - mem_heap_t* tmp_heap; - ulint* offsets; + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(rec && heap && index); - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); if (type == ROW_COPY_DATA) { /* Take a copy of rec to heap */ @@ -334,7 +334,9 @@ row_rec_to_index_entry( } ut_ad(dtuple_check_typed(entry)); - mem_heap_free(tmp_heap); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } return(entry); } @@ -374,13 +376,14 @@ row_build_row_ref( byte* buf; ulint clust_col_prefix_len; ulint i; - mem_heap_t* tmp_heap; - ulint* offsets; - + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ut_ad(index && rec && heap); - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); if (type == ROW_COPY_DATA) { /* Take a copy of rec to heap */ @@ -433,7 +436,9 @@ row_build_row_ref( } ut_ad(dtuple_check_typed(ref)); - mem_heap_free(tmp_heap); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } return(ref); } @@ -464,8 +469,9 @@ row_build_row_ref_in_tuple( ulint pos; ulint clust_col_prefix_len; ulint i; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(ref && index && rec); @@ -486,8 +492,7 @@ row_build_row_ref_in_tuple( goto notfound; } - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); ref_len = dict_index_get_n_unique(clust_index); @@ -526,7 +531,9 @@ row_build_row_ref_in_tuple( } ut_ad(dtuple_check_typed(ref)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*********************************************************************** diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 2b40b62e5bc..a3d844d1dac 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -78,14 +78,19 @@ row_sel_sec_rec_is_for_clust_rec( ulint n; ulint i; dtype_t* cur_type; - mem_heap_t* heap; - ulint* clust_offs; - ulint* sec_offs; + mem_heap_t* heap = NULL; + ulint clust_offsets_[100] + = { 100, }; + ulint sec_offsets_[10] + = { 10, }; + ulint* clust_offs = clust_offsets_; + ulint* sec_offs = sec_offsets_; + ibool is_equal = TRUE; - heap = mem_heap_create(100); - clust_offs = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); - sec_offs = rec_get_offsets(sec_rec, sec_index, ULINT_UNDEFINED, heap); + clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, + ULINT_UNDEFINED, &heap); + sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs, + ULINT_UNDEFINED, &heap); n = dict_index_get_n_ordering_defined_by_user(sec_index); @@ -113,13 +118,16 @@ row_sel_sec_rec_is_for_clust_rec( if (0 != cmp_data_data(dict_col_get_type(col), clust_field, clust_len, sec_field, sec_len)) { - mem_heap_free(heap); - return(FALSE); + is_equal = FALSE; + goto func_exit; } } - mem_heap_free(heap); - return(TRUE); +func_exit: + if (heap) { + mem_heap_free(heap); + } + return(is_equal); } /************************************************************************* @@ -612,13 +620,13 @@ row_sel_get_clust_rec( rec_t* clust_rec; rec_t* old_vers; ulint err; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; - heap = mem_heap_create(100); offsets = rec_get_offsets(rec, btr_pcur_get_btr_cur(&plan->pcur)->index, - ULINT_UNDEFINED, heap); + offsets, ULINT_UNDEFINED, &heap); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets); @@ -654,8 +662,8 @@ row_sel_get_clust_rec( goto func_exit; } - offsets = rec_reget_offsets(clust_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(clust_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (!node->read_view) { /* Try to place a lock on the index record */ @@ -677,8 +685,7 @@ row_sel_get_clust_rec( if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } } else { /* This is a non-locking consistent read: if necessary, fetch @@ -693,8 +700,7 @@ row_sel_get_clust_rec( clust_rec, &old_vers, mtr); if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } clust_rec = old_vers; @@ -731,9 +737,12 @@ row_sel_get_clust_rec( UT_LIST_GET_FIRST(plan->columns)); func_exit: *out_rec = clust_rec; - - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; +err_exit: + if (heap) { + mem_heap_free(heap); + } + return(err); } /************************************************************************* @@ -975,8 +984,10 @@ row_sel_try_search_shortcut( { dict_index_t* index; rec_t* rec; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ulint ret; index = plan->index; @@ -1010,43 +1021,46 @@ row_sel_try_search_shortcut( /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (index->type & DICT_CLUSTERED) { if (!lock_clust_rec_cons_read_sees(rec, index, offsets, node->read_view)) { - mem_heap_free(heap); - return(SEL_RETRY); + ret = SEL_RETRY; + goto func_exit; } } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) { - mem_heap_free(heap); - return(SEL_RETRY); + ret = SEL_RETRY; + goto func_exit; } /* Test deleted flag. Fetch the columns needed in test conditions. */ row_sel_fetch_columns(index, rec, offsets, UT_LIST_GET_FIRST(plan->columns)); - mem_heap_free(heap); if (rec_get_deleted_flag(rec, plan->table->comp)) { - return(SEL_EXHAUSTED); + ret = SEL_EXHAUSTED; + goto func_exit; } /* Test the rest of search conditions */ if (!row_sel_test_other_conds(plan)) { - return(SEL_EXHAUSTED); + ret = SEL_EXHAUSTED; + goto func_exit; } ut_ad(plan->pcur.latch_mode == node->latch_mode); plan->n_rows_fetched++; - +func_exit: + if (heap) { + mem_heap_free(heap); + } return(SEL_FOUND); } @@ -1095,8 +1109,9 @@ row_sel( to the next non-clustered record */ ulint found_flag; ulint err; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(thr->run_node == node); @@ -1253,8 +1268,8 @@ rec_loop: rec_t* next_rec = page_rec_get_next(rec); ulint lock_type; - offsets = rec_reget_offsets(next_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(next_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (srv_locks_unsafe_for_binlog) { lock_type = LOCK_REC_NOT_GAP; @@ -1295,8 +1310,8 @@ rec_loop: not used. */ ulint lock_type; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (srv_locks_unsafe_for_binlog) { lock_type = LOCK_REC_NOT_GAP; @@ -1369,8 +1384,7 @@ rec_loop: /* PHASE 3: Get previous version in a consistent read */ cons_read_requires_clust_rec = FALSE; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (consistent_read) { /* This is a non-locking consistent read: if necessary, fetch @@ -1403,8 +1417,8 @@ rec_loop: } rec = old_vers; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); } } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) { @@ -1635,8 +1649,8 @@ next_table_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } node->fetch_table++; @@ -1669,7 +1683,7 @@ table_exhausted: table_exhausted_no_mtr: if (node->fetch_table == 0) { - mem_heap_free(heap); + err = DB_SUCCESS; if (node->is_aggregate && !node->aggregate_already_fetched) { @@ -1683,7 +1697,7 @@ table_exhausted_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - return(DB_SUCCESS); + goto func_exit; } node->state = SEL_NODE_NO_MORE_ROWS; @@ -1694,7 +1708,7 @@ table_exhausted_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - return(DB_SUCCESS); + goto func_exit; } node->fetch_table--; @@ -1718,8 +1732,8 @@ stop_for_a_while: mtr_commit(&mtr); ut_ad(sync_thread_levels_empty_gen(TRUE)); - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; commit_mtr_for_a_while: /* Stores the cursor position and commits &mtr; this is used if @@ -1754,7 +1768,10 @@ lock_wait_or_error: ut_ad(sync_thread_levels_empty_gen(TRUE)); - mem_heap_free(heap); +func_exit: + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2197,7 +2214,7 @@ row_sel_store_row_id_to_prebuilt( fprintf(stderr, "\n" "InnoDB: Field number %lu, record:\n", (ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID)); - rec_print(stderr, index_rec, offsets); + rec_print_new(stderr, index_rec, offsets); putc('\n', stderr); ut_error; } @@ -2496,8 +2513,9 @@ row_sel_get_clust_rec_for_mysql( rec_t* old_vers; ulint err; trx_t* trx; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; *out_rec = NULL; trx = thr_get_trx(thr); @@ -2537,14 +2555,10 @@ row_sel_get_clust_rec_for_mysql( dict_index_name_print(stderr, trx, sec_index); fputs("\n" "InnoDB: sec index record ", stderr); - offsets = rec_get_offsets(rec, sec_index, - ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, sec_index); fputs("\n" "InnoDB: clust index record ", stderr); - offsets = rec_reget_offsets(clust_rec, clust_index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, clust_rec, offsets); + rec_print(stderr, clust_rec, clust_index); putc('\n', stderr); trx_print(stderr, trx); @@ -2557,8 +2571,8 @@ row_sel_get_clust_rec_for_mysql( goto func_exit; } - offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(clust_rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); if (prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a lock on the index record; we are searching @@ -2571,8 +2585,7 @@ row_sel_get_clust_rec_for_mysql( LOCK_REC_NOT_GAP, thr); if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } } else { /* This is a non-locking consistent read: if necessary, fetch @@ -2594,8 +2607,7 @@ row_sel_get_clust_rec_for_mysql( if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } clust_rec = old_vers; @@ -2637,8 +2649,12 @@ func_exit: btr_pcur_store_position(prebuilt->clust_pcur, mtr); } - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; +err_exit: + if (heap) { + mem_heap_free(heap); + } + return(err); } /************************************************************************ @@ -2809,8 +2825,8 @@ row_sel_try_search_shortcut_for_mysql( /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */ rec_t** out_rec,/* out: record if found */ row_prebuilt_t* prebuilt,/* in: prebuilt struct */ - ulint** offsets,/* in/out: for rec_reget_offsets(*out_rec) */ - mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ + ulint** offsets,/* in/out: for rec_get_offsets(*out_rec) */ + mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */ mtr_t* mtr) /* in: started mtr */ { dict_index_t* index = prebuilt->index; @@ -2849,8 +2865,8 @@ row_sel_try_search_shortcut_for_mysql( /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - *offsets = rec_reget_offsets(rec, index, - *offsets, ULINT_UNDEFINED, heap); + *offsets = rec_get_offsets(rec, index, *offsets, + ULINT_UNDEFINED, heap); if (!lock_clust_rec_cons_read_sees(rec, index, *offsets, trx->read_view)) { @@ -2915,7 +2931,6 @@ row_search_for_mysql( ibool moved; ibool cons_read_requires_clust_rec; ibool was_lock_wait; - ulint ret; ulint shortcut; ibool unique_search = FALSE; ibool unique_search_from_clust_index = FALSE; @@ -2931,8 +2946,9 @@ row_search_for_mysql( ulint cnt = 0; ulint next_offs; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(index && pcur && search_tuple); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -3023,9 +3039,8 @@ row_search_for_mysql( prebuilt->n_rows_fetched++; srv_n_rows_read++; - trx->op_info = ""; - - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } if (prebuilt->fetch_cache_first > 0 @@ -3034,9 +3049,9 @@ row_search_for_mysql( /* The previous returned row was popped from the fetch cache, but the cache was not full at the time of the popping: no more rows can exist in the result set */ - - trx->op_info = ""; - return(DB_RECORD_NOT_FOUND); + + err = DB_RECORD_NOT_FOUND; + goto func_exit; } prebuilt->n_rows_fetched++; @@ -3080,13 +3095,12 @@ row_search_for_mysql( if (direction != 0 && !prebuilt->used_in_HANDLER) { - trx->op_info = ""; - return(DB_RECORD_NOT_FOUND); + err = DB_RECORD_NOT_FOUND; + goto func_exit; } } mtr_start(&mtr); - heap = mem_heap_create(100); /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ @@ -3132,7 +3146,7 @@ row_search_for_mysql( } #endif shortcut = row_sel_try_search_shortcut_for_mysql(&rec, - prebuilt, &offsets, heap, &mtr); + prebuilt, &offsets, &heap, &mtr); if (shortcut == SEL_FOUND) { #ifdef UNIV_SEARCH_DEBUG ut_a(0 == cmp_dtuple_rec(search_tuple, @@ -3163,12 +3177,10 @@ row_search_for_mysql( trx->has_search_latch = FALSE; } - trx->op_info = ""; - /* NOTE that we do NOT store the cursor position */ - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } else if (shortcut == SEL_EXHAUSTED) { @@ -3186,13 +3198,11 @@ row_search_for_mysql( trx->has_search_latch = FALSE; } - trx->op_info = ""; - /* NOTE that we do NOT store the cursor position */ - mem_heap_free(heap); - return(DB_RECORD_NOT_FOUND); + err = DB_RECORD_NOT_FOUND; + goto func_exit; } shortcut_fails_too_big_rec: mtr_commit(&mtr); @@ -3334,9 +3344,9 @@ rec_loop: we do not lock gaps. Supremum record is really a gap and therefore we do not set locks there. */ - if (srv_locks_unsafe_for_binlog == FALSE) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + if (!srv_locks_unsafe_for_binlog) { + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); err = sel_set_rec_lock(rec, index, offsets, prebuilt->select_lock_type, LOCK_ORDINARY, thr); @@ -3406,8 +3416,7 @@ rec_loop: } } - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (srv_force_recovery > 0) { if (!rec_validate(rec, offsets) @@ -3464,7 +3473,7 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; /* ut_print_name(stderr, index->name); fputs(" record not found 3\n", stderr); */ @@ -3498,7 +3507,7 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; /* ut_print_name(stderr, index->name); fputs(" record not found 4\n", stderr); */ @@ -3644,11 +3653,11 @@ rec_loop: if (prebuilt->need_to_access_clustered) { ut_ad(rec == clust_rec || index == clust_index); - offsets = rec_reget_offsets(rec, clust_index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); } else { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); } /* We found a qualifying row */ @@ -3694,8 +3703,8 @@ rec_loop: } if (prebuilt->clust_index_was_generated) { - offsets = rec_reget_offsets(index_rec, index, offsets, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(index_rec, index, offsets, + ULINT_UNDEFINED, &heap); row_sel_store_row_id_to_prebuilt(prebuilt, index_rec, index, offsets); } @@ -3717,7 +3726,7 @@ got_row: btr_pcur_store_position(pcur, &mtr); } - ret = DB_SUCCESS; + err = DB_SUCCESS; goto normal_return; @@ -3756,9 +3765,9 @@ next_rec: btr_pcur_store_position(pcur, &mtr); if (match_mode != 0) { - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; } else { - ret = DB_END_OF_INDEX; + err = DB_END_OF_INDEX; } goto normal_return; @@ -3797,10 +3806,7 @@ lock_wait_or_error: /* fputs("Using ", stderr); dict_index_name_print(stderr, index); fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ - trx->op_info = ""; - - mem_heap_free(heap); - return(err); + goto func_exit; normal_return: /*-------------------------------------------------------------*/ @@ -3811,20 +3817,22 @@ normal_return: if (prebuilt->n_fetch_cached > 0) { row_sel_pop_cached_row_for_mysql(buf, prebuilt); - ret = DB_SUCCESS; + err = DB_SUCCESS; } /* fputs("Using ", stderr); dict_index_name_print(stderr, index); fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ - if (ret == DB_SUCCESS) { + if (err == DB_SUCCESS) { srv_n_rows_read++; } +func_exit: trx->op_info = ""; - - mem_heap_free(heap); - return(ret); + if (heap) { + mem_heap_free(heap); + } + return(err); } /*********************************************************************** diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index ee9066a0d6f..1cade0f304f 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update( found = row_search_index_entry(index, entry, mode, &pcur, &mtr); if (!found) { - heap = mem_heap_create(100); fputs("InnoDB: error in sec index entry del undo in\n" "InnoDB: ", stderr); dict_index_name_print(stderr, trx, index); @@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update( dtuple_print(stderr, entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, btr_pcur_get_rec(&pcur), - rec_get_offsets(btr_pcur_get_rec(&pcur), - index, ULINT_UNDEFINED, heap)); + rec_print(stderr, btr_pcur_get_rec(&pcur), index); putc('\n', stderr); trx_print(stderr, trx); fputs("\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); - mem_heap_free(heap); } else { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 42f5ef94854..d994eab9873 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur( mtr_t mtr; ibool ret; rec_t* rec; - mem_heap_t* heap; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; mtr_start(&mtr); @@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur( rec = btr_pcur_get_rec(&(node->pcur)); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); if (!found || 0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(rec, clust_index, offsets))) { @@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur( btr_pcur_commit_specify_mtr(&(node->pcur), &mtr); + if (heap) { + mem_heap_free(heap); + } return(ret); } diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index e080d0ba577..e4013633bed 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary( upd_t* update; ulint n_diff; ulint i; + ulint offsets_[10] = { 10, }; const ulint* offsets; /* This function is used only for a secondary index */ @@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary( update = upd_create(dtuple_get_n_fields(entry), heap); n_diff = 0; - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { @@ -775,6 +777,7 @@ row_upd_build_difference_binary( ulint trx_id_pos; ibool extern_bit; ulint i; + ulint offsets_[100] = { 100, }; const ulint* offsets; /* This function is used only for a clustered index */ @@ -787,7 +790,8 @@ row_upd_build_difference_binary( roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR); trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { @@ -1182,7 +1186,8 @@ row_upd_store_row( dict_index_t* clust_index; upd_t* update; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; const ulint* offsets; ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES); @@ -1196,8 +1201,8 @@ row_upd_store_row( rec = btr_pcur_get_rec(node->pcur); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets_, + ULINT_UNDEFINED, &heap); node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, node->heap); node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint) @@ -1210,7 +1215,9 @@ row_upd_store_row( node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec, offsets, update); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*************************************************************** @@ -1263,8 +1270,7 @@ row_upd_sec_index_entry( dtuple_print(stderr, entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap)); + rec_print(stderr, rec, index); putc('\n', stderr); trx_print(stderr, trx); @@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert( a foreign key constraint */ mtr_t* mtr) /* in: mtr; gets committed here */ { - mem_heap_t* heap; + mem_heap_t* heap = NULL; btr_pcur_t* pcur; btr_cur_t* btr_cur; trx_t* trx; @@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert( table = node->table; pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); - heap = mem_heap_create(500); if (node->state != UPD_NODE_INSERT_CLUSTERED) { + ulint offsets_[100] = { 100, }; err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, btr_cur, TRUE, thr, mtr); if (err != DB_SUCCESS) { mtr_commit(mtr); - mem_heap_free(heap); return(err); } @@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert( btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur), rec_get_offsets(btr_cur_get_rec(btr_cur), - dict_table_get_first_index(table), - ULINT_UNDEFINED, heap), node->update, mtr); + dict_table_get_first_index(table), offsets_, + ULINT_UNDEFINED, &heap), node->update, mtr); if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert( index, thr, mtr); if (err != DB_SUCCESS) { mtr_commit(mtr); - + if (heap) { + mem_heap_free(heap); + } return(err); } } @@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert( mtr_commit(mtr); + if (!heap) { + heap = mem_heap_create(500); + } node->state = UPD_NODE_INSERT_CLUSTERED; entry = row_build_index_entry(node->row, index, heap); @@ -1516,17 +1526,20 @@ row_upd_clust_rec( mtr_commit(mtr); if (err == DB_SUCCESS && big_rec) { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; rec_t* rec; mtr_start(mtr); - heap = mem_heap_create(100); rec = btr_cur_get_rec(btr_cur); ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr)); err = btr_store_big_rec_extern_fields(index, rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), big_rec, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } mtr_commit(mtr); } @@ -1611,7 +1624,8 @@ row_upd_clust_step( mtr_t* mtr; mtr_t mtr_buf; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; const ulint* offsets; index = dict_table_get_first_index(node->table); @@ -1670,33 +1684,31 @@ row_upd_clust_step( } rec = btr_pcur_get_rec(pcur); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); if (!node->has_clust_rec_x_lock) { err = lock_clust_rec_modify_check_and_lock(0, rec, index, offsets, thr); if (err != DB_SUCCESS) { mtr_commit(mtr); - mem_heap_free(heap); - return(err); + goto exit_func; } } /* NOTE: the following function calls will also commit mtr */ if (node->is_delete) { - mem_heap_free(heap); err = row_upd_del_mark_clust_rec(node, index, thr, check_ref, mtr); - if (err != DB_SUCCESS) { - - return(err); + if (err == DB_SUCCESS) { + node->state = UPD_NODE_UPDATE_ALL_SEC; + node->index = dict_table_get_next_index(index); + } + exit_func: + if (heap) { + mem_heap_free(heap); } - - node->state = UPD_NODE_UPDATE_ALL_SEC; - node->index = dict_table_get_next_index(index); - return(err); } @@ -1710,13 +1722,14 @@ row_upd_clust_step( UT_LIST_GET_FIRST(node->columns)); row_upd_eval_new_vals(node->update); } - - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } + if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { err = row_upd_clust_rec(node, index, thr, mtr); - return(err); } @@ -1968,7 +1981,8 @@ row_upd_in_place_in_select( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; ut_ad(sel_node->select_will_do_update); ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF); @@ -1984,11 +1998,13 @@ row_upd_in_place_in_select( /* Copy the necessary columns from clust_rec and calculate the new values to set */ - heap = mem_heap_create(100); row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets( - btr_pcur_get_rec(pcur), btr_cur->index, ULINT_UNDEFINED, heap), + btr_pcur_get_rec(pcur), btr_cur->index, offsets_, + ULINT_UNDEFINED, &heap), UT_LIST_GET_FIRST(node->columns)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } row_upd_eval_new_vals(node->update); ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur), diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index 5281dbd67d7..9ccaf32f2c2 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel( } heap = mem_heap_create(1024); - clust_offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); + clust_offsets = rec_get_offsets(clust_rec, clust_index, NULL, + ULINT_UNDEFINED, &heap); trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets); mtr_s_lock(&(purge_sys->latch), &mtr); mutex_enter(&kernel_mutex); + trx = NULL; if (!trx_is_active(trx_id)) { /* The transaction that modified or inserted clust_rec is no longer active: no implicit lock on rec */ - - mem_heap_free(heap); - mtr_commit(&mtr); - - return(NULL); + goto exit_func; } if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, clust_offsets, TRUE)) { /* Corruption noticed: try to avoid a crash by returning */ - - mem_heap_free(heap); - mtr_commit(&mtr); - - return(NULL); + goto exit_func; } comp = index->table->comp; @@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel( if (prev_version) { clust_offsets = rec_get_offsets(prev_version, - clust_index, ULINT_UNDEFINED, heap); + clust_index, NULL, + ULINT_UNDEFINED, &heap); row = row_build(ROW_COPY_POINTERS, clust_index, prev_version, clust_offsets, heap); entry = row_build_index_entry(row, index, heap); @@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel( version = prev_version; }/* for (;;) */ +exit_func: mtr_commit(&mtr); mem_heap_free(heap); @@ -330,8 +325,8 @@ row_vers_old_has_index_entry( comp = index->table->comp; ut_ad(comp == page_is_comp(buf_frame_align(rec))); heap = mem_heap_create(1024); - clust_offsets = rec_get_offsets(rec, clust_index, - ULINT_UNDEFINED, heap); + clust_offsets = rec_get_offsets(rec, clust_index, NULL, + ULINT_UNDEFINED, &heap); if (also_curr && !rec_get_deleted_flag(rec, comp)) { row = row_build(ROW_COPY_POINTERS, clust_index, @@ -371,7 +366,7 @@ row_vers_old_has_index_entry( } clust_offsets = rec_get_offsets(prev_version, clust_index, - ULINT_UNDEFINED, heap); + NULL, ULINT_UNDEFINED, &heap); if (!rec_get_deleted_flag(prev_version, comp)) { row = row_build(ROW_COPY_POINTERS, clust_index, @@ -438,7 +433,7 @@ row_vers_build_for_consistent_read( #endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); ut_ad(!read_view_sees_trx_id(view, row_get_rec_trx_id(rec, index, offsets))); @@ -466,8 +461,8 @@ row_vers_build_for_consistent_read( break; } - offsets = rec_get_offsets(prev_version, index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(prev_version, index, NULL, + ULINT_UNDEFINED, &heap); prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets); if (read_view_sees_trx_id(view, prev_trx_id)) { diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 484d4f62744..12a0512da53 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -1010,8 +1010,9 @@ trx_undo_report_row_operation( ibool is_insert; trx_rseg_t* rseg; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(index->type & DICT_CLUSTERED); @@ -1066,8 +1067,6 @@ trx_undo_report_row_operation( mtr_start(&mtr); - heap = mem_heap_create(100); - for (;;) { undo_page = buf_page_get_gen(undo->space, page_no, RW_X_LATCH, undo->guess_page, @@ -1084,8 +1083,8 @@ trx_undo_report_row_operation( index, clust_entry, &mtr); } else { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); offset = trx_undo_page_report_modify(undo_page, trx, index, rec, offsets, update, cmpl_info, &mtr); } @@ -1129,7 +1128,9 @@ trx_undo_report_row_operation( mutex_exit(&(trx->undo_mutex)); mtr_commit(&mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_OUT_OF_FILE_SPACE); } } @@ -1146,7 +1147,9 @@ trx_undo_report_row_operation( *roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no, offset); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -1266,7 +1269,6 @@ trx_undo_prev_version_build( ibool dummy_extern; byte* buf; ulint err; - ulint* index_offsets = NULL; #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); #endif /* UNIV_SYNC_DEBUG */ @@ -1282,12 +1284,10 @@ trx_undo_prev_version_build( "InnoDB: Submit a detailed bug report to" " http://bugs.mysql.com\n" "InnoDB: index record ", index->name); - index_offsets = rec_get_offsets(index_rec, index, - ULINT_UNDEFINED, heap); - rec_print(stderr, index_rec, index_offsets); + rec_print(stderr, index_rec, index); fputs("\n" "InnoDB: record version ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); return(DB_ERROR); } @@ -1353,12 +1353,10 @@ trx_undo_prev_version_build( ut_print_buf(stderr, undo_rec, 150); fputs("\n" "InnoDB: index record ", stderr); - index_offsets = rec_get_offsets(index_rec, index, - ULINT_UNDEFINED, heap); - rec_print(stderr, index_rec, index_offsets); + rec_print(stderr, index_rec, index); fputs("\n" "InnoDB: record version ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fprintf(stderr, "\n" "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n" "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n", diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index dc0ef57e910..fbaa22cff14 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -317,6 +317,7 @@ my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, DBUG_ENTER("mysql_master_send_query"); if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0)) DBUG_RETURN(1); + master->reconnect= 1; mysql->last_used_con = master; DBUG_RETURN(simple_command(master, COM_QUERY, q, length, 1)); } @@ -351,6 +352,7 @@ my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0, 0,0,0,0)) DBUG_RETURN(1); + slave_to_use->reconnect= 1; DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, q, length, 1)); } @@ -448,6 +450,7 @@ static my_bool get_slaves_from_master(MYSQL* mysql) expand_error(mysql, CR_PROBE_MASTER_CONNECT); DBUG_RETURN(1); } + mysql->reconnect= 1; if (mysql_query(mysql, "SHOW SLAVE HOSTS") || !(res = mysql_store_result(mysql))) @@ -615,6 +618,7 @@ mysql_connect(MYSQL *mysql,const char *host, if (mysql->free_me) my_free((gptr) mysql,MYF(0)); } + mysql->reconnect= 1; DBUG_RETURN(res); } } diff --git a/libmysqld/examples/builder-sample/emb_samples.cpp b/libmysqld/examples/builder-sample/emb_samples.cpp index 4dfde111f84..411de26149b 100644 --- a/libmysqld/examples/builder-sample/emb_samples.cpp +++ b/libmysqld/examples/builder-sample/emb_samples.cpp @@ -109,6 +109,7 @@ bool __fastcall TForm1::connect_server() ret_value = true; is_server_started = true; } + MySQL->reconnect= 1; return ret_value; } //--------------------------------------------------------------------------- diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index e0d484312e7..37f5d0aa26a 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -52,9 +52,9 @@ KEY NAME (NAME)); ALTER TABLE t1 CHANGE NAME NAME CHAR(80) not null; SHOW FULL COLUMNS FROM t1; Field Type Collation Null Key Default Extra Privileges Comment -GROUP_ID int(10) unsigned NULL PRI 0 select,insert,update,references -LANG_ID smallint(5) unsigned NULL PRI 0 select,insert,update,references -NAME char(80) latin1_swedish_ci MUL select,insert,update,references +GROUP_ID int(10) unsigned NULL NO PRI 0 select,insert,update,references +LANG_ID smallint(5) unsigned NULL NO PRI 0 select,insert,update,references +NAME char(80) latin1_swedish_ci NO MUL select,insert,update,references DROP TABLE t1; create table t1 (n int); insert into t1 values(9),(3),(12),(10); @@ -187,7 +187,7 @@ alter table t1 rename t2; alter table t2 rename t1, add c char(10) comment "no comment"; show columns from t1; Field Type Null Key Default Extra -i int(10) unsigned PRI NULL auto_increment +i int(10) unsigned NO PRI NULL auto_increment c char(10) YES NULL drop table t1; create table t1 (a int, b int); diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index ce4515f900b..f2e91c36f75 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -100,12 +100,12 @@ drop table t2; create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f; describe t2; Field Type Null Key Default Extra -a datetime 0000-00-00 00:00:00 -b time 00:00:00 -c date 0000-00-00 -d bigint(17) 0 -e double(18,1) 0.0 -f bigint(17) 0 +a datetime NO 0000-00-00 00:00:00 +b time NO 00:00:00 +c date NO 0000-00-00 +d bigint(17) NO 0 +e double(18,1) NO 0.0 +f bigint(17) NO 0 drop table t2; create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt; describe t2; @@ -412,13 +412,13 @@ from t1; explain t2; Field Type Null Key Default Extra a int(11) YES NULL -b bigint(11) 0 -c bigint(10) 0 +b bigint(11) NO 0 +c bigint(10) NO 0 d date YES NULL -e varchar(1) +e varchar(1) NO f datetime YES NULL g time YES NULL -h longblob +h longblob NO dd time YES NULL select * from t2; a b c d e f g h dd diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index aebf8b4637b..201e1c6de08 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -488,7 +488,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 SHOW FIELDS FROM t1; Field Type Null Key Default Extra -latin1_f char(32) +latin1_f char(32) NO ALTER TABLE t1 CHANGE latin1_f latin1_f CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin; SHOW CREATE TABLE t1; diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 7d5f9d5b59a..da0007fdfbe 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -54,7 +54,7 @@ Table Create Table ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ' SHOW FIELDS FROM ÔÁÂÌÉÃÁ; Field Type Null Key Default Extra -ÐÏÌÅ char(32) +ÐÏÌÅ char(32) NO SET CHARACTER SET cp1251; SHOW TABLES; Tables_in_test @@ -66,7 +66,7 @@ Table Create Table ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='êîììåíòàðèé òàáëèöû' SHOW FIELDS FROM òàáëèöà; Field Type Null Key Default Extra -ïîëå char(32) +ïîëå char(32) NO SET CHARACTER SET utf8; SHOW TABLES; Tables_in_test @@ -78,7 +78,7 @@ Table Create Table ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='комментарий таблицы' SHOW FIELDS FROM таблица; Field Type Null Key Default Extra -поле char(32) +поле char(32) NO SET CHARACTER SET koi8r; DROP TABLE ÔÁÂÌÉÃÁ; SET CHARACTER SET default; diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index d02ac0062f8..c9d37fb845a 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -123,7 +123,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=ujis SHOW COLUMNS FROM t1; Field Type Null Key Default Extra -a char(1) +a char(1) NO b enum('¤¢','¤¤') YES NULL DROP TABLE t1; CREATE TABLE t1 diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 223ceb003b3..901871f437e 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -32,6 +32,7 @@ unlock tables; create database mysqltest; show databases; Database +information_schema mysql mysqltest test @@ -42,6 +43,7 @@ unlock tables; drop database mysqltest; show databases; Database +information_schema mysql test drop database mysqltest; diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index fb344855e83..f80b0281dd8 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -174,12 +174,12 @@ date("1997-12-31 23:59:59.000001") as f8, time("1997-12-31 23:59:59.000001") as f9; describe t1; Field Type Null Key Default Extra -f1 date 0000-00-00 +f1 date NO 0000-00-00 f2 datetime YES NULL f3 time YES NULL -f4 time 00:00:00 -f5 time 00:00:00 -f6 time 00:00:00 +f4 time NO 00:00:00 +f5 time NO 00:00:00 +f6 time NO 00:00:00 f7 datetime YES NULL f8 date YES NULL f9 time YES NULL diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 131496f3d9f..32c80bb330e 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -611,7 +611,7 @@ create table t1 select last_day('2000-02-05') as a, from_days(to_days("960101")) as b; describe t1; Field Type Null Key Default Extra -a date 0000-00-00 +a date NO 0000-00-00 b date YES NULL select * from t1; a b diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index ee0a30e27d0..3b196a60d68 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -9,35 +9,35 @@ CREATE TABLE gis_geometrycollection (fid INTEGER NOT NULL PRIMARY KEY, g GEOMET CREATE TABLE gis_geometry (fid INTEGER NOT NULL PRIMARY KEY, g GEOMETRY); SHOW FIELDS FROM gis_point; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g point YES NULL SHOW FIELDS FROM gis_line; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g linestring YES NULL SHOW FIELDS FROM gis_polygon; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g polygon YES NULL SHOW FIELDS FROM gis_multi_point; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g multipoint YES NULL SHOW FIELDS FROM gis_multi_line; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g multilinestring YES NULL SHOW FIELDS FROM gis_multi_polygon; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g multipolygon YES NULL SHOW FIELDS FROM gis_geometrycollection; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g geometrycollection YES NULL SHOW FIELDS FROM gis_geometry; Field Type Null Key Default Extra -fid int(11) PRI +fid int(11) NO PRI g geometry YES NULL INSERT INTO gis_point VALUES (101, PointFromText('POINT(10 10)')), @@ -430,7 +430,7 @@ mln multilinestring YES NULL mpg multipolygon YES NULL gc geometrycollection YES NULL gm geometry YES NULL -fid int(11) +fid int(11) NO DROP TABLE t1; SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))); AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)')))) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index f716d90a073..ab6e180e6b7 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -5,10 +5,12 @@ NULL mysql latin1 NULL NULL test latin1 NULL select schema_name from information_schema.schemata; schema_name +information_schema mysql test show databases *; CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH +NULL information_schema utf8 NULL NULL mysql latin1 NULL NULL test latin1 NULL show databases like 't%'; @@ -16,6 +18,7 @@ Database (t%) test show databases; Database +information_schema mysql test show databases * where schema_name like 't%'; @@ -31,6 +34,22 @@ create table testtets.t4(a int); create view v1 (c) as select table_name from information_schema.TABLES; select * from v1; c +SCHEMATA +TABLES +COLUMNS +CHARACTER_SETS +COLLATIONS +COLLATION_CHARACTER_SET_APPLICABILITY +ROUTINES +STATISTICS +VIEWS +USER_PRIVILEGES +SCHEMA_PRIVILEGES +TABLE_PRIVILEGES +COLUMN_PRIVILEGES +TABLE_CONSTRAINTS +KEY_COLUMN_USAGE +TABLE_NAMES columns_priv db func @@ -56,6 +75,10 @@ select c,table_name from v1 left join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name +TABLES TABLES +TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_CONSTRAINTS TABLE_CONSTRAINTS +TABLE_NAMES TABLE_NAMES tables_priv tables_priv time_zone time_zone time_zone_leap_second time_zone_leap_second @@ -70,6 +93,10 @@ select c, v2.table_name from v1 right join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; c table_name +TABLES TABLES +TABLE_PRIVILEGES TABLE_PRIVILEGES +TABLE_CONSTRAINTS TABLE_CONSTRAINTS +TABLE_NAMES TABLE_NAMES tables_priv tables_priv time_zone time_zone time_zone_leap_second time_zone_leap_second @@ -88,11 +115,10 @@ t4 select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT NULL testtets t1 1 testtets string_data 1 b A NULL NULL NULL YES BTREE -show keys * where TABLE_SCHEMA Like "test%"; +show keys * from t3 where TABLE_SCHEMA Like "test%"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT NULL test t3 1 test a_data 1 a A NULL NULL NULL YES BTREE -NULL testtets t1 1 testtets string_data 1 b A NULL NULL NULL YES BTREE -show keys where INDEX_NAME = "a_data"; +show keys from t3 where INDEX_NAME = "a_data"; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t3 1 a_data 1 a A NULL NULL NULL YES BTREE show tables like 't%'; @@ -113,15 +139,15 @@ Field Type Collation Null Key Default Extra Privileges Comment a int(11) NULL YES MUL NULL select,insert,update,references show full columns from mysql.db like "Insert%"; Field Type Collation Null Key Default Extra Privileges Comment -Insert_priv enum('N','Y') utf8_bin N select,insert,update,references +Insert_priv enum('N','Y') utf8_bin NO N select,insert,update,references show full columns from v1; Field Type Collation Null Key Default Extra Privileges Comment -c varchar(64) utf8_general_ci select,insert,update,references +c varchar(64) utf8_general_ci NO select,insert,update,references select * from information_schema.COLUMNS where table_name="t1" and column_name= "a"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT NULL testtets t1 a 1 NULL YES int 11 11 11 0 NULL NULL int(11) select,insert,update,references -show columns * where table_name = "t1"; +show columns * from testtets.t1 where table_name = "t1"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT NULL testtets t1 a 1 NULL YES int 11 11 11 0 NULL NULL int(11) select,insert,update,references NULL testtets t1 b 2 NULL YES varchar 30 30 NULL NULL latin1 latin1_swedish_ci varchar(30) MUL select,insert,update,references @@ -255,6 +281,7 @@ count(*) create view v0 (c) as select schema_name from information_schema.schemata; select * from v0; c +information_schema mysql test explain select * from v0; @@ -351,18 +378,18 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from information_schema.TABLE_CONSTRAINTS where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD -NULL test PRIMARY test t1 PRIMARY KEY NULL -NULL test constraint_1 test t1 UNIQUE NULL -NULL test key_1 test t1 UNIQUE NULL -NULL test key_2 test t1 UNIQUE NULL +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE +NULL test PRIMARY test t1 PRIMARY KEY +NULL test constraint_1 test t1 UNIQUE +NULL test key_1 test t1 UNIQUE +NULL test key_2 test t1 UNIQUE select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -NULL test PRIMARY NULL test t1 a 1 NULL NULL NULL -NULL test constraint_1 NULL test t1 a 1 NULL NULL NULL -NULL test key_1 NULL test t1 a 1 NULL NULL NULL -NULL test key_2 NULL test t1 a 1 NULL NULL NULL +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY NULL test t1 a 1 NULL NULL NULL NULL +NULL test constraint_1 NULL test t1 a 1 NULL NULL NULL NULL +NULL test key_1 NULL test t1 a 1 NULL NULL NULL NULL +NULL test key_2 NULL test t1 a 1 NULL NULL NULL NULL select table_name from information_schema.TABLES where table_schema like "test%"; table_name t1 @@ -392,7 +419,6 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN 'joe'@'localhost' NULL test t1 a SELECT YES select * from INFORMATION_SCHEMA.TABLE_PRIVILEGES; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE -'joe'@'localhost' NULL test t1 USAGE YES drop view v1, v2, v3; drop table t1; delete from mysql.user where user='joe'; @@ -404,7 +430,7 @@ create procedure px5 () begin declare v int; declare c cursor for select version from -information_schema.tables; +information_schema.tables where table_schema <> 'information_schema'; open c; fetch c into v; select v; @@ -432,6 +458,7 @@ select s1 from t1 where s1 in (select version from information_schema.tables) union select version from information_schema.tables; s1 +0 9 10 drop table t1; @@ -508,11 +535,6 @@ proc modified timestamp proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO') proc comment char(64) drop table t115; -create view vk as select count(*) from information_schema.tables a; -select * from vk; -count(*) -17 -drop view vk; create procedure p108 () begin declare c cursor for select data_type from information_schema.columns; open c; open c; end;// call p108()// @@ -529,8 +551,37 @@ show index from vo; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME= "vo"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE select * from information_schema.KEY_COLUMN_USAGE where TABLE_NAME= "vo"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME drop view vo; +select TABLE_NAME,TABLE_TYPE,ENGINE +from information_schema.tables +where table_schema='information_schema' limit 2; +TABLE_NAME TABLE_TYPE ENGINE +SCHEMATA TEMPORARY MyISAM +TABLES TEMPORARY MyISAM +show tables from information_schema like "t%"; +Tables_in_information_schema (t%) +create database information_schema; +ERROR HY000: Can't create database 'information_schema'; database exists +use information_schema; +show full tables like "T%"; +Tables_in_information_schema (T%) Table_type +TABLES TEMPORARY +TABLE_PRIVILEGES TEMPORARY +TABLE_CONSTRAINTS TEMPORARY +TABLE_NAMES TEMPORARY +create table t1(a int); +ERROR 42S02: Unknown table 't1' in information_schema +use test; +show tables; +Tables_in_test +use information_schema; +show tables like "T%"; +Tables_in_information_schema (T%) +TABLES +TABLE_PRIVILEGES +TABLE_CONSTRAINTS +TABLE_NAMES diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result index e6dcda2c15d..cdbdda5fd43 100644 --- a/mysql-test/r/information_schema_inno.result +++ b/mysql-test/r/information_schema_inno.result @@ -4,16 +4,16 @@ FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE CASCADE) ENGINE=INNODB; select * from information_schema.TABLE_CONSTRAINTS where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD -NULL test PRIMARY test t1 PRIMARY KEY NULL -NULL test PRIMARY test t2 PRIMARY KEY NULL -NULL test t2_ibfk_1 test t2 FOREIGN KEY ON DELETE CASCADE -NULL test t2_ibfk_2 test t2 FOREIGN KEY ON UPDATE CASCADE +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE +NULL test PRIMARY test t1 PRIMARY KEY +NULL test PRIMARY test t2 PRIMARY KEY +NULL test t2_ibfk_1 test t2 FOREIGN KEY +NULL test t2_ibfk_2 test t2 FOREIGN KEY select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -NULL test PRIMARY NULL test t1 id 1 NULL NULL NULL -NULL test PRIMARY NULL test t2 id 1 NULL NULL NULL -NULL test t2_ibfk_1 NULL test t2 t1_id 1 NULL id -NULL test t2_ibfk_2 NULL test t2 t1_id 1 NULL id +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY NULL test t1 id 1 NULL NULL NULL NULL +NULL test PRIMARY NULL test t2 id 1 NULL NULL NULL NULL +NULL test t2_ibfk_1 NULL test t2 t1_id 1 1 test t1 id +NULL test t2_ibfk_2 NULL test t2 t1_id 1 1 test t1 id drop table t2, t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 60028763b17..9a6c69b7bea 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -931,7 +931,7 @@ drop table t1; create table t1 (t int not null default 1, key (t)) engine=innodb; desc t1; Field Type Null Key Default Extra -t int(11) MUL 1 +t int(11) NO MUL 1 drop table t1; CREATE TABLE t1 ( number bigint(20) NOT NULL default '0', diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index 82ff4072378..ba7bcd05673 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -355,6 +355,7 @@ drop table t2; drop database test2; show databases; Database +information_schema mysql test use test; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 0868ec3a364..ef399b6662d 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -254,6 +254,7 @@ a int primary key, b char(10) prepare stmt4 from ' show databases '; execute stmt4; Database +information_schema mysql test prepare stmt4 from ' show tables from test like ''t2%'' '; @@ -263,7 +264,7 @@ t2 prepare stmt4 from ' show columns from t2 from test like ''a%'' '; execute stmt4; Field Type Null Key Default Extra -a int(11) PRI +a int(11) NO PRI create index t2_idx on t2(b); prepare stmt4 from ' show index from t2 from test '; execute stmt4; @@ -410,7 +411,7 @@ drop user drop_user@localhost; prepare stmt3 from ' describe t2 '; execute stmt3; Field Type Null Key Default Extra -a int(11) PRI +a int(11) NO PRI b char(10) YES MUL NULL drop table t2 ; execute stmt3; diff --git a/mysql-test/r/rpl000009.result b/mysql-test/r/rpl000009.result index bb82dcb1e6a..a4dbf54f39b 100644 --- a/mysql-test/r/rpl000009.result +++ b/mysql-test/r/rpl000009.result @@ -32,6 +32,7 @@ create database mysqltest2; create database mysqltest; show databases; Database +information_schema mysql mysqltest mysqltest2 @@ -48,6 +49,7 @@ insert into mysqltest.t2 values (11, 'eleven test'), (12, 'twelve test'), set sql_log_bin = 1; show databases; Database +information_schema mysql test create database mysqltest2; @@ -66,6 +68,7 @@ insert into mysqltest.t3 values (1, 'original bar.t3'); load data from master; show databases; Database +information_schema mysql mysqltest mysqltest2 diff --git a/mysql-test/r/rpl_create_database.result b/mysql-test/r/rpl_create_database.result index 86282ce3cc5..ca4585d0d8d 100644 --- a/mysql-test/r/rpl_create_database.result +++ b/mysql-test/r/rpl_create_database.result @@ -22,6 +22,7 @@ USE mysqltest_sisyfos; ALTER DATABASE mysqltest_bob CHARACTER SET latin1; SHOW DATABASES; Database +information_schema mysql mysqltest_bob mysqltest_prometheus @@ -29,6 +30,7 @@ mysqltest_sisyfos test SHOW DATABASES; Database +information_schema mysql mysqltest_prometheus mysqltest_sisyfos @@ -57,6 +59,7 @@ master-bin.000001 # Query 1 # CREATE DATABASE mysqltest_sisyfos master-bin.000001 # Query 1 # use `mysqltest_sisyfos`; CREATE TABLE t2 (a INT) SHOW DATABASES; Database +information_schema mysql mysqltest_bob mysqltest_prometheus @@ -64,6 +67,7 @@ mysqltest_sisyfos test SHOW DATABASES; Database +information_schema mysql mysqltest_prometheus mysqltest_sisyfos diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result index d7bd6fef655..48e6ebcfad2 100644 --- a/mysql-test/r/schema.result +++ b/mysql-test/r/schema.result @@ -4,6 +4,7 @@ Database Create Database foo CREATE DATABASE `foo` /*!40100 DEFAULT CHARACTER SET latin1 */ show schemas; Database +information_schema foo mysql test diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index e4232a759b1..ac0157fcfd1 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2034,20 +2034,20 @@ show tables from test like "t?"; Tables_in_test (t?) show full columns from t2; Field Type Collation Null Key Default Extra Privileges Comment -auto int(11) NULL PRI NULL auto_increment select,insert,update,references -fld1 int(6) unsigned zerofill NULL UNI 000000 select,insert,update,references -companynr tinyint(2) unsigned zerofill NULL 00 select,insert,update,references -fld3 char(30) latin1_swedish_ci MUL select,insert,update,references -fld4 char(35) latin1_swedish_ci select,insert,update,references -fld5 char(35) latin1_swedish_ci select,insert,update,references -fld6 char(4) latin1_swedish_ci select,insert,update,references +auto int(11) NULL NO PRI NULL auto_increment select,insert,update,references +fld1 int(6) unsigned zerofill NULL NO UNI 000000 select,insert,update,references +companynr tinyint(2) unsigned zerofill NULL NO 00 select,insert,update,references +fld3 char(30) latin1_swedish_ci NO MUL select,insert,update,references +fld4 char(35) latin1_swedish_ci NO select,insert,update,references +fld5 char(35) latin1_swedish_ci NO select,insert,update,references +fld6 char(4) latin1_swedish_ci NO select,insert,update,references show full columns from t2 from test like 'f%'; Field Type Collation Null Key Default Extra Privileges Comment -fld1 int(6) unsigned zerofill NULL UNI 000000 select,insert,update,references -fld3 char(30) latin1_swedish_ci MUL select,insert,update,references -fld4 char(35) latin1_swedish_ci select,insert,update,references -fld5 char(35) latin1_swedish_ci select,insert,update,references -fld6 char(4) latin1_swedish_ci select,insert,update,references +fld1 int(6) unsigned zerofill NULL NO UNI 000000 select,insert,update,references +fld3 char(30) latin1_swedish_ci NO MUL select,insert,update,references +fld4 char(35) latin1_swedish_ci NO select,insert,update,references +fld5 char(35) latin1_swedish_ci NO select,insert,update,references +fld6 char(4) latin1_swedish_ci NO select,insert,update,references show full columns from t2 from test like 's%'; Field Type Collation Null Key Default Extra Privileges Comment show keys from t2; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 931fb8b20b9..dab35262e0a 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -50,6 +50,7 @@ show table status from test like "this_doesn't_exists%"; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment show databases; Database +information_schema mysql test show databases like "test%"; @@ -118,9 +119,9 @@ t1 CREATE TABLE t1 ( set sql_quote_show_create=1; show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment -test_set set('val1','val2','val3') latin1_swedish_ci select,insert,update,references +test_set set('val1','val2','val3') latin1_swedish_ci NO select,insert,update,references name char(20) latin1_swedish_ci YES O'Brien select,insert,update,references O'Brien as default -c int(11) NULL select,insert,update,references int column +c int(11) NULL NO select,insert,update,references int column c-b int(11) NULL YES NULL select,insert,update,references name with a minus space 2 int(11) NULL YES NULL select,insert,update,references name with a space drop table t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 8745a274851..0d7f9f7d50c 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1646,8 +1646,8 @@ test CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ Database (foo) Level Code Message Field Type Null Key Default Extra -id char(16) -data int(11) +id char(16) NO +data int(11) NO Grants for root@localhost GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment @@ -1696,8 +1696,8 @@ test CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ Database (foo) Level Code Message Field Type Null Key Default Extra -id char(16) -data int(11) +id char(16) NO +data int(11) NO Grants for root@localhost GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index 2ccf32367fb..6e92cb7b54c 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1654,7 +1654,7 @@ set names latin1; create table t1 (a enum(0xE4, '1', '2') not null default 0xE4); show columns from t1; Field Type Null Key Default Extra -a enum('ä','1','2') ä +a enum('ä','1','2') NO ä show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -1675,7 +1675,7 @@ t1 CREATE TABLE `t1` ( show columns from t1; Field Type Null Key Default Extra a int(11) YES 1 -b enum('value','öäü_value','ÊÃÕ') value +b enum('value','öäü_value','ÊÃÕ') NO value drop table t1; CREATE TABLE t1 (c enum('a', 'A') BINARY); INSERT INTO t1 VALUES ('a'),('A'); diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index ef4f65eda1f..1a66f0d91d2 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -40,30 +40,30 @@ KEY (options,flags) ); show full fields from t1; Field Type Collation Null Key Default Extra Privileges Comment -auto int(5) unsigned NULL PRI NULL auto_increment select,insert,update,references +auto int(5) unsigned NULL NO PRI NULL auto_increment select,insert,update,references string char(10) latin1_swedish_ci YES hello select,insert,update,references -tiny tinyint(4) NULL MUL 0 select,insert,update,references -short smallint(6) NULL MUL 1 select,insert,update,references -medium mediumint(8) NULL MUL 0 select,insert,update,references -long_int int(11) NULL 0 select,insert,update,references -longlong bigint(13) NULL MUL 0 select,insert,update,references -real_float float(13,1) NULL MUL 0.0 select,insert,update,references +tiny tinyint(4) NULL NO MUL 0 select,insert,update,references +short smallint(6) NULL NO MUL 1 select,insert,update,references +medium mediumint(8) NULL NO MUL 0 select,insert,update,references +long_int int(11) NULL NO 0 select,insert,update,references +longlong bigint(13) NULL NO MUL 0 select,insert,update,references +real_float float(13,1) NULL NO MUL 0.0 select,insert,update,references real_double double(16,4) NULL YES NULL select,insert,update,references -utiny tinyint(3) unsigned NULL MUL 0 select,insert,update,references -ushort smallint(5) unsigned zerofill NULL MUL 00000 select,insert,update,references -umedium mediumint(8) unsigned NULL MUL 0 select,insert,update,references -ulong int(11) unsigned NULL MUL 0 select,insert,update,references -ulonglong bigint(13) unsigned NULL MUL 0 select,insert,update,references +utiny tinyint(3) unsigned NULL NO MUL 0 select,insert,update,references +ushort smallint(5) unsigned zerofill NULL NO MUL 00000 select,insert,update,references +umedium mediumint(8) unsigned NULL NO MUL 0 select,insert,update,references +ulong int(11) unsigned NULL NO MUL 0 select,insert,update,references +ulonglong bigint(13) unsigned NULL NO MUL 0 select,insert,update,references time_stamp timestamp NULL YES CURRENT_TIMESTAMP select,insert,update,references date_field date NULL YES NULL select,insert,update,references time_field time NULL YES NULL select,insert,update,references date_time datetime NULL YES NULL select,insert,update,references blob_col blob NULL YES NULL select,insert,update,references tinyblob_col tinyblob NULL YES NULL select,insert,update,references -mediumblob_col mediumblob NULL select,insert,update,references -longblob_col longblob NULL select,insert,update,references -options enum('one','two','tree') latin1_swedish_ci MUL one select,insert,update,references -flags set('one','two','tree') latin1_swedish_ci select,insert,update,references +mediumblob_col mediumblob NULL NO select,insert,update,references +longblob_col longblob NULL NO select,insert,update,references +options enum('one','two','tree') latin1_swedish_ci NO MUL one select,insert,update,references +flags set('one','two','tree') latin1_swedish_ci NO select,insert,update,references show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE @@ -208,56 +208,56 @@ Warning 1265 Data truncated for column 'options' at row 6 update t2 set string="changed" where auto=16; show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment -auto int(5) unsigned NULL MUL NULL auto_increment select,insert,update,references +auto int(5) unsigned NULL NO MUL NULL auto_increment select,insert,update,references string char(10) latin1_swedish_ci YES new defaul select,insert,update,references -tiny tinyint(4) NULL MUL 0 select,insert,update,references -short smallint(6) NULL MUL 0 select,insert,update,references -medium mediumint(8) NULL MUL 0 select,insert,update,references -long_int int(11) NULL 0 select,insert,update,references -longlong bigint(13) NULL MUL 0 select,insert,update,references -real_float float(13,1) NULL MUL 0.0 select,insert,update,references +tiny tinyint(4) NULL NO MUL 0 select,insert,update,references +short smallint(6) NULL NO MUL 0 select,insert,update,references +medium mediumint(8) NULL NO MUL 0 select,insert,update,references +long_int int(11) NULL NO 0 select,insert,update,references +longlong bigint(13) NULL NO MUL 0 select,insert,update,references +real_float float(13,1) NULL NO MUL 0.0 select,insert,update,references real_double double(16,4) NULL YES NULL select,insert,update,references -utiny tinyint(3) unsigned NULL 0 select,insert,update,references -ushort smallint(5) unsigned zerofill NULL 00000 select,insert,update,references -umedium mediumint(8) unsigned NULL MUL 0 select,insert,update,references -ulong int(11) unsigned NULL MUL 0 select,insert,update,references -ulonglong bigint(13) unsigned NULL MUL 0 select,insert,update,references +utiny tinyint(3) unsigned NULL NO 0 select,insert,update,references +ushort smallint(5) unsigned zerofill NULL NO 00000 select,insert,update,references +umedium mediumint(8) unsigned NULL NO MUL 0 select,insert,update,references +ulong int(11) unsigned NULL NO MUL 0 select,insert,update,references +ulonglong bigint(13) unsigned NULL NO MUL 0 select,insert,update,references time_stamp timestamp NULL YES CURRENT_TIMESTAMP select,insert,update,references date_field char(10) latin1_swedish_ci YES NULL select,insert,update,references time_field time NULL YES NULL select,insert,update,references date_time datetime NULL YES NULL select,insert,update,references new_blob_col varchar(20) latin1_swedish_ci YES NULL select,insert,update,references tinyblob_col tinyblob NULL YES NULL select,insert,update,references -mediumblob_col mediumblob NULL select,insert,update,references -options enum('one','two','tree') latin1_swedish_ci MUL one select,insert,update,references -flags set('one','two','tree') latin1_swedish_ci select,insert,update,references -new_field char(10) latin1_swedish_ci new select,insert,update,references +mediumblob_col mediumblob NULL NO select,insert,update,references +options enum('one','two','tree') latin1_swedish_ci NO MUL one select,insert,update,references +flags set('one','two','tree') latin1_swedish_ci NO select,insert,update,references +new_field char(10) latin1_swedish_ci NO new select,insert,update,references show full columns from t2; Field Type Collation Null Key Default Extra Privileges Comment -auto int(5) unsigned NULL 0 select,insert,update,references +auto int(5) unsigned NULL NO 0 select,insert,update,references string char(10) latin1_swedish_ci YES new defaul select,insert,update,references -tiny tinyint(4) NULL 0 select,insert,update,references -short smallint(6) NULL 0 select,insert,update,references -medium mediumint(8) NULL 0 select,insert,update,references -long_int int(11) NULL 0 select,insert,update,references -longlong bigint(13) NULL 0 select,insert,update,references -real_float float(13,1) NULL 0.0 select,insert,update,references +tiny tinyint(4) NULL NO 0 select,insert,update,references +short smallint(6) NULL NO 0 select,insert,update,references +medium mediumint(8) NULL NO 0 select,insert,update,references +long_int int(11) NULL NO 0 select,insert,update,references +longlong bigint(13) NULL NO 0 select,insert,update,references +real_float float(13,1) NULL NO 0.0 select,insert,update,references real_double double(16,4) NULL YES NULL select,insert,update,references -utiny tinyint(3) unsigned NULL 0 select,insert,update,references -ushort smallint(5) unsigned zerofill NULL 00000 select,insert,update,references -umedium mediumint(8) unsigned NULL 0 select,insert,update,references -ulong int(11) unsigned NULL 0 select,insert,update,references -ulonglong bigint(13) unsigned NULL 0 select,insert,update,references +utiny tinyint(3) unsigned NULL NO 0 select,insert,update,references +ushort smallint(5) unsigned zerofill NULL NO 00000 select,insert,update,references +umedium mediumint(8) unsigned NULL NO 0 select,insert,update,references +ulong int(11) unsigned NULL NO 0 select,insert,update,references +ulonglong bigint(13) unsigned NULL NO 0 select,insert,update,references time_stamp timestamp NULL YES 0000-00-00 00:00:00 select,insert,update,references date_field char(10) latin1_swedish_ci YES NULL select,insert,update,references time_field time NULL YES NULL select,insert,update,references date_time datetime NULL YES NULL select,insert,update,references new_blob_col varchar(20) latin1_swedish_ci YES NULL select,insert,update,references tinyblob_col tinyblob NULL YES NULL select,insert,update,references -mediumblob_col mediumblob NULL select,insert,update,references -options enum('one','two','tree') latin1_swedish_ci one select,insert,update,references -flags set('one','two','tree') latin1_swedish_ci select,insert,update,references -new_field char(10) latin1_swedish_ci new select,insert,update,references +mediumblob_col mediumblob NULL NO select,insert,update,references +options enum('one','two','tree') latin1_swedish_ci NO one select,insert,update,references +flags set('one','two','tree') latin1_swedish_ci NO select,insert,update,references +new_field char(10) latin1_swedish_ci NO new select,insert,update,references select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null))); auto auto 16 16 @@ -268,15 +268,15 @@ drop table t2; create table t2 (primary key (auto)) select auto+1 as auto,1 as t1, 'a' as t2, repeat('a',256) as t3, binary repeat('b',256) as t4, repeat('a',4096) as t5, binary repeat('b',4096) as t6, '' as t7, binary '' as t8 from t1; show full columns from t2; Field Type Collation Null Key Default Extra Privileges Comment -auto bigint(17) unsigned NULL PRI 0 select,insert,update,references -t1 bigint(1) NULL 0 select,insert,update,references -t2 varchar(1) latin1_swedish_ci select,insert,update,references -t3 varchar(256) latin1_swedish_ci select,insert,update,references -t4 varbinary(256) NULL select,insert,update,references -t5 longtext latin1_swedish_ci select,insert,update,references -t6 longblob NULL select,insert,update,references -t7 char(0) latin1_swedish_ci select,insert,update,references -t8 binary(0) NULL select,insert,update,references +auto bigint(17) unsigned NULL NO PRI 0 select,insert,update,references +t1 bigint(1) NULL NO 0 select,insert,update,references +t2 varchar(1) latin1_swedish_ci NO select,insert,update,references +t3 varchar(256) latin1_swedish_ci NO select,insert,update,references +t4 varbinary(256) NULL NO select,insert,update,references +t5 longtext latin1_swedish_ci NO select,insert,update,references +t6 longblob NULL NO select,insert,update,references +t7 char(0) latin1_swedish_ci NO select,insert,update,references +t8 binary(0) NULL NO select,insert,update,references select t1,t2,length(t3),length(t4),length(t5),length(t6),t7,t8 from t2; t1 t2 length(t3) length(t4) length(t5) length(t6) t7 t8 1 a 256 256 4096 4096 @@ -297,7 +297,7 @@ show full columns from t3; Field Type Collation Null Key Default Extra Privileges Comment c1 int(11) NULL YES NULL select,insert,update,references c2 int(11) NULL YES NULL select,insert,update,references -const bigint(1) NULL 0 select,insert,update,references +const bigint(1) NULL NO 0 select,insert,update,references drop table t1,t2,t3; create table t1 ( myfield INT NOT NULL, UNIQUE INDEX (myfield), unique (myfield), index(myfield)); drop table t1; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 1f44ad49812..123967f1c4a 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -34,8 +34,8 @@ select table_name from information_schema.TABLES where table_schema = "testtets" and table_name like "t%"; select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; -show keys * where TABLE_SCHEMA Like "test%"; -show keys where INDEX_NAME = "a_data"; +show keys * from t3 where TABLE_SCHEMA Like "test%"; +show keys from t3 where INDEX_NAME = "a_data"; show tables like 't%'; --replace_column 15 # 16 # @@ -48,7 +48,7 @@ show full columns from mysql.db like "Insert%"; show full columns from v1; select * from information_schema.COLUMNS where table_name="t1" and column_name= "a"; -show columns * where table_name = "t1"; +show columns * from testtets.t1 where table_name = "t1"; drop view v1; drop tables testtets.t4, testtets.t1, t2, t3; @@ -198,7 +198,7 @@ create procedure px5 () begin declare v int; declare c cursor for select version from -information_schema.tables; +information_schema.tables where table_schema <> 'information_schema'; open c; fetch c into v; select v; @@ -250,10 +250,6 @@ from information_schema.columns where table_name = 'proc'; select * from t115; drop table t115; -create view vk as select count(*) from information_schema.tables a; -select * from vk; -drop view vk; - delimiter //; create procedure p108 () begin declare c cursor for select data_type from information_schema.columns; open c; open c; end;// @@ -274,3 +270,19 @@ TABLE_NAME= "vo"; select * from information_schema.KEY_COLUMN_USAGE where TABLE_NAME= "vo"; drop view vo; + +select TABLE_NAME,TABLE_TYPE,ENGINE +from information_schema.tables +where table_schema='information_schema' limit 2; +show tables from information_schema like "t%"; + +--error 1007 +create database information_schema; +use information_schema; +show full tables like "T%"; +--error 1109 +create table t1(a int); +use test; +show tables; +use information_schema; +show tables like "T%"; diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp index c8d4d85bedf..ad84390a9e5 100644 --- a/ndb/test/ndbapi/flex_bench_mysql.cpp +++ b/ndb/test/ndbapi/flex_bench_mysql.cpp @@ -397,6 +397,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) ndbout << "Connect failed" <options.port; if (!unix_socket) unix_socket=mysql->options.unix_socket; + + /* + By default we don't reconnect because it could silently corrupt data (after + reconnection you potentially lose table locks, user variables, session + variables (transactions but they are specifically dealt with in + mysql_reconnect()). + This is a change: < 5.0.3 mysql->reconnect was set to 1 by default. + How this change impacts existing apps: + - existing apps which relyed on the default will see a behaviour change; + they will have to set reconnect=1 after mysql_real_connect(). + - existing apps which explicitely asked for reconnection (the only way they + could do it was by setting mysql.reconnect to 1 after mysql_real_connect()) + will not see a behaviour change. + - existing apps which explicitely asked for no reconnection + (mysql.reconnect=0) will not see a behaviour change. + */ + mysql->reconnect= 0; - mysql->reconnect=1; /* Reconnect as default */ mysql->server_status=SERVER_STATUS_AUTOCOMMIT; /* @@ -2161,6 +2177,7 @@ my_bool mysql_reconnect(MYSQL *mysql) strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate); DBUG_RETURN(1); } + tmp_mysql.reconnect= 1; tmp_mysql.free_me= mysql->free_me; /* Don't free options as these are now used in tmp_mysql */ bzero((char*) &mysql->options,sizeof(mysql->options)); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index f759be59ffb..b7575f3a44e 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -709,6 +709,7 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) if (!mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) DBUG_RETURN(1); + mysql->reconnect= 1; DBUG_RETURN(0); } diff --git a/sql/slave.cc b/sql/slave.cc index 1e38d92ebc5..9ddbe7d05de 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4394,6 +4394,7 @@ replication resumed in log '%s' at position %s", mi->user, thd->set_active_vio(mysql->net.vio); #endif } + mysql->reconnect= 1; DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed)); DBUG_RETURN(slave_was_killed); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8be915b89e2..d33faffb2c2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4670,9 +4670,15 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) if (!(user=grant_table->user)) user= ""; ulong table_access= grant_table->privs; - if (table_access != 0) + if (table_access) { ulong test_access= table_access & ~GRANT_ACL; + /* + We should skip 'usage' privilege on table if + we have any privileges on column(s) of this table + */ + if (!test_access && grant_table->cols) + continue; if (!(table_access & GRANT_ACL)) is_grantable= "NO"; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 3e606029bec..ea81013a401 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -389,6 +389,13 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, uint create_options= create_info ? create_info->options : 0; uint path_len; DBUG_ENTER("mysql_create_db"); + + /* do not create 'information_schema' db */ + if (!my_strcasecmp(system_charset_info, db, information_schema_name.str)) + { + my_error(ER_DB_CREATE_EXISTS, MYF(0), db); + DBUG_RETURN(-1); + } VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); @@ -1015,6 +1022,7 @@ bool mysql_change_db(THD *thd, const char *name) char *dbname=my_strdup((char*) name,MYF(MY_WME)); char path[FN_REFLEN]; HA_CREATE_INFO create; + bool schema_db= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; #endif @@ -1034,6 +1042,15 @@ bool mysql_change_db(THD *thd, const char *name) DBUG_RETURN(1); } DBUG_PRINT("info",("Use database: %s", dbname)); + if (!my_strcasecmp(system_charset_info, dbname, information_schema_name.str)) + { + schema_db= 1; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + db_access= SELECT_ACL; +#endif + goto end; + } + #ifndef NO_EMBEDDED_ACCESS_CHECKS if (test_all_bits(thd->master_access,DB_ACLS)) db_access=DB_ACLS; @@ -1064,6 +1081,7 @@ bool mysql_change_db(THD *thd, const char *name) my_free(dbname,MYF(0)); DBUG_RETURN(1); } +end: send_ok(thd); x_free(thd->db); thd->db=dbname; // THD::~THD will free this @@ -1071,11 +1089,19 @@ bool mysql_change_db(THD *thd, const char *name) #ifndef NO_EMBEDDED_ACCESS_CHECKS thd->db_access=db_access; #endif - strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); - thd->db_charset= create.default_table_charset ? - create.default_table_charset : - thd->variables.collation_server; - thd->variables.collation_database= thd->db_charset; + if (schema_db) + { + thd->db_charset= system_charset_info; + thd->variables.collation_database= system_charset_info; + } + else + { + strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); + load_db_opt(thd, path, &create); + thd->db_charset= create.default_table_charset ? + create.default_table_charset : + thd->variables.collation_server; + thd->variables.collation_database= thd->db_charset; + } DBUG_RETURN(0); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7acbe564f58..7cc746793dc 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1941,6 +1941,60 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table) } +/* + Add 'information_schema' name to db_names list + + SYNOPSIS + schema_db_add() + thd thread handler + files list of db names + wild wild string + with_i_schema returns 1 if we added 'IS' name to list + otherwise returns 0 + + RETURN + 1 error + 0 success +*/ + +int schema_db_add(THD *thd, List *files, + const char *wild, bool *with_i_schema) +{ + *with_i_schema= 0; + if (!wild || !wild_compare(information_schema_name.str, wild, 0)) + { + *with_i_schema= 1; + if (files->push_back(thd->strdup(information_schema_name.str))) + return 1; + } + return 0; +} + + +int schema_tables_add(THD *thd, List *files, const char *wild) +{ + ST_SCHEMA_TABLE *tmp_schema_table= schema_tables; + for ( ; tmp_schema_table->table_name; tmp_schema_table++) + { + if (wild) + { + if (lower_case_table_names) + { + if (wild_case_compare(files_charset_info, + tmp_schema_table->table_name, + wild)) + continue; + } + else if (wild_compare(tmp_schema_table->table_name, wild, 0)) + continue; + } + if (files->push_back(thd->strdup(tmp_schema_table->table_name))) + return 1; + } + return 0; +} + + int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; @@ -1970,8 +2024,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) SELECT_LEX sel; INDEX_FIELD_VALUES idx_field_vals; - char path[FN_REFLEN], *end, *base_name, *file_name; - uint len; + char path[FN_REFLEN], *end= 0, *base_name, *file_name; + uint len= 0; + bool with_i_schema; List bases; lex->all_selects_list= &sel; enum enum_schema_tables schema_table_idx= @@ -1980,6 +2035,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (schema_table_idx == SCH_TABLES) lock_type= TL_READ; get_index_field_values(lex, &idx_field_vals); + + /* information schema name always is first in list */ + if (schema_db_add(thd, &bases, idx_field_vals.db_value, &with_i_schema)) + return 1; + if (mysql_find_files(thd, &bases, NullS, mysql_data_home, idx_field_vals.db_value, 1)) return 1; @@ -1995,19 +2055,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) (base_name= select_lex->db) && !bases.elements)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!check_access(thd,SELECT_ACL, base_name, &thd->col_access,0,1) || + if (with_i_schema || // don't check the rights if information schema db + !check_access(thd,SELECT_ACL, base_name, &thd->col_access,0,1) || thd->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) || (grant_option && !check_grant_db(thd, base_name))) #endif { List files; - strxmov(path, mysql_data_home, "/", base_name, NullS); - end= path + (len= unpack_dirname(path,path)); - len= FN_LEN - len; - if (mysql_find_files(thd, &files, base_name, - path, idx_field_vals.table_value, 0)) - DBUG_RETURN(1); + if (with_i_schema) // information schema table names + { + if (schema_tables_add(thd, &files, idx_field_vals.table_value)) + DBUG_RETURN(1); + } + else + { + strxmov(path, mysql_data_home, "/", base_name, NullS); + end= path + (len= unpack_dirname(path,path)); + len= FN_LEN - len; + if (mysql_find_files(thd, &files, base_name, + path, idx_field_vals.table_value, 0)) + DBUG_RETURN(1); + } List_iterator_fast it(files); while ((file_name=it++)) @@ -2023,20 +2092,27 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { if (lex->verbose || lex->orig_sql_command == SQLCOM_END) { - my_snprintf(end, len, "/%s%s", file_name, reg_ext); - switch (mysql_frm_type(path)) + if (with_i_schema) { - case FRMTYPE_ERROR: - table->field[3]->store("ERROR", 5, system_charset_info); - break; - case FRMTYPE_TABLE: - table->field[3]->store("BASE TABLE", 10, system_charset_info); - break; - case FRMTYPE_VIEW: - table->field[3]->store("VIEW", 4, system_charset_info); - break; - default: - DBUG_ASSERT(0); + table->field[3]->store("TEMPORARY", 9, system_charset_info); + } + else + { + my_snprintf(end, len, "/%s%s", file_name, reg_ext); + switch (mysql_frm_type(path)) + { + case FRMTYPE_ERROR: + table->field[3]->store("ERROR", 5, system_charset_info); + break; + case FRMTYPE_TABLE: + table->field[3]->store("BASE TABLE", 10, system_charset_info); + break; + case FRMTYPE_VIEW: + table->field[3]->store("VIEW", 4, system_charset_info); + break; + default: + DBUG_ASSERT(0); + } } } table->file->write_row(table->record[0]); @@ -2059,6 +2135,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } } } + with_i_schema= 0; } } lex->all_selects_list= select_lex; @@ -2066,6 +2143,16 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } +void store_schema_shemata(TABLE *table, const char *db_name, + const char* cs_name) +{ + restore_record(table, default_values); + table->field[1]->store(db_name, strlen(db_name), system_charset_info); + table->field[2]->store(cs_name, strlen(cs_name), system_charset_info); + table->file->write_row(table->record[0]); +} + + int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) { char path[FN_REFLEN],*end; @@ -2074,16 +2161,26 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) List files; char *file_name; uint length; + bool with_i_schema; HA_CREATE_INFO create; TABLE *table= tables->table; get_index_field_values(thd->lex, &idx_field_vals); + /* information schema name always is first in list */ + if (schema_db_add(thd, &files, idx_field_vals.db_value, &with_i_schema)) + return 1; if (mysql_find_files(thd, &files, NullS, mysql_data_home, idx_field_vals.db_value, 1)) return 1; List_iterator_fast it(files); while ((file_name=it++)) { + if (with_i_schema) // information schema name is always first in list + { + store_schema_shemata(table, file_name, system_charset_info->csname); + with_i_schema= 0; + continue; + } #ifndef NO_EMBEDDED_ACCESS_CHECKS if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) || @@ -2103,12 +2200,8 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) path[length-1]= FN_LIBCHAR; strmov(path+length, MY_DB_OPT_FILE); load_db_opt(thd, path, &create); - restore_record(table, default_values); - table->field[1]->store(file_name, strlen(file_name), system_charset_info); - table->field[2]->store(create.default_table_charset->csname, - strlen(create.default_table_charset->csname), - system_charset_info); - table->file->write_row(table->record[0]); + store_schema_shemata(table, file_name, + create.default_table_charset->csname); } } return 0; @@ -2147,7 +2240,11 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, TABLE *show_table= tables->table; handler *file= show_table->file; file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); - table->field[3]->store("BASE TABLE", 10, cs); + if (table->tmp_table == TMP_TABLE) + table->field[3]->store("TEMPORARY", 9, cs); + else + table->field[3]->store("BASE TABLE", 10, cs); + for (int i= 4; i < 20; i++) { if ((i > 12 && i < 17) || i == 18) @@ -2341,7 +2438,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, } pos=(byte*) ((flags & NOT_NULL_FLAG) && field->type() != FIELD_TYPE_TIMESTAMP ? - "" : "YES"); + "NO" : "YES"); table->field[6]->store((const char*) pos, strlen((const char*) pos), cs); if (field->has_charset()) @@ -2741,12 +2838,26 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, } +void store_constarints(TABLE *table, const char*db, const char *tname, + const char *key_name, uint key_len, + const char *con_type, uint con_len) +{ + CHARSET_INFO *cs= system_charset_info; + restore_record(table, default_values); + table->field[1]->store(db, strlen(db), cs); + table->field[2]->store(key_name, key_len, cs); + table->field[3]->store(db, strlen(db), cs); + table->field[4]->store(tname, strlen(tname), cs); + table->field[5]->store(con_type, con_len, cs); + table->file->write_row(table->record[0]); +} + + static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, TABLE *table, bool res, const char *base_name, const char *file_name) { - CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_constarints_record"); if (!res && !tables->view) { @@ -2760,17 +2871,14 @@ static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, for (uint i=0 ; i < show_table->keys ; i++, key_info++) { if (i != primary_key && !(key_info->flags & HA_NOSAME)) - continue; - restore_record(table, default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(key_info->name, strlen(key_info->name), cs); - table->field[3]->store(base_name, strlen(base_name), cs); - table->field[4]->store(file_name, strlen(file_name), cs); + continue; + if (i == primary_key && !strcmp(key_info->name, primary_key_name)) - table->field[5]->store("PRIMARY KEY", 11, cs); + store_constarints(table, base_name, file_name, key_info->name, + strlen(key_info->name), "PRIMARY KEY", 11); else if (key_info->flags & HA_NOSAME) - table->field[5]->store("UNIQUE", 6, cs); - table->file->write_row(table->record[0]); + store_constarints(table, base_name, file_name, key_info->name, + strlen(key_info->name), "UNIQUE", 6); } show_table->file->get_foreign_key_list(thd, &f_key_list); @@ -2778,23 +2886,28 @@ static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, List_iterator_fast it(f_key_list); while ((f_key_info=it++)) { - restore_record(table, default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(f_key_info->forein_id->str, - f_key_info->forein_id->length, cs); - table->field[3]->store(base_name, strlen(base_name), cs); - table->field[4]->store(file_name, strlen(file_name), cs); - table->field[5]->store("FOREIGN KEY", 11, system_charset_info); - table->field[6]->store(f_key_info->constraint_method->str, - f_key_info->constraint_method->length, cs); - table->field[6]->set_notnull(); - table->file->write_row(table->record[0]); + store_constarints(table, base_name, file_name, f_key_info->forein_id->str, + strlen(f_key_info->forein_id->str), "FOREIGN KEY", 11); } } DBUG_RETURN(res); } +void store_key_column_usage(TABLE *table, const char*db, const char *tname, + const char *key_name, uint key_len, + const char *con_type, uint con_len, longlong idx) +{ + CHARSET_INFO *cs= system_charset_info; + table->field[1]->store(db, strlen(db), cs); + table->field[2]->store(key_name, key_len, cs); + table->field[4]->store(db, strlen(db), cs); + table->field[5]->store(tname, strlen(tname), cs); + table->field[6]->store(con_type, con_len, cs); + table->field[7]->store((longlong) idx); +} + + static int get_schema_key_column_usage_record(THD *thd, struct st_table_list *tables, TABLE *table, bool res, @@ -2825,13 +2938,12 @@ static int get_schema_key_column_usage_record(THD *thd, { f_idx++; restore_record(table, default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(key_info->name, strlen(key_info->name), cs); - table->field[4]->store(base_name, strlen(base_name), cs); - table->field[5]->store(file_name, strlen(file_name), cs); - table->field[6]->store(key_part->field->field_name, - strlen(key_part->field->field_name), cs); - table->field[7]->store((longlong) f_idx); + store_key_column_usage(table, base_name, file_name, + key_info->name, + strlen(key_info->name), + key_part->field->field_name, + strlen(key_part->field->field_name), + (longlong) f_idx); table->file->write_row(table->record[0]); } } @@ -2851,21 +2963,21 @@ static int get_schema_key_column_usage_record(THD *thd, r_info= it1++; f_idx++; restore_record(table, default_values); - table->field[1]->store(base_name, strlen(base_name), cs); - table->field[2]->store(f_key_info->forein_id->str, - f_key_info->forein_id->length, cs); - table->field[4]->store(base_name, strlen(base_name), cs); - table->field[5]->store(file_name, strlen(file_name), cs); - table->field[6]->store(f_info->str, f_info->length, cs); - table->field[7]->store((longlong) f_idx); - table->field[8]->store(f_key_info->referenced_db->str, + store_key_column_usage(table, base_name, file_name, + f_key_info->forein_id->str, + f_key_info->forein_id->length, + f_info->str, f_info->length, + (longlong) f_idx); + table->field[8]->store((longlong) f_idx); + table->field[8]->set_notnull(); + table->field[9]->store(f_key_info->referenced_db->str, f_key_info->referenced_db->length, cs); table->field[9]->set_notnull(); table->field[10]->store(f_key_info->referenced_table->str, f_key_info->referenced_table->length, cs); - table->field[9]->set_notnull(); - table->field[10]->store(r_info->str, r_info->length, cs); table->field[10]->set_notnull(); + table->field[11]->store(r_info->str, r_info->length, cs); + table->field[11]->set_notnull(); table->file->write_row(table->record[0]); } } @@ -3466,7 +3578,6 @@ ST_FIELD_INFO table_constraints_fields_info[]= {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, - {"CONSTRAINT_METHOD", 20, MYSQL_TYPE_STRING, 0, 1, 0}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3481,6 +3592,7 @@ ST_FIELD_INFO key_column_usage_fields_info[]= {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0}, + {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0}, {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8b3cdda5d9e..3511777dd27 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -670,7 +670,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_table_alias %type - table_ident table_ident_nodb references from_table_ident + table_ident table_ident_nodb references %type remember_name remember_end opt_ident opt_db text_or_password @@ -5902,14 +5902,14 @@ show_param: | ENGINE_SYM storage_engines { Lex->create_info.db_type= $2; } show_engine_param - | opt_full COLUMNS ext_select_item_list from_table_ident opt_db wild_and_where + | opt_full COLUMNS ext_select_item_list from_or_in table_ident opt_db wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SELECT; lex->orig_sql_command= SQLCOM_SHOW_FIELDS; - if ($5) - $4->change_db($5); - if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS)) + if ($6) + $5->change_db($6); + if (prepare_schema_table(YYTHD, lex, $5, SCH_COLUMNS)) YYABORT; } | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ @@ -5935,14 +5935,14 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; } opt_limit_clause_init - | keys_or_index ext_select_item_list from_table_ident opt_db where_clause + | keys_or_index ext_select_item_list from_or_in table_ident opt_db where_clause { LEX *lex= Lex; lex->sql_command= SQLCOM_SELECT; lex->orig_sql_command= SQLCOM_SHOW_KEYS; - if ($4) - $3->change_db($4); - if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS)) + if ($5) + $4->change_db($5); + if (prepare_schema_table(YYTHD, lex, $4, SCH_STATISTICS)) YYABORT; } | COLUMN_SYM TYPES_SYM @@ -6159,11 +6159,6 @@ binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } | FROM ulonglong_num { Lex->mi.pos = $2; }; -from_table_ident: - /* empty */ { $$= 0; } - | from_or_in table_ident { $$= $2; } - ; - wild_and_where: /* empty */ | LIKE TEXT_STRING_sys diff --git a/tests/client_test.c b/tests/client_test.c index e6a530f786a..979c1563c02 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -243,6 +243,7 @@ static void client_connect() fprintf(stdout, "\n Check the connection options using --help or -?\n"); exit(1); } + mysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -1057,6 +1058,7 @@ static my_bool thread_query(char *query) error= 1; goto end; } + l_mysql->reconnect= 1; if (mysql_query(l_mysql, (char *)query)) { fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql)); @@ -4481,6 +4483,7 @@ static void test_stmt_close() myerror("connection failed"); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -5372,6 +5375,7 @@ DROP TABLE IF EXISTS test_multi_tab"; fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local)); exit(1); } + mysql_local->reconnect= 1; rc= mysql_query(mysql_local, query); myquery(rc); @@ -5480,6 +5484,7 @@ static void test_prepare_multi_statements() fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local)); exit(1); } + mysql_local->reconnect= 1; strmov(query, "select 1; select 'another value'"); stmt= mysql_simple_prepare(mysql_local, query); check_stmt_r(stmt); @@ -7012,6 +7017,7 @@ static void test_prepare_grant() mysql_close(lmysql); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -7457,6 +7463,7 @@ static void test_drop_temp() mysql_close(lmysql); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); diff --git a/tests/connect_test.c b/tests/connect_test.c index fd81ad635ad..c68ade9f78f 100644 --- a/tests/connect_test.c +++ b/tests/connect_test.c @@ -46,6 +46,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + sock->reconnect= 1; if (mysql_select_db(sock,"test")) { diff --git a/tests/deadlock_test.c b/tests/deadlock_test.c index 65a0df5c215..ab8158e0cd8 100644 --- a/tests/deadlock_test.c +++ b/tests/deadlock_test.c @@ -227,6 +227,7 @@ int main() !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) || !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 )) die("Error in mysql_real_connect(): %s", mysql_error(&lock)); + lock.reconnect= sel.reconnect= del_ins.reconnect= 1; permute(order, num_queries); printf("count = %d\n", count); diff --git a/tests/insert_test.c b/tests/insert_test.c index 052c12bfdf0..2b659e9eecb 100644 --- a/tests/insert_test.c +++ b/tests/insert_test.c @@ -40,6 +40,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; num = atoi(argv[2]); count = 0; diff --git a/tests/list_test.c b/tests/list_test.c index 06bf16d2751..1d50e703133 100644 --- a/tests/list_test.c +++ b/tests/list_test.c @@ -43,6 +43,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; if (mysql_select_db(sock,argv[1]) < 0) { diff --git a/tests/select_test.c b/tests/select_test.c index ee2a9192865..64c4fec5167 100644 --- a/tests/select_test.c +++ b/tests/select_test.c @@ -44,6 +44,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); diff --git a/tests/showdb_test.c b/tests/showdb_test.c index df2b3037c00..08229fc51ee 100644 --- a/tests/showdb_test.c +++ b/tests/showdb_test.c @@ -45,6 +45,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); diff --git a/tests/ssl_test.c b/tests/ssl_test.c index b18e493c267..85f490cb02e 100644 --- a/tests/ssl_test.c +++ b/tests/ssl_test.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); while (count < num) diff --git a/tests/thread_test.c b/tests/thread_test.c index 06f335fe1a6..f8577857d0a 100644 --- a/tests/thread_test.c +++ b/tests/thread_test.c @@ -55,6 +55,7 @@ unsigned __stdcall test_thread(void *arg __attribute__((unused))) perror(""); goto end; } + mysql.reconnect= 1; if (verbose) { putchar('*'); fflush(stdout); } for (count=0 ; count < number_of_tests ; count++) { diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c index bb0a76d6c49..1be0242c505 100644 --- a/tools/mysqlmanager.c +++ b/tools/mysqlmanager.c @@ -877,7 +877,10 @@ static void manager_exec_connect(struct manager_exec* e) { if (mysql_real_connect(&e->mysql,e->con_host,e->con_user,e->con_pass,0, e->con_port,e->con_sock,0)) + { + e->mysql.reconnect= 1; return; + } sleep(1); } e->error="Could not connect to MySQL server withing the number of tries";