diff options
Diffstat (limited to 'innobase/include')
70 files changed, 599 insertions, 1759 deletions
diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am index 8664f6dfc17..2584357e24a 100644 --- a/innobase/include/Makefile.am +++ b/innobase/include/Makefile.am @@ -18,21 +18,20 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ btr0pcur.h btr0pcur.ic btr0sea.h btr0sea.ic btr0types.h \ buf0buf.h buf0buf.ic buf0flu.h buf0flu.ic buf0lru.h \ - buf0lru.ic buf0rea.h buf0types.h com0com.h com0com.ic \ - com0shm.h com0shm.ic data0data.h data0data.ic data0type.h \ + buf0lru.ic buf0rea.h buf0types.h data0data.h data0data.ic data0type.h \ data0type.ic data0types.h db0err.h dict0boot.h \ dict0boot.ic dict0crea.h dict0crea.ic dict0dict.h \ dict0dict.ic dict0load.h dict0load.ic dict0mem.h \ dict0mem.ic dict0types.h dyn0dyn.h dyn0dyn.ic eval0eval.h \ eval0eval.ic eval0proc.h eval0proc.ic fil0fil.h fsp0fsp.h \ fsp0fsp.ic fut0fut.h fut0fut.ic fut0lst.h fut0lst.ic \ - ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic ib_odbc.h \ + ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic \ ibuf0ibuf.h ibuf0ibuf.ic ibuf0types.h lock0lock.h \ lock0lock.ic lock0types.h log0log.h log0log.ic log0recv.h \ log0recv.ic mach0data.h mach0data.ic makefilewin.i \ mem0dbg.h mem0dbg.ic mem0mem.h mem0mem.ic mem0pool.h \ mem0pool.ic mtr0log.h mtr0log.ic mtr0mtr.h mtr0mtr.ic \ - mtr0types.h odbc0odbc.h os0file.h os0proc.h os0proc.ic \ + mtr0types.h os0file.h os0proc.h os0proc.ic \ os0shm.h os0shm.ic os0sync.h os0sync.ic os0thread.h \ os0thread.ic page0cur.h page0cur.ic page0page.h \ page0page.ic page0types.h pars0grm.h pars0opt.h \ @@ -50,7 +49,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ thr0loc.h thr0loc.ic trx0purge.h trx0purge.ic trx0rec.h \ trx0rec.ic trx0roll.h trx0roll.ic trx0rseg.h trx0rseg.ic \ trx0sys.h trx0sys.ic trx0trx.h trx0trx.ic trx0types.h \ - trx0undo.h trx0undo.ic univ.i univold.i univoldmysql.i \ + trx0undo.h trx0undo.ic univ.i \ usr0sess.h usr0sess.ic usr0types.h ut0byte.h ut0byte.ic \ ut0dbg.h ut0lst.h ut0mem.h ut0mem.ic ut0rnd.h ut0rnd.ic \ ut0sort.h ut0ut.h ut0ut.ic diff --git a/innobase/include/btr0btr.ic b/innobase/include/btr0btr.ic index 301a73b3444..b0aa0756307 100644 --- a/innobase/include/btr0btr.ic +++ b/innobase/include/btr0btr.ic @@ -45,8 +45,7 @@ btr_page_set_index_id( dulint id, /* in: index id */ mtr_t* mtr) /* in: mtr */ { - mlog_write_dulint(page + PAGE_HEADER + PAGE_INDEX_ID, id, - MLOG_8BYTES, mtr); + mlog_write_dulint(page + PAGE_HEADER + PAGE_INDEX_ID, id, mtr); } /****************************************************************** diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index 31aecef8104..f1334656d53 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -365,17 +365,6 @@ btr_cur_parse_update_in_place( byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ page_t* page); /* in: page or NULL */ -/*************************************************************** -Parses a redo log record of updating a record, but not in-place. */ - -byte* -btr_cur_parse_opt_update( -/*=====================*/ - /* out: end of log record or NULL */ - byte* ptr, /* in: buffer */ - byte* end_ptr,/* in: buffer end */ - page_t* page, /* in: page or NULL */ - mtr_t* mtr); /* in: mtr or NULL */ /******************************************************************** Parses the redo log record for delete marking or unmarking of a clustered index record. */ @@ -446,16 +435,6 @@ btr_cur_mark_dtuple_inherited_extern( ulint n_ext_vec, /* in: number of elements in ext_vec */ upd_t* update); /* in: update vector */ /*********************************************************************** -Marks all extern fields in a record as owned by the record. This function -should be called if the delete mark of a record is removed: a not delete -marked record always owns all its extern fields. */ - -void -btr_cur_unmark_extern_fields( -/*=========================*/ - rec_t* rec, /* in: record in a clustered index */ - mtr_t* mtr); /* in: mtr */ -/*********************************************************************** Marks all extern fields in a dtuple as owned by the record. */ void diff --git a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h index ee762a12221..ce4140ecf92 100644 --- a/innobase/include/btr0sea.h +++ b/innobase/include/btr0sea.h @@ -49,21 +49,6 @@ btr_search_info_update( dict_index_t* index, /* in: index of the cursor */ btr_cur_t* cursor);/* in: cursor which was just positioned */ /********************************************************************** -Tries to guess the right search position based on the search pattern info -of the index. */ - -ibool -btr_search_guess_on_pattern( -/*========================*/ - /* out: TRUE if succeeded */ - dict_index_t* index, /* in: index */ - btr_search_t* info, /* in: index search info */ - dtuple_t* tuple, /* in: logical record */ - ulint mode, /* in: PAGE_CUR_L, ... */ - ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */ - btr_cur_t* cursor, /* out: tree cursor */ - mtr_t* mtr); /* in: mtr */ -/********************************************************************** Tries to guess the right search position based on the hash search info of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts, and the function returns TRUE, then cursor->up_match and cursor->low_match @@ -140,26 +125,6 @@ btr_search_update_hash_on_delete( record to delete using btr_cur_search_..., the record is not yet deleted */ /************************************************************************ -Prints info of the search system. */ - -void -btr_search_print_info(void); -/*=======================*/ -/************************************************************************ -Prints info of searches on an index. */ - -void -btr_search_index_print_info( -/*========================*/ - dict_index_t* index); /* in: index */ -/************************************************************************ -Prints info of searches on a table. */ - -void -btr_search_table_print_info( -/*========================*/ - char* name); /* in: table name */ -/************************************************************************ Validates the search system. */ ibool @@ -249,7 +214,9 @@ extern rw_lock_t* btr_search_latch_temp; #define btr_search_latch (*btr_search_latch_temp) +#ifdef UNIV_SEARCH_PERF_STAT extern ulint btr_search_n_succ; +#endif /* UNIV_SEARCH_PERF_STAT */ extern ulint btr_search_n_hash_fail; /* After change in n_fields or n_bytes in info, this many rounds are waited diff --git a/innobase/include/btr0sea.ic b/innobase/include/btr0sea.ic index 63a3a658cf4..8a41042f713 100644 --- a/innobase/include/btr0sea.ic +++ b/innobase/include/btr0sea.ic @@ -44,8 +44,10 @@ btr_search_info_update( { btr_search_t* info; - ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED) - && !rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#ifdef UNIV_SYNC_DEBUG + ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); + ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ info = btr_search_get_info(index); diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 3f2fd5bbbe0..3cab717546a 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -562,11 +562,11 @@ buf_awe_map_page_to_frame( we need to map the page should also add the block to the awe_LRU_free_mapped list */ +#ifdef UNIV_SYNC_DEBUG /************************************************************************* Adds latch level info for the rw-lock protecting the buffer frame. This should be called in the debug version after a successful latching of a -page if we know the latching order level of the acquired latch. If -UNIV_SYNC_DEBUG is not defined, compiles to an empty function. */ +page if we know the latching order level of the acquired latch. */ UNIV_INLINE void buf_page_dbg_add_level( @@ -574,6 +574,7 @@ buf_page_dbg_add_level( buf_frame_t* frame, /* in: buffer page where we have acquired a latch */ ulint level); /* in: latching order level */ +#endif /* UNIV_SYNC_DEBUG */ /************************************************************************* Gets a pointer to the memory frame of a block. */ UNIV_INLINE diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index eb22bae7ff0..cb54785128f 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -130,7 +130,9 @@ buf_pool_clock_tic(void) /*====================*/ /* out: new clock value */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); +#endif /* UNIV_SYNC_DEBUG */ buf_pool->ulint_clock++; @@ -221,7 +223,7 @@ buf_block_align( "InnoDB: how to force recovery.\n", (long)ptr, (long)frame_zero, (long)(buf_pool->high_end)); - ut_a(0); + ut_error; } block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero)) @@ -257,7 +259,7 @@ buf_frame_align( "InnoDB: how to force recovery.\n", (long)ptr, (long)(buf_pool->frame_zero), (long)(buf_pool->high_end)); - ut_a(0); + ut_error; } return(frame); @@ -447,8 +449,10 @@ buf_frame_modify_clock_inc( block = buf_block_align(frame); +#ifdef UNIV_SYNC_DEBUG ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0)) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); +#endif /*UNIV_SYNC_DEBUG */ UT_DULINT_INC(block->modify_clock); @@ -466,8 +470,10 @@ buf_block_modify_clock_inc( /* out: new value */ buf_block_t* block) /* in: block */ { +#ifdef UNIV_SYNC_DEBUG ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0)) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); +#endif /* UNIV_SYNC_DEBUG */ UT_DULINT_INC(block->modify_clock); @@ -490,12 +496,15 @@ buf_frame_get_modify_clock( block = buf_block_align(frame); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); +#endif /* UNIV_SYNC_DEBUG */ return(block->modify_clock); } +#ifdef UNIV_SYNC_DEBUG /*********************************************************************** Increments the bufferfix count. */ UNIV_INLINE @@ -515,7 +524,7 @@ buf_block_buf_fix_inc_debug( #endif block->buf_fix_count++; } - +#else /* UNIV_SYNC_DEBUG */ /*********************************************************************** Increments the bufferfix count. */ UNIV_INLINE @@ -526,7 +535,7 @@ buf_block_buf_fix_inc( { block->buf_fix_count++; } - +#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** Returns the control block of a file page, NULL if not found. */ UNIV_INLINE @@ -541,7 +550,9 @@ buf_page_hash_get( ulint fold; ut_ad(buf_pool); +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); +#endif /* UNIV_SYNC_DEBUG */ /* Look for the page in the hash table */ @@ -641,6 +652,7 @@ buf_page_release( } } +#ifdef UNIV_SYNC_DEBUG /************************************************************************* Adds latch level info for the rw-lock protecting the buffer frame. This should be called in the debug version after a successful latching of a @@ -655,7 +667,6 @@ buf_page_dbg_add_level( ulint level __attribute__((unused))) /* in: latching order level */ { -#ifdef UNIV_SYNC_DEBUG sync_thread_add_level(&(buf_block_align(frame)->lock), level); -#endif } +#endif /* UNIV_SYNC_DEBUG */ diff --git a/innobase/include/buf0flu.ic b/innobase/include/buf0flu.ic index e2faf773cab..d6dbdcc0865 100644 --- a/innobase/include/buf0flu.ic +++ b/innobase/include/buf0flu.ic @@ -40,8 +40,10 @@ buf_flush_note_modification( ut_ad(block); ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->buf_fix_count > 0); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(mutex_own(&(buf_pool->mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(ut_dulint_cmp(mtr->start_lsn, ut_dulint_zero) != 0); ut_ad(mtr->modifications); @@ -76,7 +78,9 @@ buf_flush_recv_note_modification( ut_ad(block); ut_ad(block->state == BUF_BLOCK_FILE_PAGE); ut_ad(block->buf_fix_count > 0); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ mutex_enter(&(buf_pool->mutex)); diff --git a/innobase/include/com0com.h b/innobase/include/com0com.h deleted file mode 100644 index 6f04b6a3f11..00000000000 --- a/innobase/include/com0com.h +++ /dev/null @@ -1,125 +0,0 @@ -/****************************************************** -The communication primitives - -(c) 1995 Innobase Oy - -Created 9/23/1995 Heikki Tuuri -*******************************************************/ - -/* This module defines a standard datagram communication -function interface for use in the database. We assume that -the communication medium is reliable. */ - -#ifndef com0com_h -#define com0com_h - -#include "univ.i" - -/* The communications endpoint type definition */ -typedef struct com_endpoint_struct com_endpoint_t; - -/* Possible endpoint communication types */ -#define COM_SHM 1 /* communication through shared memory */ - -/* Option numbers for endpoint */ -#define COM_OPT_MAX_DGRAM_SIZE 1 - -/* Error numbers */ -#define COM_ERR_NOT_SPECIFIED 1 -#define COM_ERR_NOT_BOUND 2 -#define COM_ERR_ALREADY_BOUND 3 -#define COM_ERR_MAX_DATAGRAM_SIZE_NOT_SET 4 -#define COM_ERR_DATA_BUFFER_TOO_SMALL 5 -#define COM_ERR_ADDR_BUFFER_TOO_SMALL 6 -#define COM_ERR_DATA_TOO_LONG 7 -#define COM_ERR_ADDR_TOO_LONG 8 -#define COM_ERR_DGRAM_NOT_DELIVERED 9 - -/* Maximum allowed address length in bytes */ -#define COM_MAX_ADDR_LEN 100 - -/************************************************************************* -Creates a communications endpoint. */ - -com_endpoint_t* -com_endpoint_create( -/*================*/ - /* out, own: communications endpoint, NULL if - did not succeed */ - ulint type); /* in: communication type of endpoint: - only COM_SHM supported */ -/************************************************************************* -Frees a communications endpoint. */ - -ulint -com_endpoint_free( -/*==============*/ - /* out: O if succeed, else error number */ - com_endpoint_t* ep); /* in, own: communications endpoint */ -/************************************************************************* -Sets an option, like the maximum datagram size for an endpoint. -The options may vary depending on the endpoint type. */ - -ulint -com_endpoint_set_option( -/*====================*/ - /* out: 0 if succeed, else error number */ - com_endpoint_t* ep, /* in: endpoint */ - ulint optno, /* in: option number, only - COM_OPT_MAX_DGRAM_SIZE currently supported */ - byte* optval, /* in: pointer to a buffer containing the - option value to set */ - ulint optlen);/* in: option value buffer length */ -/************************************************************************* -Binds a communications endpoint to a specified address. */ - -ulint -com_bind( -/*=====*/ - /* out: 0 if succeed, else error number */ - com_endpoint_t* ep, /* in: communications endpoint */ - char* name, /* in: address name */ - ulint len); /* in: name length */ -/************************************************************************* -Waits for a datagram to arrive at an endpoint. */ - -ulint -com_recvfrom( -/*=========*/ - /* out: 0 if succeed, else error number */ - com_endpoint_t* ep, /* in: communications endpoint */ - byte* buf, /* out: datagram buffer; the buffer must be - supplied by the caller */ - ulint buf_len,/* in: datagram buffer length */ - ulint* len, /* out: datagram length */ - char* from, /* out: address name buffer; the buffer must be - supplied by the caller */ - ulint from_len,/* in: address name buffer length */ - ulint* addr_len);/* out: address name length */ -/************************************************************************* -Sends a datagram to a specified destination. */ - -ulint -com_sendto( -/*=======*/ - /* out: 0 if succeed, else error number */ - com_endpoint_t* ep, /* in: communications endpoint */ - byte* buf, /* in: datagram buffer */ - ulint len, /* in: datagram length */ - char* to, /* in: address name buffer */ - ulint tolen); /* in: address name length */ -/************************************************************************* -Gets the maximum datagram size for an endpoint. */ - -ulint -com_endpoint_get_max_size( -/*======================*/ - /* out: maximum size */ - com_endpoint_t* ep); /* in: endpoint */ - - -#ifndef UNIV_NONINL -#include "com0com.ic" -#endif - -#endif diff --git a/innobase/include/com0com.ic b/innobase/include/com0com.ic deleted file mode 100644 index cec1cb190cc..00000000000 --- a/innobase/include/com0com.ic +++ /dev/null @@ -1,7 +0,0 @@ -/****************************************************** -The communication primitives - -(c) 1995 Innobase Oy - -Created 9/23/1995 Heikki Tuuri -*******************************************************/ diff --git a/innobase/include/com0shm.h b/innobase/include/com0shm.h deleted file mode 100644 index 7de9c4ac2de..00000000000 --- a/innobase/include/com0shm.h +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************** -The communication through shared memory - -(c) 1995 Innobase Oy - -Created 9/23/1995 Heikki Tuuri -*******************************************************/ - -#ifndef com0shm_h -#define com0shm_h - -#include "univ.i" - -typedef struct com_shm_endpoint_struct com_shm_endpoint_t; - -/* The performance of communication in NT depends on how -many times a system call is made (excluding os_thread_yield, -as that is the fastest way to switch thread). -The following variable counts such events. */ - -extern ulint com_shm_system_call_count; - - -/************************************************************************* -Creates a communications endpoint. */ - -com_shm_endpoint_t* -com_shm_endpoint_create(void); -/*=========================*/ - /* out, own: communications endpoint, NULL if - did not succeed */ -/************************************************************************* -Frees a communications endpoint. */ - -ulint -com_shm_endpoint_free( -/*==================*/ - /* out: O if succeed, else error number */ - com_shm_endpoint_t* ep);/* in, own: communications endpoint */ -/************************************************************************* -Sets an option, like the maximum datagram size for an endpoint. -The options may vary depending on the endpoint type. */ - -ulint -com_shm_endpoint_set_option( -/*========================*/ - /* out: 0 if succeed, else error number */ - com_shm_endpoint_t* ep, /* in: endpoint */ - ulint optno, /* in: option number, only - COM_OPT_MAX_DGRAM_SIZE currently supported */ - byte* optval, /* in: pointer to a buffer containing the - option value to set */ - ulint optlen);/* in: option value buffer length */ -/************************************************************************* -Bind a communications endpoint to a specified address. */ - -ulint -com_shm_bind( -/*=========*/ - /* out: 0 if succeed, else error number */ - com_shm_endpoint_t* ep, /* in: communications endpoint */ - char* name, /* in: address name */ - ulint len); /* in: address name length */ -/************************************************************************* -Waits for a datagram to arrive at an endpoint. */ - -ulint -com_shm_recvfrom( -/*=============*/ - /* out: 0 if succeed, else error number */ - com_shm_endpoint_t* ep, /* in: communications endpoint */ - byte* buf, /* out: datagram buffer; the buffer is - supplied by the caller */ - ulint buf_len,/* in: datagram buffer length */ - ulint* len, /* out: datagram length */ - char* from, /* out: address name buffer; the buffer is - supplied by the caller */ - ulint from_len,/* in: address name buffer length */ - ulint* addr_len);/* out: address name length */ -/************************************************************************* -Sends a datagram to the specified destination. */ - -ulint -com_shm_sendto( -/*===========*/ - /* out: 0 if succeed, else error number */ - com_shm_endpoint_t* ep, /* in: communications endpoint */ - byte* buf, /* in: datagram buffer */ - ulint len, /* in: datagram length */ - char* to, /* in: address name buffer */ - ulint tolen); /* in: address name length */ - -ulint -com_shm_endpoint_get_size( -/*======================*/ - com_shm_endpoint_t* ep); - - -#ifndef UNIV_NONINL -#include "com0shm.ic" -#endif - -#endif diff --git a/innobase/include/com0shm.ic b/innobase/include/com0shm.ic deleted file mode 100644 index e0d3cb26f69..00000000000 --- a/innobase/include/com0shm.ic +++ /dev/null @@ -1,7 +0,0 @@ -/****************************************************** -Communication through shared memory - -(c) 1995 Innobase Oy - -Created 9/23/1995 Heikki Tuuri -*******************************************************/ diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index 889d148d3fe..c4e93bec738 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -262,6 +262,14 @@ dtuple_set_types_binary( /*====================*/ dtuple_t* tuple, /* in: data tuple */ ulint n); /* in: number of fields to set */ +/************************************************************************** +Checks if a dtuple contains an SQL null value. */ +UNIV_INLINE +ibool +dtuple_contains_null( +/*=================*/ + /* out: TRUE if some field is SQL null */ + dtuple_t* tuple); /* in: dtuple */ /************************************************************** Checks that a data field is typed. Asserts an error if not. */ @@ -367,84 +375,6 @@ dtuple_big_rec_free( /*================*/ big_rec_t* vector); /* in, own: big rec vector; it is freed in this function */ -/*************************************************************** -Generates a random tuple. */ - -dtuple_t* -dtuple_gen_rnd_tuple( -/*=================*/ - /* out: pointer to the tuple */ - mem_heap_t* heap); /* in: memory heap where generated */ -/******************************************************************* -Generates a test tuple for sort and comparison tests. */ - -void -dtuple_gen_test_tuple( -/*==================*/ - dtuple_t* tuple, /* in/out: a tuple with 3 fields */ - ulint i); /* in: a number, 0 <= i < 512 */ -/******************************************************************* -Generates a test tuple for B-tree speed tests. */ - -void -dtuple_gen_test_tuple3( -/*===================*/ - dtuple_t* tuple, /* in/out: a tuple with 3 fields */ - ulint i, /* in: a number < 1000000 */ - ulint type, /* in: DTUPLE_TEST_FIXED30, ... */ - byte* buf); /* in: a buffer of size >= 8 bytes */ -/******************************************************************* -Generates a test tuple for B-tree speed tests. */ - -void -dtuple_gen_search_tuple3( -/*=====================*/ - dtuple_t* tuple, /* in/out: a tuple with 1 or 2 fields */ - ulint i, /* in: a number < 1000000 */ - byte* buf); /* in: a buffer of size >= 8 bytes */ -/******************************************************************* -Generates a test tuple for TPC-A speed test. */ - -void -dtuple_gen_test_tuple_TPC_A( -/*========================*/ - dtuple_t* tuple, /* in/out: a tuple with >= 3 fields */ - ulint i, /* in: a number < 10000 */ - byte* buf); /* in: a buffer of size >= 16 bytes */ -/******************************************************************* -Generates a test tuple for B-tree speed tests. */ - -void -dtuple_gen_search_tuple_TPC_A( -/*==========================*/ - dtuple_t* tuple, /* in/out: a tuple with 1 field */ - ulint i, /* in: a number < 10000 */ - byte* buf); /* in: a buffer of size >= 16 bytes */ -/******************************************************************* -Generates a test tuple for TPC-C speed test. */ - -void -dtuple_gen_test_tuple_TPC_C( -/*========================*/ - dtuple_t* tuple, /* in/out: a tuple with >= 12 fields */ - ulint i, /* in: a number < 100000 */ - byte* buf); /* in: a buffer of size >= 16 bytes */ -/******************************************************************* -Generates a test tuple for B-tree speed tests. */ - -void -dtuple_gen_search_tuple_TPC_C( -/*==========================*/ - dtuple_t* tuple, /* in/out: a tuple with 1 field */ - ulint i, /* in: a number < 100000 */ - byte* buf); /* in: a buffer of size >= 16 bytes */ - -/* Types of the third field in dtuple_gen_test_tuple3 */ -#define DTUPLE_TEST_FIXED30 1 -#define DTUPLE_TEST_RND30 2 -#define DTUPLE_TEST_RND3500 3 -#define DTUPLE_TEST_FIXED2000 4 -#define DTUPLE_TEST_FIXED3 5 /*######################################################################*/ @@ -472,9 +402,11 @@ struct dtuple_struct { UT_LIST_NODE_T(dtuple_t) tuple_list; /* data tuples can be linked into a list using this field */ - ulint magic_n; -}; +#ifdef UNIV_DEBUG + ulint magic_n; #define DATA_TUPLE_MAGIC_N 65478679 +#endif /* UNIV_DEBUG */ +}; /* A slot for a field in a big rec vector */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index d356664df21..def80d3f430 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -406,3 +406,28 @@ data_write_sql_null( data[j] = '\0'; } } + +/************************************************************************** +Checks if a dtuple contains an SQL null value. */ +UNIV_INLINE +ibool +dtuple_contains_null( +/*=================*/ + /* out: TRUE if some field is SQL null */ + dtuple_t* tuple) /* in: dtuple */ +{ + ulint n; + ulint i; + + n = dtuple_get_n_fields(tuple); + + for (i = 0; i < n; i++) { + if (dfield_get_len(dtuple_get_nth_field(tuple, i)) + == UNIV_SQL_NULL) { + + return(TRUE); + } + } + + return(FALSE); +} diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index f202230bb94..2b27ead5fac 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -11,6 +11,9 @@ Created 1/16/1996 Heikki Tuuri #include "univ.i" +extern ulint data_mysql_default_charset_coll; +extern ulint data_mysql_latin1_swedish_charset_coll; + /* SQL data type struct */ typedef struct dtype_struct dtype_t; @@ -18,31 +21,79 @@ typedef struct dtype_struct dtype_t; data type */ extern dtype_t* dtype_binary; -/* Data main types of SQL data */ -#define DATA_VARCHAR 1 /* character varying */ -#define DATA_CHAR 2 /* fixed length character */ +/*-------------------------------------------*/ +/* The 'MAIN TYPE' of a column */ +#define DATA_VARCHAR 1 /* character varying of the + latin1_swedish_ci charset-collation */ +#define DATA_CHAR 2 /* fixed length character of the + latin1_swedish_ci charset-collation */ #define DATA_FIXBINARY 3 /* binary string of fixed length */ #define DATA_BINARY 4 /* binary string */ -#define DATA_BLOB 5 /* binary large object, or a TEXT type; if - prtype & DATA_NONLATIN1 != 0 the data must - be compared by MySQL as a whole field; if - prtype & DATA_BINARY_TYPE == 0, then this is - actually a TEXT column */ +#define DATA_BLOB 5 /* binary large object, or a TEXT type; + if prtype & DATA_BINARY_TYPE == 0, then this is + actually a TEXT column (or a BLOB created + with < 4.0.14) */ #define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */ #define DATA_SYS_CHILD 7 /* address of the child page in node pointer */ #define DATA_SYS 8 /* system column */ + /* Data types >= DATA_FLOAT must be compared using the whole field, not as binary strings */ + #define DATA_FLOAT 9 #define DATA_DOUBLE 10 #define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */ -#define DATA_VARMYSQL 12 /* non-latin1 varying length char */ -#define DATA_MYSQL 13 /* non-latin1 fixed length char */ +#define DATA_VARMYSQL 12 /* any charset varying length char */ +#define DATA_MYSQL 13 /* any charset fixed length char */ + /* NOTE that 4.1.1 used DATA_MYSQL and + DATA_VARMYSQL for all character sets, and the + charset-collation for tables created with it + can also be latin1_swedish_ci */ #define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size() requires the values are <= 63 */ /*-------------------------------------------*/ -/* In the lowest byte in the precise type we store the MySQL type code -(not applicable for system columns). */ +/* The 'PRECISE TYPE' of a column */ +/* +Tables created by a MySQL user have the following convention: + +- In the least significant byte in the precise type we store the MySQL type +code (not applicable for system columns). + +- In the second least significant byte we OR flags DATA_NOT_NULL, +DATA_UNSIGNED, DATA_BINARY_TYPE. + +- In the third least significant byte of the precise type of string types we +store the MySQL charset-collation code. In DATA_BLOB columns created with +< 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there +are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no +problem, though. + +Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the +precise type, since the charset was always the default charset of the MySQL +installation. If the stored charset code is 0 in the system table SYS_COLUMNS +of InnoDB, that means that the default charset of this MySQL installation +should be used. + +When loading a table definition from the system tables to the InnoDB data +dictionary cache in main memory, InnoDB versions >= 4.1.2 and >= 5.0.1 check +if the stored charset-collation is 0, and if that is the case and the type is +a non-binary string, replace that 0 by the default charset-collation code of +this MySQL installation. In short, in old tables, the charset-collation code +in the system tables on disk can be 0, but in in-memory data structures +(dtype_t), the charset-collation code is always != 0 for non-binary string +types. + +In new tables, in binary string types, the charset-collation code is the +MySQL code for the 'binary charset', that is, != 0. + +For binary string types and for DATA_CHAR, DATA_VARCHAR, and for those +DATA_BLOB which are binary or have the charset-collation latin1_swedish_ci, +InnoDB performs all comparisons internally, without resorting to the MySQL +comparison functions. This is to save CPU time. + +InnoDB's own internal system tables have different precise types for their +columns, and for them the precise type is usually not used at all. +*/ #define DATA_ENGLISH 4 /* English language character string: this is a relic from pre-MySQL time and only used @@ -69,7 +120,7 @@ be less than 256 */ #define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a compressed dulint form) */ #define DATA_N_SYS_COLS 4 /* number of system columns defined above */ -/*-------------------------------------------*/ + /* Flags ORed to the precise data type */ #define DATA_NOT_NULL 256 /* this is ORed to the precise type when the column is declared as NOT NULL */ @@ -79,20 +130,53 @@ be less than 256 */ string, this is ORed to the precise type: this only holds for tables created with >= MySQL-4.0.14 */ -#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually - TEXT) of a non-latin1 type, this is ORed to - the precise type: this only holds for tables - created with >= MySQL-4.0.14 */ +/* #define DATA_NONLATIN1 2048 This is a relic from < 4.1.2 and < 5.0.1. + In earlier versions this was set for some + BLOB columns. +*/ /*-------------------------------------------*/ /* This many bytes we need to store the type information affecting the alphabetical order for a single field and decide the storage size of an SQL null*/ -#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4 -/* In the >= 4.1.x storage format we need 2 bytes more for the charset */ +#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4 +/* In the >= 4.1.x storage format we add 2 bytes more so that we can also +store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 /************************************************************************* +Checks if a data main type is a string type. Also a BLOB is considered a +string type. */ + +ibool +dtype_is_string_type( +/*=================*/ + /* out: TRUE if string type */ + ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */ +/************************************************************************* +Checks if a type is a binary string type. Note that for tables created with +< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For +those DATA_BLOB columns this function currently returns FALSE. */ + +ibool +dtype_is_binary_string_type( +/*========================*/ + /* out: TRUE if binary string type */ + ulint mtype, /* in: main data type */ + ulint prtype);/* in: precise type */ +/************************************************************************* +Checks if a type is a non-binary string type. That is, dtype_is_string_type is +TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created +with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. +For those DATA_BLOB columns this function currently returns TRUE. */ + +ibool +dtype_is_non_binary_string_type( +/*============================*/ + /* out: TRUE if non-binary string type */ + ulint mtype, /* in: main data type */ + ulint prtype);/* in: precise type */ +/************************************************************************* Sets a data type structure. */ UNIV_INLINE void @@ -126,6 +210,23 @@ dtype_get_prtype( /*=============*/ dtype_t* type); /************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ +UNIV_INLINE +ulint +dtype_get_charset_coll( +/*===================*/ + ulint prtype);/* in: precise data type */ +/************************************************************************* +Forms a precise type from the < 4.1.2 format precise type plus the +charset-collation code. */ + +ulint +dtype_form_prtype( +/*==============*/ + ulint old_prtype, /* in: the MySQL type code and the flags + DATA_BINARY_TYPE etc. */ + ulint charset_coll); /* in: MySQL charset-collation code */ +/************************************************************************* Gets the type length. */ UNIV_INLINE ulint @@ -225,9 +326,8 @@ dtype_print( struct dtype_struct{ ulint mtype; /* main data type */ ulint prtype; /* precise type; MySQL data type */ - ulint chrset; /* MySQL character set code */ - /* remaining two fields do not affect alphabetical ordering: */ + /* the remaining two fields do not affect alphabetical ordering: */ ulint len; /* length */ ulint prec; /* precision */ diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index 5d39b3e430b..946b646ffbf 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -27,7 +27,6 @@ dtype_set( type->prtype = prtype; type->len = len; type->prec = prec; - type->chrset = 0; ut_ad(dtype_validate(type)); } @@ -73,6 +72,17 @@ dtype_get_prtype( } /************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ +UNIV_INLINE +ulint +dtype_get_charset_coll( +/*===================*/ + ulint prtype) /* in: precise data type */ +{ + return((prtype >> 16) & 0xFFUL); +} + +/************************************************************************* Gets the type length. */ UNIV_INLINE ulint @@ -147,20 +157,25 @@ dtype_new_store_for_order_and_null_size( buf[0] = buf[0] | 128; } - if (type->prtype & DATA_NONLATIN1) { - buf[0] = buf[0] | 64; - } + /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) { + buf[0] = buf[0] | 64; + } + */ buf[1] = (byte)(type->prtype & 0xFFUL); mach_write_to_2(buf + 2, type->len & 0xFFFFUL); - mach_write_to_2(buf + 4, type->chrset & 0xFFFFUL); + mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype)); + + /* Note that the second last byte is left unused, because the + charset-collation code is always < 256 */ } /************************************************************************** Reads to a type the stored information which determines its alphabetical -ordering and the storage size of an SQL NULL value. */ +ordering and the storage size of an SQL NULL value. This is the < 4.1.x +storage format. */ UNIV_INLINE void dtype_read_for_order_and_null_size( @@ -177,17 +192,16 @@ dtype_read_for_order_and_null_size( type->prtype = type->prtype | DATA_BINARY_TYPE; } - if (buf[0] & 64) { - type->prtype = type->prtype | DATA_NONLATIN1; - } - type->len = mach_read_from_2(buf + 2); + + type->prtype = dtype_form_prtype(type->prtype, + data_mysql_default_charset_coll); } /************************************************************************** Reads to a type the stored information which determines its alphabetical -ordering and the storage size of an SQL NULL value. This is the 4.1.x storage -format. */ +ordering and the storage size of an SQL NULL value. This is the >= 4.1.x +storage format. */ UNIV_INLINE void dtype_new_read_for_order_and_null_size( @@ -195,6 +209,8 @@ dtype_new_read_for_order_and_null_size( dtype_t* type, /* in: type struct */ byte* buf) /* in: buffer for stored type order info */ { + ulint charset_coll; + ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); type->mtype = buf[0] & 63; @@ -204,14 +220,28 @@ dtype_new_read_for_order_and_null_size( type->prtype = type->prtype | DATA_BINARY_TYPE; } - if (buf[0] & 64) { - type->prtype = type->prtype | DATA_NONLATIN1; - } - type->len = mach_read_from_2(buf + 2); - type->chrset = mach_read_from_2(buf + 4); -} + mach_read_from_2(buf + 4); + + charset_coll = mach_read_from_2(buf + 4); + + if (dtype_is_string_type(type->mtype)) { + ut_a(charset_coll < 256); + + if (charset_coll == 0) { + /* This insert buffer record was inserted with MySQL + version < 4.1.2, and the charset-collation code was not + explicitly stored to dtype->prtype at that time. It + must be the default charset-collation of this MySQL + installation. */ + + charset_coll = data_mysql_default_charset_coll; + } + + type->prtype = dtype_form_prtype(type->prtype, charset_coll); + } +} /*************************************************************************** Returns the size of a fixed size data type, 0 if not a fixed size type. */ @@ -250,7 +280,7 @@ dtype_get_fixed_size( case DATA_VARMYSQL: case DATA_BLOB: return(0); - default: ut_a(0); + default: ut_error; } return(0); diff --git a/innobase/include/dict0crea.h b/innobase/include/dict0crea.h index ccdedff42c8..8b6944fc605 100644 --- a/innobase/include/dict0crea.h +++ b/innobase/include/dict0crea.h @@ -17,15 +17,6 @@ Created 1/8/1996 Heikki Tuuri #include "mtr0mtr.h" /************************************************************************* -Creates the default clustered index for a table: the records are ordered -by row id. */ - -void -dict_create_default_index( -/*======================*/ - dict_table_t* table, /* in: table */ - trx_t* trx); /* in: transaction handle */ -/************************************************************************* Creates a table create graph. */ tab_node_t* @@ -81,12 +72,25 @@ dict_create_or_check_foreign_constraint_tables(void); /*================================================*/ /* out: DB_SUCCESS or error code */ /************************************************************************ -Adds foreign key definitions to data dictionary tables in the database. */ +Adds foreign key definitions to data dictionary tables in the database. We +look at table->foreign_list, and also generate names to constraints that were +not named by the user. A generated constraint has a name of the format +databasename/tablename_ibfk_<number>, where the numbers start from 1, and are +given locally for this table, that is, the number is not global, as in the +old format constraints < 4.0.18 it used to be. */ ulint dict_create_add_foreigns_to_dictionary( /*===================================*/ /* out: error code or DB_SUCCESS */ + ulint start_id,/* in: if we are actually doing ALTER TABLE + ADD CONSTRAINT, we want to generate constraint + numbers which are bigger than in the table so + far; we number the constraints from + start_id + 1 up; start_id should be set to 0 if + we are creating a new table, or if the table + so far has no constraints for which the name + was generated here */ dict_table_t* table, /* in: table */ trx_t* trx); /* in: transaction */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 234dece2cda..688685cff8b 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -26,6 +26,14 @@ Created 1/8/1996 Heikki Tuuri #include "ut0byte.h" #include "trx0types.h" +/************************************************************************ +Get the database name length in a table name. */ + +ulint +dict_get_db_name_len( +/*=================*/ + /* out: database name length */ + char* name); /* in: table name in the form dbname '/' tablename */ /************************************************************************* Accepts a specified string. Comparisons are case-insensitive. */ @@ -217,6 +225,15 @@ dict_foreign_add_to_cache( /* out: DB_SUCCESS or error code */ dict_foreign_t* foreign); /* in, own: foreign key constraint */ /************************************************************************* +Checks if a table is referenced by foreign keys. */ + +ibool +dict_table_referenced_by_foreign_key( +/*=================================*/ + /* out: TRUE if table is referenced by a + foreign key */ + dict_table_t* table); /* in: InnoDB table */ +/************************************************************************* Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. @@ -476,6 +493,17 @@ dict_table_get_sys_col_no( /* out: column number */ dict_table_t* table, /* in: table */ ulint sys); /* in: DATA_ROW_ID, ... */ +/************************************************************************ +Checks if a column is in the ordering columns of the clustered index of a +table. Column prefixes are treated like whole columns. */ + +ibool +dict_table_col_in_clustered_key( +/*============================*/ + /* out: TRUE if the column, or its prefix, is + in the clustered key */ + dict_table_t* table, /* in: table */ + ulint n); /* in: column number */ /*********************************************************************** Copies types of columns contained in table to tuple. */ @@ -660,13 +688,6 @@ dict_index_get_tree( /* out: index tree */ dict_index_t* index); /* in: index */ /************************************************************************* -Gets the column data type. */ -UNIV_INLINE -dtype_t* -dict_col_get_type( -/*==============*/ - dict_col_t* col); -/************************************************************************* Gets the field order criterion. */ UNIV_INLINE ulint diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index c5982c162a7..b70822e331f 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -543,8 +543,10 @@ dict_table_check_if_in_cache_low( ulint table_fold; ut_ad(table_name); +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); - +#endif /* UNIV_SYNC_DEBUG */ + /* Look for the table name in the hash table */ table_fold = ut_fold_string(table_name); @@ -566,8 +568,10 @@ dict_table_get_low( dict_table_t* table; ut_ad(table_name); +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); - +#endif /* UNIV_SYNC_DEBUG */ + table = dict_table_check_if_in_cache_low(table_name); if (table == NULL) { @@ -621,7 +625,9 @@ dict_table_get_on_id_low( dict_table_t* table; ulint fold; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ UT_NOT_USED(trx); /* Look for the table name in the hash table */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index b18e20a644a..23753df4079 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -198,10 +198,11 @@ struct dict_tree_struct{ the list; if the tree is of the mixed type, the first index in the list is the index of the cluster which owns the tree */ +#ifdef UNIV_DEBUG ulint magic_n;/* magic number */ -}; - #define DICT_TREE_MAGIC_N 7545676 +#endif /* UNIV_DEBUG */ +}; /* Data structure for an index */ struct dict_index_struct{ @@ -247,7 +248,10 @@ struct dict_index_struct{ ulint stat_n_leaf_pages; /* approximate number of leaf pages in the index tree */ +#ifdef UNIV_DEBUG ulint magic_n;/* magic number */ +#define DICT_INDEX_MAGIC_N 76789786 +#endif /* UNIV_DEBUG */ }; /* Data structure for a foreign key constraint; an example: @@ -298,9 +302,6 @@ a foreign key constraint is enforced, therefore RESTRICT just means no flag */ #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 - -#define DICT_INDEX_MAGIC_N 76789786 - /* Data structure for a database table */ struct dict_table_struct{ dulint id; /* id of the table or cluster */ @@ -419,10 +420,12 @@ struct dict_table_struct{ inited; MySQL gets the init value by executing SELECT MAX(auto inc column) */ ib_longlong autoinc;/* autoinc counter value to give to the - next inserted row */ + next inserted row */ +#ifdef UNIV_DEBUG ulint magic_n;/* magic number */ -}; #define DICT_TABLE_MAGIC_N 76333786 +#endif /* UNIV_DEBUG */ +}; /* Data structure for a stored procedure */ struct dict_proc_struct{ diff --git a/innobase/include/fut0fut.ic b/innobase/include/fut0fut.ic index 0f1aa9dd9ae..6a107786376 100644 --- a/innobase/include/fut0fut.ic +++ b/innobase/include/fut0fut.ic @@ -30,7 +30,9 @@ fut_get_ptr( ptr = buf_page_get(space, addr.page, rw_latch, mtr) + addr.boffset; +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(ptr, SYNC_NO_ORDER_CHECK); +#endif /* UNIV_SYNC_DEBUG */ return(ptr); } diff --git a/innobase/include/ha0ha.ic b/innobase/include/ha0ha.ic index 77064cdf9da..5369ca7f273 100644 --- a/innobase/include/ha0ha.ic +++ b/innobase/include/ha0ha.ic @@ -81,7 +81,9 @@ ha_search( { ha_node_t* node; +#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); +#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -111,7 +113,9 @@ ha_search_and_get_data( { ha_node_t* node; +#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); +#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -170,7 +174,9 @@ ha_search_with_data( { ha_node_t* node; +#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); +#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -200,7 +206,9 @@ ha_search_and_delete_if_found( { ha_node_t* node; +#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); +#endif /* UNIV_SYNC_DEBUG */ node = ha_search_with_data(table, fold, data); diff --git a/innobase/include/hash0hash.h b/innobase/include/hash0hash.h index 2e9ab498116..79efe016324 100644 --- a/innobase/include/hash0hash.h +++ b/innobase/include/hash0hash.h @@ -53,15 +53,24 @@ hash_calc_hash( /* out: hashed value */ ulint fold, /* in: folded value */ hash_table_t* table); /* in: hash table */ +/************************************************************************ +Assert that the mutex for the table in a hash operation is owned. */ +#ifdef UNIV_SYNC_DEBUG +# define HASH_ASSERT_OWNED(TABLE, FOLD) \ +ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD))); +#else +# define HASH_ASSERT_OWNED(TABLE, FOLD) +#endif + /*********************************************************************** Inserts a struct to a hash table. */ #define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)\ -{\ +do {\ hash_cell_t* cell3333;\ TYPE* struct3333;\ \ - ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));\ + HASH_ASSERT_OWNED(TABLE, FOLD)\ \ (DATA)->NAME = NULL;\ \ @@ -79,17 +88,17 @@ Inserts a struct to a hash table. */ \ struct3333->NAME = DATA;\ }\ -} +} while (0) /*********************************************************************** Deletes a struct from a hash table. */ #define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)\ -{\ +do {\ hash_cell_t* cell3333;\ TYPE* struct3333;\ \ - ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));\ + HASH_ASSERT_OWNED(TABLE, FOLD)\ \ cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE));\ \ @@ -100,13 +109,13 @@ Deletes a struct from a hash table. */ \ while (struct3333->NAME != DATA) {\ \ - ut_a(struct3333)\ + ut_a(struct3333);\ struct3333 = struct3333->NAME;\ }\ \ struct3333->NAME = DATA->NAME;\ }\ -} +} while (0) /*********************************************************************** Gets the first struct in a hash chain, NULL if none. */ @@ -124,7 +133,7 @@ Looks for a struct in a hash table. */ #define HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)\ {\ \ - ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));\ + HASH_ASSERT_OWNED(TABLE, FOLD)\ \ (DATA) = HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE));\ \ @@ -160,7 +169,7 @@ the heap. The fold value must be stored in the struct NODE in a field named 'fold'. */ #define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE)\ -{\ +do {\ TYPE* node111;\ TYPE* top_node111;\ hash_cell_t* cell111;\ @@ -211,33 +220,7 @@ the heap. The fold value must be stored in the struct NODE in a field named /* Free the space occupied by the top node */\ \ mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));\ -} - -/*********************************************************************** -Calculates the number of stored structs in a hash table. */ - -#define HASH_GET_N_NODES(TYPE, NAME, TABLE, N)\ -{\ - hash_cell_t* cell3333;\ - TYPE* struct3333;\ - ulint i3333;\ -\ - (N) = 0;\ -\ - for (i3333 = 0; i3333 < hash_get_n_cells(TABLE); i3333++) {\ -\ - cell3333 = hash_get_nth_cell(TABLE, i3333);\ -\ - struct3333 = cell3333->node;\ -\ - while (struct3333) {\ -\ - (N) = (N) + 1;\ -\ - struct = HASH_GET_NEXT(NAME, struct3333);\ - }\ - }\ -} +} while (0) /**************************************************************** Gets the mutex index for a fold value in a hash table. */ @@ -300,21 +283,6 @@ hash_mutex_exit( /*============*/ hash_table_t* table, /* in: hash table */ ulint fold); /* in: fold */ -/**************************************************************** -Reserves all the mutexes of a hash table, in an ascending order. */ - -void -hash_mutex_enter_all( -/*=================*/ - hash_table_t* table); /* in: hash table */ -/**************************************************************** -Releases all the mutexes of a hash table. */ - -void -hash_mutex_exit_all( -/*================*/ - hash_table_t* table); /* in: hash table */ - struct hash_cell_struct{ void* node; /* hash chain node, NULL if none */ @@ -335,10 +303,11 @@ struct hash_table_struct { memory heaps; there are then n_mutexes many of these heaps */ mem_heap_t* heap; +#ifdef UNIV_DEBUG ulint magic_n; -}; - #define HASH_TABLE_MAGIC_N 76561114 +#endif /* UNIV_DEBUG */ +}; #ifndef UNIV_NONINL #include "hash0hash.ic" diff --git a/innobase/include/hash0hash.ic b/innobase/include/hash0hash.ic index 0d713140c13..1b9acfa2f34 100644 --- a/innobase/include/hash0hash.ic +++ b/innobase/include/hash0hash.ic @@ -18,6 +18,7 @@ hash_get_nth_cell( hash_table_t* table, /* in: hash table */ ulint n) /* in: cell index */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(n < table->n_cells); return(table->array + n); @@ -32,6 +33,7 @@ hash_get_n_cells( /* out: number of cells */ hash_table_t* table) /* in: table */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(table->n_cells); } @@ -45,6 +47,7 @@ hash_calc_hash( ulint fold, /* in: folded value */ hash_table_t* table) /* in: hash table */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(ut_hash_ulint(fold, table->n_cells)); } @@ -58,6 +61,7 @@ hash_get_mutex_no( hash_table_t* table, /* in: hash table */ ulint fold) /* in: fold */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); return(ut_2pow_remainder(fold, table->n_mutexes)); } @@ -71,6 +75,7 @@ hash_get_nth_heap( hash_table_t* table, /* in: hash table */ ulint i) /* in: index of the heap */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(i < table->n_mutexes); return(table->heaps[i]); @@ -88,6 +93,8 @@ hash_get_heap( { ulint i; + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); + if (table->heap) { return(table->heap); } @@ -107,6 +114,7 @@ hash_get_nth_mutex( hash_table_t* table, /* in: hash table */ ulint i) /* in: index of the mutex */ { + ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ut_ad(i < table->n_mutexes); return(table->mutexes + i); diff --git a/innobase/include/ib_odbc.h b/innobase/include/ib_odbc.h deleted file mode 100644 index 86884b41d39..00000000000 --- a/innobase/include/ib_odbc.h +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************** -Innobase ODBC client library header; this is equivalent to -the standard sql.h ODBC header file - -(c) 1998 Innobase Oy - -Created 2/22/1998 Heikki Tuuri -*******************************************************/ - -#ifndef ib_odbc_h -#define ib_odbc_h - -typedef unsigned char UCHAR; -typedef signed char SCHAR; -typedef long int SDWORD; -typedef short int SWORD; -typedef unsigned long int UDWORD; -typedef unsigned short int UWORD; - -typedef void* PTR; - -typedef void* HENV; -typedef void* HDBC; -typedef void* HSTMT; - -typedef signed short RETCODE; - -/* RETCODEs */ -#define SQL_NO_DATA_FOUND (-3) -#define SQL_INVALID_HANDLE (-2) -#define SQL_ERROR (-1) -#define SQL_SUCCESS 0 - -/* Standard SQL datatypes, using ANSI type numbering */ -#define SQL_CHAR 1 -#define SQL_INTEGER 4 -#define SQL_VARCHAR 12 - -/* C datatype to SQL datatype mapping */ -#define SQL_C_CHAR SQL_CHAR -#define SQL_C_LONG SQL_INTEGER - -/* Special length value */ -#define SQL_NULL_DATA (-1) - -#define SQL_PARAM_INPUT 1 -#define SQL_PARAM_OUTPUT 4 - -/* Null handles */ -#define SQL_NULL_HENV NULL -#define SQL_NULL_HDBC NULL -#define SQL_NULL_HSTM NULL - - -/************************************************************************** -Allocates an SQL environment. */ - -RETCODE -SQLAllocEnv( -/*========*/ - /* out: SQL_SUCCESS */ - HENV* phenv); /* out: pointer to an environment handle */ -/************************************************************************** -Allocates an SQL connection. */ - -RETCODE -SQLAllocConnect( -/*============*/ - /* out: SQL_SUCCESS */ - HENV henv, /* in: pointer to an environment handle */ - HDBC* phdbc); /* out: pointer to a connection handle */ -/************************************************************************** -Allocates an SQL statement. */ - -RETCODE -SQLAllocStmt( -/*=========*/ - HDBC hdbc, /* in: SQL connection */ - HSTMT* phstmt); /* out: pointer to a statement handle */ -/************************************************************************** -Connects to a database server process (establishes a connection and a -session). */ - -RETCODE -SQLConnect( -/*=======*/ - /* out: SQL_SUCCESS */ - HDBC hdbc, /* in: SQL connection handle */ - UCHAR* szDSN, /* in: data source name (server name) */ - SWORD cbDSN, /* in: data source name length */ - UCHAR* szUID, /* in: user name */ - SWORD cbUID, /* in: user name length */ - UCHAR* szAuthStr, /* in: password */ - SWORD cbAuthStr); /* in: password length */ -/************************************************************************** -Makes the server to parse and optimize an SQL string. */ - -RETCODE -SQLPrepare( -/*=======*/ - /* out: SQL_SUCCESS */ - HSTMT hstmt, /* in: statement handle */ - UCHAR* szSqlStr, /* in: SQL string */ - SDWORD cbSqlStr); /* in: SQL string length */ -/************************************************************************** -Binds a parameter in a prepared statement. */ - -RETCODE -SQLBindParameter( -/*=============*/ - /* out: SQL_SUCCESS */ - HSTMT hstmt, /* in: statement handle */ - UWORD ipar, /* in: parameter index, starting from 1 */ - SWORD fParamType, /* in: SQL_PARAM_INPUT or SQL_PARAM_OUTPUT */ - SWORD fCType, /* in: SQL_C_CHAR, ... */ - SWORD fSqlType, /* in: SQL_CHAR, ... */ - UDWORD cbColDef, /* in: precision: ignored */ - SWORD ibScale, /* in: scale: ignored */ - PTR rgbValue, /* in: pointer to a buffer for the data */ - SDWORD cbValueMax, /* in: buffer size */ - SDWORD* pcbValue); /* in: pointer to a buffer for the data - length or SQL_NULL_DATA */ -/************************************************************************** -Executes a prepared statement where all parameters have been bound. */ - -RETCODE -SQLExecute( -/*=======*/ - /* out: SQL_SUCCESS or SQL_ERROR */ - HSTMT hstmt); /* in: statement handle */ -/************************************************************************** -Queries an error message. */ - -RETCODE -SQLError( -/*=====*/ - /* out: SQL_SUCCESS or SQL_NO_DATA_FOUND */ - HENV henv, /* in: SQL_NULL_HENV */ - HDBC hdbc, /* in: SQL_NULL_HDBC */ - HSTMT hstmt, /* in: statement handle */ - UCHAR* szSqlState, /* in/out: SQLSTATE as a null-terminated string, - (currently, always == "S1000") */ - SDWORD* pfNativeError, /* out: native error code */ - UCHAR* szErrorMsg, /* in/out: buffer for an error message as a - null-terminated string */ - SWORD cbErrorMsgMax, /* in: buffer size for szErrorMsg */ - SWORD* pcbErrorMsg); /* out: error message length */ - -#endif diff --git a/innobase/include/ibuf0ibuf.h b/innobase/include/ibuf0ibuf.h index bf03b06bd28..8ef67df26f8 100644 --- a/innobase/include/ibuf0ibuf.h +++ b/innobase/include/ibuf0ibuf.h @@ -177,15 +177,6 @@ ibuf_page_low( mtr_t* mtr); /* in: mtr which will contain an x-latch to the bitmap page if the page is not one of the fixed address ibuf pages */ -/************************************************************************* -Checks if an index page has so much free space that the free bit should -be set TRUE in the ibuf bitmap. */ - -ibool -ibuf_index_page_has_free( -/*=====================*/ - /* out: TRUE if there is enough free space */ - page_t* page); /* in: non-unique secondary index page */ /*************************************************************************** Frees excess pages from the ibuf free list. This function is called when an OS thread calls fsp services to allocate a new file segment, or a new page to a diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 49f4597b30c..103d28cd130 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -442,14 +442,6 @@ lock_rec_hash( ulint space, /* in: space */ ulint page_no);/* in: page number */ /************************************************************************* -Gets the mutex protecting record locks on a given page address. */ - -mutex_t* -lock_rec_get_mutex_for_addr( -/*========================*/ - ulint space, /* in: space id */ - ulint page_no);/* in: page number */ -/************************************************************************* Checks that a transaction id is sensible, i.e., not in the future. */ ibool diff --git a/innobase/include/lock0lock.ic b/innobase/include/lock0lock.ic index 64c43c88d2e..fabc9256401 100644 --- a/innobase/include/lock0lock.ic +++ b/innobase/include/lock0lock.ic @@ -64,7 +64,9 @@ lock_clust_rec_some_has_impl( { dulint trx_id; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(index->type & DICT_CLUSTERED); ut_ad(page_rec_is_user_rec(rec)); diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index dc44429d636..2bdc158502f 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -18,7 +18,9 @@ typedef struct log_struct log_t; typedef struct log_group_struct log_group_t; extern ibool log_do_write; +#ifdef UNIV_LOG_DEBUG extern ibool log_debug_writes; +#endif /* UNIV_LOG_DEBUG */ /* Wait modes for log_write_up_to */ #define LOG_NO_WAIT 91 @@ -719,11 +721,13 @@ struct log_struct{ ulint max_buf_free; /* recommended maximum value of buf_free, after which the buffer is flushed */ +#ifdef UNIV_LOG_DEBUG ulint old_buf_free; /* value of buf free when log was last time opened; only in the debug version */ dulint old_lsn; /* value of lsn when log was last time opened; only in the debug version */ +#endif /* UNIV_LOG_DEBUG */ ibool check_flush_or_checkpoint; /* this is set to TRUE when there may be need to flush the log buffer, or diff --git a/innobase/include/log0log.ic b/innobase/include/log0log.ic index 7ae7e859032..e273b6a292b 100644 --- a/innobase/include/log0log.ic +++ b/innobase/include/log0log.ic @@ -10,6 +10,7 @@ Created 12/9/1995 Heikki Tuuri #include "mach0data.h" #include "mtr0mtr.h" +#ifdef UNIV_LOG_DEBUG /********************************************************** Checks by parsing that the catenated log segment for a single mtr is consistent. */ @@ -21,6 +22,7 @@ log_check_log_recs( in the log_sys->buf log buffer */ ulint len, /* in: segment length in bytes */ dulint buf_start_lsn); /* in: buffer start lsn */ +#endif /* UNIV_LOG_DEBUG */ /**************************************************************** Gets a log block flush bit. */ @@ -255,7 +257,9 @@ log_block_init( { ulint no; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ no = log_block_convert_lsn_to_no(lsn); @@ -277,7 +281,9 @@ log_block_init_in_old_format( { ulint no; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ no = log_block_convert_lsn_to_no(lsn); @@ -407,7 +413,9 @@ log_get_online_backup_lsn_low(void) /* out: online_backup_lsn, the caller must own the log_sys mutex */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(log_sys->online_backup_state); return(log_sys->online_backup_lsn); @@ -422,7 +430,9 @@ log_get_online_backup_state_low(void) /* out: online backup state, the caller must own the log_sys mutex */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ return(log_sys->online_backup_state); } diff --git a/innobase/include/mach0data.h b/innobase/include/mach0data.h index 006f55d5f1f..f28c9422670 100644 --- a/innobase/include/mach0data.h +++ b/innobase/include/mach0data.h @@ -88,25 +88,6 @@ mach_read_from_4( /*=============*/ /* out: ulint integer */ byte* b); /* in: pointer to four bytes */ -/*********************************************************** -The following function is used to store data from a ulint to memory -in standard order: -we store the most significant byte to the lowest address. */ -UNIV_INLINE -void -mach_write( -/*=======*/ - byte* b, /* in: pointer to sizeof(ulint) bytes where to store */ - ulint n); /* in: ulint integer to be stored */ -/************************************************************ -The following function is used to fetch data from memory to a ulint. -The most significant byte is at the lowest address. */ -UNIV_INLINE -ulint -mach_read( -/*======*/ - /* out: ulint integer */ - byte* b); /* in: pointer to sizeof(ulint) bytes */ /************************************************************* Writes a ulint in a compressed form. */ UNIV_INLINE diff --git a/innobase/include/mach0data.ic b/innobase/include/mach0data.ic index 0934c27d9f4..3ccdcf1dc0a 100644 --- a/innobase/include/mach0data.ic +++ b/innobase/include/mach0data.ic @@ -167,44 +167,6 @@ mach_read_from_4( #endif } -/*********************************************************** -The following function is used to store data from a ulint to memory -in standard order: we store the most significant byte to the lowest -address. */ -UNIV_INLINE -void -mach_write( -/*=======*/ - byte* b, /* in: pointer to 4 bytes where to store */ - ulint n) /* in: ulint integer to be stored */ -{ - ut_ad(b); - - b[0] = (byte)(n >> 24); - b[1] = (byte)(n >> 16); - b[2] = (byte)(n >> 8); - b[3] = (byte)n; -} - -/************************************************************ -The following function is used to fetch data from memory to a ulint. -The most significant byte is at the lowest address. */ -UNIV_INLINE -ulint -mach_read( -/*======*/ - /* out: ulint integer */ - byte* b) /* in: pointer to 4 bytes */ -{ - ut_ad(b); - - return( ((ulint)(b[0]) << 24) - + ((ulint)(b[1]) << 16) - + ((ulint)(b[2]) << 8) - + (ulint)(b[3]) - ); -} - /************************************************************* Writes a ulint in a compressed form where the first byte codes the length of the stored ulint. We look at the most significant bits of diff --git a/innobase/include/mem0dbg.h b/innobase/include/mem0dbg.h index 0b1aa53d694..6c92d669be3 100644 --- a/innobase/include/mem0dbg.h +++ b/innobase/include/mem0dbg.h @@ -60,6 +60,7 @@ mem_heap_validate_or_print( ulint* n_blocks); /* out: number of blocks in the heap, if a NULL pointer is passed as this argument, it is ignored */ +#ifdef UNIV_MEM_DEBUG /****************************************************************** Prints the contents of a memory heap. */ @@ -67,6 +68,7 @@ void mem_heap_print( /*===========*/ mem_heap_t* heap); /* in: memory heap */ +#endif /* UNIV_MEM_DEBUG */ /****************************************************************** Checks that an object is a memory heap (or a block of it) */ @@ -83,20 +85,7 @@ mem_heap_validate( /*==============*/ /* out: TRUE if ok */ mem_heap_t* heap); /* in: memory heap */ -/********************************************************************* -Prints information of dynamic memory usage and currently live -memory heaps or buffers. Can only be used in the debug version. */ - -void -mem_print_info(void); -/*=================*/ -/********************************************************************* -Prints information of dynamic memory usage and currently allocated memory -heaps or buffers since the last ..._print_info or..._print_new_info. */ - -void -mem_print_new_info(void); -/*====================*/ +#ifdef UNIV_MEM_DEBUG /********************************************************************* TRUE if no memory is currently allocated. */ @@ -118,6 +107,7 @@ ibool mem_validate(void); /*===============*/ /* out: TRUE if ok */ +#endif /* UNIV_MEM_DEBUG */ /**************************************************************** Tries to find neigboring memory allocation blocks and dumps to stderr the neighborhood of a given pointer. */ diff --git a/innobase/include/mem0dbg.ic b/innobase/include/mem0dbg.ic index 765e23e747e..6efac719760 100644 --- a/innobase/include/mem0dbg.ic +++ b/innobase/include/mem0dbg.ic @@ -7,6 +7,7 @@ compilation module but is included in mem0mem.*. Created 6/8/1994 Heikki Tuuri *************************************************************************/ +#ifdef UNIV_MEM_DEBUG extern mutex_t mem_hash_mutex; extern ulint mem_current_allocated_memory; @@ -89,3 +90,4 @@ mem_field_trailer_set_check(byte* field, ulint check); ulint mem_field_trailer_get_check(byte* field); +#endif /* UNIV_MEM_DEBUG */ diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index 1ff8c66e80a..fb4cef49ec9 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -162,7 +162,7 @@ mem_heap_alloc( mem_block_set_free(block, free + MEM_SPACE_NEEDED(n)); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG /* In the debug version write debugging info to the field */ mem_field_init((byte*)buf, n); @@ -171,7 +171,7 @@ mem_heap_alloc( caller */ buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; - #endif +#endif #ifdef UNIV_SET_MEM_TO_ZERO memset(buf, '\0', n); #endif @@ -212,15 +212,15 @@ mem_heap_free_heap_top( { mem_block_t* block; mem_block_t* prev_block; - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG ibool error; ulint total_size; ulint size; - #endif +#endif ut_ad(mem_heap_check(heap)); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG /* Validate the heap and get its total allocated size */ mem_heap_validate_or_print(heap, NULL, FALSE, &error, &total_size, @@ -232,7 +232,7 @@ mem_heap_free_heap_top( NULL); ut_a(!error); - #endif +#endif block = UT_LIST_GET_LAST(heap->base); @@ -259,7 +259,7 @@ mem_heap_free_heap_top( /* Set the free field of block */ mem_block_set_free(block, old_top - (byte*)block); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); /* In the debug version erase block from top up */ @@ -271,7 +271,7 @@ mem_heap_free_heap_top( mem_current_allocated_memory -= (total_size - size); mutex_exit(&mem_hash_mutex); - #endif +#endif /* If free == start, we may free the block if it is not the first one */ @@ -317,7 +317,7 @@ mem_heap_get_top( buf = (byte*)block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <=(ulint)((byte*)buf - (byte*)block)); /* In the debug version, advance buf to point at the storage which @@ -327,7 +327,7 @@ mem_heap_get_top( /* Check that the field lengths agree */ ut_ad(n == (ulint)mem_field_header_get_len(buf)); - #endif +#endif return(buf); } @@ -351,13 +351,13 @@ mem_heap_free_top( /* Subtract the free field of block */ mem_block_set_free(block, mem_block_get_free(block) - MEM_SPACE_NEEDED(n)); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); /* In the debug version check the consistency, and erase field */ mem_field_erase((byte*)block + mem_block_get_free(block), n); - #endif +#endif /* If free == start, we may free the block if it is not the first one */ @@ -417,7 +417,7 @@ mem_heap_create_func( /* Add the created block itself as the first block in the list */ UT_LIST_ADD_FIRST(list, block->base, block); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG if (block == NULL) { @@ -426,7 +426,7 @@ mem_heap_create_func( mem_hash_insert(block, file_name, line); - #endif +#endif return(block); } @@ -452,14 +452,14 @@ mem_heap_free_func( block = UT_LIST_GET_LAST(heap->base); - #ifdef UNIV_MEM_DEBUG +#ifdef UNIV_MEM_DEBUG /* In the debug version remove the heap from the hash table of heaps and check its consistency */ mem_hash_remove(heap, file_name, line); - #endif +#endif if (heap->free_block) { mem_heap_free_block_free(heap); @@ -493,18 +493,6 @@ mem_alloc_func( ulint line /* in: line where created */ ) { -#ifdef notdefined - void* buf; - - buf = mem_area_alloc(n, mem_comm_pool); - -#ifdef UNIV_SET_MEM_TO_ZERO - memset(buf, '\0', n); -#endif - return(buf); - -#else - mem_heap_t* heap; void* buf; @@ -525,8 +513,6 @@ mem_alloc_func( ut_a((byte*)heap == (byte*)buf - MEM_BLOCK_HEADER_SIZE - MEM_FIELD_HEADER_SIZE); return(buf); - -#endif } /******************************************************************* @@ -542,17 +528,11 @@ mem_free_func( ulint line /* in: line where created */ ) { -#ifdef notdefined - - mem_area_free(ptr, mem_comm_pool); - -#else mem_heap_t* heap; heap = (mem_heap_t*)((byte*)ptr - MEM_BLOCK_HEADER_SIZE - MEM_FIELD_HEADER_SIZE); mem_heap_free_func(heap, file_name, line); -#endif } /********************************************************************* diff --git a/innobase/include/mtr0log.h b/innobase/include/mtr0log.h index da942dd45d7..f50c1dfcb6a 100644 --- a/innobase/include/mtr0log.h +++ b/innobase/include/mtr0log.h @@ -32,7 +32,6 @@ mlog_write_dulint( /*==============*/ byte* ptr, /* in: pointer where to write */ dulint val, /* in: value to write */ - byte type, /* in: MLOG_8BYTES */ mtr_t* mtr); /* in: mini-transaction handle */ /************************************************************ Writes a string to a file page buffered in the buffer pool. Writes the @@ -133,15 +132,6 @@ mlog_write_initial_log_record_fast( byte type, /* in: log item type: MLOG_1BYTE, ... */ byte* log_ptr,/* in: pointer to mtr log which has been opened */ mtr_t* mtr); /* in: mtr */ -/**************************************************************** -Writes the contents of a mini-transaction log, if any, to the database log. */ - -dulint -mlog_write( -/*=======*/ - dyn_array_t* mlog, /* in: mlog */ - ibool* modifications); /* out: TRUE if there were - log items to write */ /************************************************************ Parses an initial log record written by mlog_write_initial_log_record. */ diff --git a/innobase/include/mtr0mtr.h b/innobase/include/mtr0mtr.h index c47fb54a6f8..9cf592f71e1 100644 --- a/innobase/include/mtr0mtr.h +++ b/innobase/include/mtr0mtr.h @@ -132,16 +132,6 @@ void mtr_commit( /*=======*/ mtr_t* mtr); /* in: mini-transaction */ -/**************************************************************** -Writes to the database log the full contents of the pages that this mtr is -the first to modify in the buffer pool. This function is called when the -database is in the online backup state. */ - -void -mtr_log_write_backup_entries( -/*=========================*/ - mtr_t* mtr, /* in: mini-transaction */ - dulint backup_lsn); /* in: online backup lsn */ /************************************************************** Sets and returns a savepoint in mtr. */ UNIV_INLINE @@ -205,7 +195,6 @@ mtr_read_dulint( /*===========*/ /* out: value read */ byte* ptr, /* in: pointer from where to read */ - ulint type, /* in: MLOG_8BYTES */ mtr_t* mtr); /* in: mini-transaction handle */ /************************************************************************* This macro locks an rw-lock in s-mode. */ @@ -306,7 +295,12 @@ struct mtr_memo_slot_struct{ /* Mini-transaction handle and buffer */ struct mtr_struct{ +#ifdef UNIV_DEBUG ulint state; /* MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */ +#define MTR_ACTIVE 12231 +#define MTR_COMMITTING 56456 +#define MTR_COMMITTED 34676 +#endif /* UNIV_DEBUG */ dyn_array_t memo; /* memo stack for locks etc. */ dyn_array_t log; /* mini-transaction log */ ibool modifications; @@ -321,15 +315,12 @@ struct mtr_struct{ this mtr */ dulint end_lsn;/* end lsn of the possible log entry for this mtr */ +#ifdef UNIV_DEBUG ulint magic_n; -}; - #define MTR_MAGIC_N 54551 +#endif /* UNIV_DEBUG */ +}; -#define MTR_ACTIVE 12231 -#define MTR_COMMITTING 56456 -#define MTR_COMMITTED 34676 - #ifndef UNIV_NONINL #include "mtr0mtr.ic" #endif diff --git a/innobase/include/odbc0odbc.h b/innobase/include/odbc0odbc.h deleted file mode 100644 index 7f842b54b27..00000000000 --- a/innobase/include/odbc0odbc.h +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************** -Innobase ODBC client library additional header - -(c) 1998 Innobase Oy - -Created 2/22/1998 Heikki Tuuri -*******************************************************/ - -#ifndef odbc0odbc_h -#define odbc0odbc_h - -#include "ib_odbc.h" - -/* Datagram size in communications */ -#define ODBC_DATAGRAM_SIZE 8192 - -/* Communication address maximum length in bytes */ -#define ODBC_ADDRESS_SIZE COM_MAX_ADDR_LEN - -#endif diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 5f2d6e3ed21..813e6e72e65 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -20,6 +20,9 @@ extern ibool os_do_not_call_flush_at_each_write; extern ibool os_has_said_disk_full; extern ibool os_aio_print_debug; +extern ulint os_file_n_pending_preads; +extern ulint os_file_n_pending_pwrites; + #ifdef __WIN__ /* We define always WIN_ASYNC_IO, and check at run-time whether @@ -60,6 +63,7 @@ log. */ #define OS_FILE_CREATE 52 #define OS_FILE_OVERWRITE 53 #define OS_FILE_OPEN_RAW 54 +#define OS_FILE_CREATE_PATH 55 #define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_WRITE 444 @@ -228,7 +232,9 @@ os_file_create_simple( string */ ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error) */ + file is created (if exists, error), or + OS_FILE_CREATE_PATH if new file (if exists, error) and + subdirectories along its path are created (if needed)*/ ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ ibool* success);/* out: TRUE if succeed, FALSE if error */ /******************************************************************** @@ -421,6 +427,59 @@ os_file_write( ulint offset_high,/* in: most significant 32 bits of offset */ ulint n); /* in: number of bytes to write */ +/*********************************************************************** +Check the existence and type of the given file. */ + +ibool +os_file_status( +/*===========*/ + /* out: TRUE if call succeeded */ + char * path, /* in: pathname of the file */ + ibool * exists, /* out: TRUE if file exists */ + os_file_type_t* type); /* out: type of the file (if it exists) */ +/******************************************************************** +The function os_file_dirname returns a directory component of a +null-terminated pathname string. In the usual case, dirname returns +the string up to, but not including, the final '/', and basename +is the component following the final '/'. Trailing '/' charac +ters are not counted as part of the pathname. + +If path does not contain a slash, dirname returns the string ".". + +Concatenating the string returned by dirname, a "/", and the basename +yields a complete pathname. + +The return value is a copy of the directory component of the pathname. +The copy is allocated from heap. It is the caller responsibility +to free it after it is no longer needed. + +The following list of examples (taken from SUSv2) shows the strings +returned by dirname and basename for different paths: + + path dirname basename + "/usr/lib" "/usr" "lib" + "/usr/" "/" "usr" + "usr" "." "usr" + "/" "/" "/" + "." "." "." + ".." "." ".." +*/ + +char* +os_file_dirname( +/*============*/ + /* out, own: directory component of the + pathname */ + char* path); /* in: pathname */ +/******************************************************************** +Creates all missing subdirectories along the given path. */ + +ibool +os_file_create_subdirs_if_needed( +/*=============================*/ + /* out: TRUE if call succeeded + FALSE otherwise */ + char* path); /* in: path name */ /**************************************************************************** Initializes the asynchronous io system. Creates separate aio array for non-ibuf read and write, a third aio array for the ibuf i/o, with just one diff --git a/innobase/include/os0proc.h b/innobase/include/os0proc.h index 664952bd166..d0d3cf82e38 100644 --- a/innobase/include/os0proc.h +++ b/innobase/include/os0proc.h @@ -102,37 +102,6 @@ os_mem_alloc_nocache( /*=================*/ /* out: allocated memory */ ulint n); /* in: number of bytes */ -#ifdef notdefined -/******************************************************************** -Creates a new process. */ - -ibool -os_process_create( -/*==============*/ - char* name, /* in: name of the executable to start - or its full path name */ - char* cmd, /* in: command line for the starting - process, or NULL if no command line - specified */ - os_process_t* proc, /* out: handle to the process */ - os_process_id_t* id); /* out: process id */ -/************************************************************************** -Exits a process. */ - -void -os_process_exit( -/*============*/ - ulint code); /* in: exit code */ -/************************************************************************** -Gets process exit code. */ - -ibool -os_process_get_exit_code( -/*=====================*/ - /* out: TRUE if succeed, FALSE if fail */ - os_process_t proc, /* in: handle to the process */ - ulint* code); /* out: exit code */ -#endif /******************************************************************** Sets the priority boost for threads released from waiting within the current process. */ diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h index 554ca0563e4..6603229e524 100644 --- a/innobase/include/os0thread.h +++ b/innobase/include/os0thread.h @@ -99,13 +99,6 @@ os_thread_t os_thread_get_curr(void); /*====================*/ /********************************************************************* -Waits for a thread to terminate. */ - -void -os_thread_wait( -/*===========*/ - os_thread_t thread); /* in: thread to wait */ -/********************************************************************* Advises the os to give up remainder of the thread's time slice. */ void diff --git a/innobase/include/page0cur.h b/innobase/include/page0cur.h index c3f0decdb4b..c85669ed4df 100644 --- a/innobase/include/page0cur.h +++ b/innobase/include/page0cur.h @@ -32,8 +32,11 @@ Created 10/4/1994 Heikki Tuuri which extend it */ #define PAGE_CUR_DBG 6 - +#ifdef PAGE_CUR_ADAPT +# ifdef UNIV_SEARCH_PERF_STAT extern ulint page_cur_short_succ; +# endif /* UNIV_SEARCH_PERF_STAT */ +#endif /* PAGE_CUR_ADAPT */ /************************************************************* Gets pointer to the page frame where the cursor is positioned. */ diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index e08b071e246..8ff226ebbd0 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -21,7 +21,9 @@ extern int yydebug; /* If the following is set TRUE, the lexer will print the SQL string as it tokenizes it */ +#ifdef UNIV_SQL_DEBUG extern ibool pars_print_lexed; +#endif /* UNIV_SQL_DEBUG */ /* Global variable used while parsing a single procedure or query : the code is NOT re-entrant */ @@ -390,41 +392,18 @@ pars_procedure_definition( table */ sym_node_t* param_list, /* in: parameter declaration list */ que_node_t* stat_list); /* in: statement list */ -/***************************************************************** -Reads stored procedure input parameter values from a buffer. */ - -void -pars_proc_read_input_params_from_buf( -/*=================================*/ - que_t* graph, /* in: query graph which contains a stored procedure */ - byte* buf); /* in: buffer */ -/***************************************************************** -Writes stored procedure output parameter values to a buffer. */ -ulint -pars_proc_write_output_params_to_buf( -/*=================================*/ - byte* buf, /* in: buffer which must be big enough */ - que_t* graph); /* in: query graph which contains a stored procedure */ /***************************************************************** Parses a stored procedure call, when this is not within another stored -procedure, that is, the client issues a procedure call directly. */ +procedure, that is, the client issues a procedure call directly. +In MySQL/InnoDB, stored InnoDB procedures are invoked via the +parsed procedure tree, not via InnoDB SQL, so this function is not used. */ que_fork_t* pars_stored_procedure_call( /*=======================*/ /* out: query graph */ sym_node_t* sym_node); /* in: stored procedure name */ -/***************************************************************** -Writes info about query parameter markers (denoted with '?' in ODBC) into a -buffer. */ - -ulint -pars_write_query_param_info( -/*========================*/ - /* out: number of bytes used for info in buf */ - byte* buf, /* in: buffer which must be big enough */ - que_fork_t* graph); /* in: parsed query graph */ /********************************************************************** Completes a query graph by adding query thread and fork nodes above it and prepares the graph for running. The fork created is of diff --git a/innobase/include/que0que.h b/innobase/include/que0que.h index a3ed18e2b14..bcd7aed7e88 100644 --- a/innobase/include/que0que.h +++ b/innobase/include/que0que.h @@ -216,9 +216,7 @@ que_fork_start_command( QUE_THR_RUNNING state, or NULL; the query thread should be executed by que_run_threads by the caller */ - que_fork_t* fork, /* in: a query fork */ - ulint command,/* in: command SESS_COMM_FETCH_NEXT, ... */ - ulint param); /* in: possible parameter to the command */ + que_fork_t* fork); /* in: a query fork */ /*************************************************************************** Gets the trx of a query thread. */ UNIV_INLINE @@ -309,22 +307,6 @@ que_thr_peek_stop( mutex reserved is necessary before deciding the actual stopping */ que_thr_t* thr); /* in: query thread */ -/*************************************************************************** -Returns TRUE if the query graph is for a SELECT statement. */ -UNIV_INLINE -ibool -que_graph_is_select( -/*================*/ - /* out: TRUE if a select */ - que_t* graph); /* in: graph */ -/************************************************************************** -Prints info of an SQL query graph node. */ - -void -que_node_print_info( -/*================*/ - que_node_t* node); /* in: query graph node */ - /* Query graph query thread node: the fields are protected by the kernel mutex with the exceptions named below */ @@ -388,11 +370,6 @@ struct que_fork_struct{ sym_tab_t* sym_tab; /* symbol table of the query, generated by the parser, or NULL if the graph was created 'by hand' */ - ulint id; /* id of this query graph */ - ulint command; /* command currently executed in the - graph */ - ulint param; /* possible command parameter */ - /* The following cur_... fields are relevant only in a select graph */ ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START, diff --git a/innobase/include/que0que.ic b/innobase/include/que0que.ic index ae4ed10560f..a63922f8c80 100644 --- a/innobase/include/que0que.ic +++ b/innobase/include/que0que.ic @@ -238,21 +238,3 @@ que_thr_peek_stop( return(FALSE); } - -/*************************************************************************** -Returns TRUE if the query graph is for a SELECT statement. */ -UNIV_INLINE -ibool -que_graph_is_select( -/*================*/ - /* out: TRUE if a select */ - que_t* graph) /* in: graph */ -{ - if (graph->fork_type == QUE_FORK_SELECT_SCROLL - || graph->fork_type == QUE_FORK_SELECT_NON_SCROLL) { - - return(TRUE); - } - - return(FALSE); -} diff --git a/innobase/include/rem0cmp.ic b/innobase/include/rem0cmp.ic index ebf513f538c..75cb3ef04e8 100644 --- a/innobase/include/rem0cmp.ic +++ b/innobase/include/rem0cmp.ic @@ -9,24 +9,6 @@ Created 7/1/1994 Heikki Tuuri /***************************************************************** This function is used to compare two data fields for which we know the data type. */ - -int -cmp_data_data_slow( -/*===============*/ - /* out: 1, 0, -1, if data1 is greater, equal, - less than data2, respectively */ - dtype_t* cur_type,/* in: data type of the fields */ - byte* data1, /* in: data field (== a pointer to a memory - buffer) */ - ulint len1, /* in: data field length or UNIV_SQL_NULL */ - byte* data2, /* in: data field (== a pointer to a memory - buffer) */ - ulint len2); /* in: data field length or UNIV_SQL_NULL */ - - -/***************************************************************** -This function is used to compare two data fields for which we know the -data type. */ UNIV_INLINE int cmp_data_data( diff --git a/innobase/include/row0ins.h b/innobase/include/row0ins.h index a5b4b74e7fc..f3f0b7e8eca 100644 --- a/innobase/include/row0ins.h +++ b/innobase/include/row0ins.h @@ -145,10 +145,11 @@ struct ins_node_struct{ entry_list and sys fields are stored here; if this is NULL, entry list should be created and buffers for sys fields in row allocated */ +#ifdef UNIV_DEBUG ulint magic_n; -}; - #define INS_NODE_MAGIC_N 15849075 +#endif /* UNIV_DEBUG */ +}; /* Insert node types */ #define INS_SEARCHED 0 /* INSERT INTO ... SELECT ... */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index fade3709631..32a0c8b5d75 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -510,13 +510,15 @@ struct row_prebuilt_struct { byte* ins_upd_rec_buff;/* buffer for storing data converted to the Innobase format from the MySQL format */ - ibool hint_no_need_to_fetch_extra_cols; - /* normally this is TRUE, but - MySQL will set this to FALSE - if we might be required to fetch also - other columns than mentioned in the - query: the clustered index column(s), - or an auto-increment column*/ + ulint hint_need_to_fetch_extra_cols; + /* normally this is set to 0; if this + is set to ROW_RETRIEVE_PRIMARY_KEY, + then we should at least retrieve all + columns in the primary key; if this + is set to ROW_RETRIEVE_ALL_COLS, then + we must retrieve all columns in the + key (if read_just_key == 1), or all + columns in the table */ upd_node_t* upd_node; /* Innobase SQL update node used to perform updates and deletes */ que_fork_t* ins_graph; /* Innobase SQL query graph used @@ -572,6 +574,11 @@ struct row_prebuilt_struct { #define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in row_scan_and_check_index */ +/* Values for hint_need_to_fetch_extra_cols */ +#define ROW_RETRIEVE_PRIMARY_KEY 1 +#define ROW_RETRIEVE_ALL_COLS 2 + + #ifndef UNIV_NONINL #include "row0mysql.ic" #endif diff --git a/innobase/include/row0row.h b/innobase/include/row0row.h index d1befbbbad3..3956f3c1692 100644 --- a/innobase/include/row0row.h +++ b/innobase/include/row0row.h @@ -68,16 +68,6 @@ row_build_index_entry( dict_index_t* index, /* in: index on the table */ mem_heap_t* heap); /* in: memory heap from which the memory for the index entry is allocated */ -/********************************************************************* -Builds an index entry from a row. */ - -void -row_build_index_entry_to_tuple( -/*===========================*/ - dtuple_t* entry, /* in/out: index entry; the dtuple must have - enough fields for the index! */ - dtuple_t* row, /* in: row */ - dict_index_t* index); /* in: index on the table */ /*********************************************************************** An inverse function to dict_row_build_index_entry. Builds a row from a record in a clustered index. */ @@ -103,21 +93,6 @@ row_build( mem_heap_t* heap); /* in: memory heap from which the memory needed is allocated */ /*********************************************************************** -An inverse function to dict_row_build_index_entry. Builds a row from a -record in a clustered index. */ - -void -row_build_to_tuple( -/*===============*/ - dtuple_t* row, /* in/out: row built; see the NOTE below! */ - dict_index_t* index, /* in: clustered index */ - rec_t* rec); /* in: record in the clustered index; - NOTE: the data fields in the row will point - directly into this record, therefore, - the buffer page of this record must be - at least s-latched and the latch held - as long as the row dtuple is used! */ -/*********************************************************************** Converts an index record to a typed data tuple. */ dtuple_t* diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index f5e0a88231f..687e90deee5 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -384,10 +384,11 @@ struct upd_node_struct{ sym_node_t* table_sym;/* table node in symbol table */ que_node_t* col_assign_list; /* column assignment list */ +#ifdef UNIV_DEBUG ulint magic_n; -}; - #define UPD_NODE_MAGIC_N 1579975 +#endif /* UNIV_DEBUG */ +}; /* Node execution states */ #define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from diff --git a/innobase/include/row0upd.ic b/innobase/include/row0upd.ic index 1878431d1a4..6b9deeac5e3 100644 --- a/innobase/include/row0upd.ic +++ b/innobase/include/row0upd.ic @@ -107,8 +107,10 @@ row_upd_rec_sys_fields( dulint roll_ptr)/* in: roll ptr of the undo log record */ { ut_ad(index->type & DICT_CLUSTERED); +#ifdef UNIV_SYNC_DEBUG ut_ad(!buf_block_align(rec)->is_hashed || rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ row_set_rec_trx_id(rec, index, trx->id); row_set_rec_roll_ptr(rec, index, roll_ptr); diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 6e47c468d26..8aac71de2a9 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -13,7 +13,6 @@ Created 10/10/1995 Heikki Tuuri #include "univ.i" #include "sync0sync.h" #include "os0sync.h" -#include "com0com.h" #include "que0types.h" #include "trx0types.h" @@ -216,13 +215,7 @@ srv_boot(void); /*==========*/ /* out: DB_SUCCESS or error code */ /************************************************************************* -Initializes the server. */ - -void -srv_init(void); -/*==========*/ -/************************************************************************* -Frees the OS fast mutex created in srv_init(). */ +Frees the OS fast mutex created in srv_boot(). */ void srv_free(void); @@ -272,23 +265,6 @@ srv_master_thread( /* out: a dummy parameter */ void* arg); /* in: a dummy parameter required by os_thread_create */ -/************************************************************************* -Reads a keyword and a value from a file. */ - -ulint -srv_read_init_val( -/*==============*/ - /* out: DB_SUCCESS or error code */ - FILE* initfile, /* in: file pointer */ - char* keyword, /* in: keyword before value(s), or NULL if - no keyword read */ - char* str_buf, /* in/out: buffer for a string value to read, - buffer size must be 10000 bytes, if NULL - then not read */ - ulint* num_val, /* out: numerical value to read, if NULL - then not read */ - ibool print_not_err); /* in: if TRUE, then we will not print - error messages to console */ /*********************************************************************** Tells the Innobase server that there has been activity in the database and wakes up the master thread if it is suspended (not sleeping). Used @@ -428,9 +404,6 @@ struct srv_sys_struct{ os_event_t operational; /* created threads must wait for the server to become operational by waiting for this event */ - com_endpoint_t* endpoint; /* the communication endpoint of the - server */ - srv_table_t* threads; /* server thread table */ UT_LIST_BASE_NODE_T(que_thr_t) tasks; /* task queue */ diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 97a59fd14c7..0074de537c3 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -21,16 +21,6 @@ srv_normalize_path_for_win( /*=======================*/ char* str); /* in/out: null-terminated character string */ /************************************************************************* -Adds a slash or a backslash to the end of a string if it is missing -and the string is not empty. */ - -char* -srv_add_path_separator_if_needed( -/*=============================*/ - /* out, own: string which has the separator if the - string is not empty */ - char* str); /* in: null-terminated character string */ -/************************************************************************* Reads the data files and their sizes from a character string given in the .cnf file. */ diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 5aa3dcdffc3..d71691b4353 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -25,13 +25,16 @@ smaller than 30 and the order of the numerical values like below! */ #define RW_NO_LATCH 3 typedef struct rw_lock_struct rw_lock_t; +#ifdef UNIV_SYNC_DEBUG typedef struct rw_lock_debug_struct rw_lock_debug_t; +#endif /* UNIV_SYNC_DEBUG */ typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t; extern rw_lock_list_t rw_lock_list; extern mutex_t rw_lock_list_mutex; +#ifdef UNIV_SYNC_DEBUG /* The global mutex which protects debug info lists of all rw-locks. To modify the debug info list of an rw-lock, this mutex has to be @@ -42,6 +45,7 @@ extern os_event_t rw_lock_debug_event; /* If deadlock detection does may wait for this event */ extern ibool rw_lock_debug_waiters; /* This is set to TRUE, if there may be waiters for the event */ +#endif /* UNIV_SYNC_DEBUG */ extern ulint rw_s_system_call_count; extern ulint rw_s_spin_wait_count; @@ -327,6 +331,7 @@ ulint rw_lock_get_reader_count( /*=====================*/ rw_lock_t* lock); +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks if the thread has locked the rw-lock in the specified mode, with the pass value == 0. */ @@ -337,6 +342,7 @@ rw_lock_own( rw_lock_t* lock, /* in: rw-lock */ ulint lock_type); /* in: lock type: RW_LOCK_SHARED, RW_LOCK_EX */ +#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** Checks if somebody has locked the rw-lock in the specified mode. */ @@ -346,6 +352,7 @@ rw_lock_is_locked( rw_lock_t* lock, /* in: rw-lock */ ulint lock_type); /* in: lock type: RW_LOCK_SHARED, RW_LOCK_EX */ +#ifdef UNIV_SYNC_DEBUG /******************************************************************* Prints debug info of an rw-lock. */ @@ -392,6 +399,7 @@ void rw_lock_debug_print( /*================*/ rw_lock_debug_t* info); /* in: debug struct */ +#endif /* UNIV_SYNC_DEBUG */ /* NOTE! The structure appears here only for the compiler to know its size. Do not use its fields directly! The structure used in the spin lock @@ -434,10 +442,12 @@ struct rw_lock_struct { UT_LIST_NODE_T(rw_lock_t) list; /* All allocated rw locks are put into a list */ +#ifdef UNIV_SYNC_DEBUG UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list; /* In the debug version: pointer to the debug info list of the lock */ - ulint level; /* Debug version: level in the global latching +#endif /* UNIV_SYNC_DEBUG */ + ulint level; /* Level in the global latching order; default SYNC_LEVEL_NONE */ char* cfile_name; /* File name where lock created */ ulint cline; /* Line where created */ @@ -450,6 +460,7 @@ struct rw_lock_struct { #define RW_LOCK_MAGIC_N 22643 +#ifdef UNIV_SYNC_DEBUG /* The structure for storing debug info of an rw-lock */ struct rw_lock_debug_struct { @@ -464,6 +475,7 @@ struct rw_lock_debug_struct { /* Debug structs are linked in a two-way list */ }; +#endif /* UNIV_SYNC_DEBUG */ #ifndef UNIV_NONINL #include "sync0rw.ic" diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic index 36ef0a985ed..8fc93f4a9da 100644 --- a/innobase/include/sync0rw.ic +++ b/innobase/include/sync0rw.ic @@ -20,6 +20,7 @@ rw_lock_s_lock_spin( be passed to another thread to unlock */ char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Inserts the debug information for an rw-lock. */ @@ -40,7 +41,7 @@ rw_lock_remove_debug_info( rw_lock_t* lock, /* in: rw-lock */ ulint pass, /* in: pass value */ ulint lock_type); /* in: lock type */ - +#endif /* UNIV_SYNC_DEBUG */ /************************************************************************ Accessor functions for rw lock. */ @@ -132,19 +133,19 @@ rw_lock_s_lock_low( char* file_name, /* in: file name where lock requested */ ulint line) /* in: line where requested */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(rw_lock_get_mutex(lock))); - +#endif /* UNIV_SYNC_DEBUG */ /* Check if the writer field is free */ if (lock->writer == RW_LOCK_NOT_LOCKED) { /* Set the shared lock by incrementing the reader count */ lock->reader_count++; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name, line); - #endif - +#endif lock->last_s_file_name = file_name; lock->last_s_line = line; @@ -175,9 +176,9 @@ rw_lock_s_lock_direct( lock->last_s_file_name = file_name; lock->last_s_line = line; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name, line); - #endif +#endif } /********************************************************************** @@ -204,9 +205,9 @@ rw_lock_x_lock_direct( lock->last_x_file_name = file_name; lock->last_x_line = line; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line); - #endif +#endif } /********************************************************************** @@ -236,7 +237,9 @@ rw_lock_s_lock_func( the threads which have s-locked a latch. This would use some CPU time. */ +#ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */ +#endif /* UNIV_SYNC_DEBUG */ mutex_enter(rw_lock_get_mutex(lock)); @@ -275,10 +278,10 @@ rw_lock_s_lock_func_nowait( /* Set the shared lock by incrementing the reader count */ lock->reader_count++; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name, line); - #endif +#endif lock->last_s_file_name = file_name; lock->last_s_line = line; @@ -320,9 +323,9 @@ rw_lock_x_lock_func_nowait( lock->writer_count++; lock->pass = 0; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line); - #endif +#endif lock->last_x_file_name = file_name; lock->last_x_line = line; @@ -361,9 +364,9 @@ rw_lock_s_unlock_func( ut_a(lock->reader_count > 0); lock->reader_count--; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED); - #endif +#endif /* If there may be waiters and this was the last s-lock, signal the object */ @@ -402,9 +405,9 @@ rw_lock_s_unlock_direct( lock->reader_count--; - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED); - #endif +#endif ut_ad(!lock->waiters); ut_ad(rw_lock_validate(lock)); @@ -442,9 +445,9 @@ rw_lock_x_unlock_func( rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); } - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX); - #endif +#endif /* If there may be waiters, signal the lock */ if (lock->waiters && (lock->writer_count == 0)) { @@ -486,9 +489,9 @@ rw_lock_x_unlock_direct( rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); } - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX); - #endif +#endif ut_ad(!lock->waiters); ut_ad(rw_lock_validate(lock)); diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 330b6b77b08..3a7203bbb56 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -185,6 +185,7 @@ sync_thread_levels_empty_gen( allowed to be owned by the thread, also purge_is_running mutex is allowed */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug version. */ @@ -217,6 +218,7 @@ Prints debug info of currently reserved mutexes. */ void mutex_list_print_info(void); /*========================*/ +#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** NOT to be used outside this module except in debugging! Gets the value of the lock word. */ @@ -225,6 +227,7 @@ ulint mutex_get_lock_word( /*================*/ mutex_t* mutex); /* in: mutex */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** NOT to be used outside this module except in debugging! Gets the waiters field in a mutex. */ @@ -234,15 +237,7 @@ mutex_get_waiters( /*==============*/ /* out: value to set */ mutex_t* mutex); /* in: mutex */ -/********************************************************************** -Implements the memory barrier operation which makes a serialization point to -the instruction flow. This is needed because the Pentium may speculatively -execute reads before preceding writes are committed. We could also use here -any LOCKed instruction (see Intel Software Dev. Manual, Vol. 3). */ - -void -mutex_fence(void); -/*=============*/ +#endif /* UNIV_SYNC_DEBUG */ /* LATCHING ORDER WITHIN THE DATABASE @@ -451,13 +446,13 @@ struct mutex_struct { Otherwise, this is 0. */ UT_LIST_NODE_T(mutex_t) list; /* All allocated mutexes are put into a list. Pointers to the next and prev. */ +#ifdef UNIV_SYNC_DEBUG + const char* file_name; /* File where the mutex was locked */ + ulint line; /* Line where the mutex was locked */ os_thread_id_t thread_id; /* Debug version: The thread id of the thread which locked the mutex. */ - char* file_name; /* Debug version: File name where the mutex - was locked */ - ulint line; /* Debug version: Line where the mutex was - locked */ - ulint level; /* Debug version: level in the global latching +#endif /* UNIV_SYNC_DEBUG */ + ulint level; /* Level in the global latching order; default SYNC_LEVEL_NONE */ char* cfile_name; /* File name where mutex created */ ulint cline; /* Line where created */ diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index c11cc0d196e..758c8524f66 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -25,6 +25,7 @@ mutex_spin_wait( mutex_t* mutex, /* in: pointer to mutex */ char* file_name,/* in: file name where mutex requested */ ulint line); /* in: line where requested */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Sets the debug information for a reserved mutex. */ @@ -34,6 +35,7 @@ mutex_set_debug_info( mutex_t* mutex, /* in: mutex */ char* file_name, /* in: file where requested */ ulint line); /* in: line where requested */ +#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** Releases the threads waiting in the primary wait array for this mutex. */ @@ -200,9 +202,9 @@ mutex_exit( /*=======*/ mutex_t* mutex) /* in: pointer to mutex */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(mutex)); -#ifdef UNIV_SYNC_DEBUG mutex->thread_id = ULINT_UNDEFINED; sync_thread_reset_level(mutex); @@ -249,14 +251,9 @@ mutex_enter_func( the atomic test_and_set; we could peek, and possibly save time. */ if (!mutex_test_and_set(mutex)) { - - #ifdef UNIV_SYNC_DEBUG +#ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); - #endif - - mutex->file_name = file_name; - mutex->line = line; - +#endif return; /* Succeeded! */ } diff --git a/innobase/include/trx0rseg.ic b/innobase/include/trx0rseg.ic index 6b242b66c09..35e927f5e79 100644 --- a/innobase/include/trx0rseg.ic +++ b/innobase/include/trx0rseg.ic @@ -24,7 +24,9 @@ trx_rsegf_get( header = TRX_RSEG + buf_page_get(space, page_no, RW_X_LATCH, mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(header, SYNC_RSEG_HEADER); +#endif /* UNIV_SYNC_DEBUG */ return(header); } @@ -45,7 +47,9 @@ trx_rsegf_get_new( header = TRX_RSEG + buf_page_get(space, page_no, RW_X_LATCH, mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(header, SYNC_RSEG_HEADER_NEW); +#endif /* UNIV_SYNC_DEBUG */ return(header); } @@ -64,7 +68,7 @@ trx_rsegf_get_nth_undo( if (n >= TRX_RSEG_N_SLOTS) { fprintf(stderr, "InnoDB: Error: trying to get slot %lu of rseg\n", (unsigned long) n); - ut_a(0); + ut_error; } return(mtr_read_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + @@ -85,7 +89,7 @@ trx_rsegf_set_nth_undo( if (n >= TRX_RSEG_N_SLOTS) { fprintf(stderr, "InnoDB: Error: trying to set slot %lu of rseg\n", (unsigned long) n); - ut_a(0); + ut_error; } mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE, diff --git a/innobase/include/trx0sys.ic b/innobase/include/trx0sys.ic index 343e6d7c2fa..8f455e554ea 100644 --- a/innobase/include/trx0sys.ic +++ b/innobase/include/trx0sys.ic @@ -60,7 +60,9 @@ trx_sys_get_nth_rseg( trx_sys_t* sys, /* in: trx system */ ulint n) /* in: index of slot */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(n < TRX_SYS_N_RSEGS); return(sys->rseg_array[n]); @@ -98,7 +100,9 @@ trx_sysf_get( header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(header, SYNC_TRX_SYS_HEADER); +#endif /* UNIV_SYNC_DEBUG */ return(header); } @@ -115,7 +119,9 @@ trx_sysf_rseg_get_space( ulint i, /* in: slot index == rseg id */ mtr_t* mtr) /* in: mtr */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -138,7 +144,9 @@ trx_sysf_rseg_get_page_no( mtr_t* mtr) /* in: mtr */ { ut_ad(sys_header); +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(i < TRX_SYS_N_RSEGS); return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS @@ -158,7 +166,9 @@ trx_sysf_rseg_set_space( ulint space, /* in: space id */ mtr_t* mtr) /* in: mtr */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -182,7 +192,9 @@ trx_sysf_rseg_set_page_no( slot is reset to unused */ mtr_t* mtr) /* in: mtr */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -236,7 +248,9 @@ trx_get_on_id( { trx_t* trx; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ trx = UT_LIST_GET_FIRST(trx_sys->trx_list); @@ -266,7 +280,9 @@ trx_list_get_min_trx_id(void) { trx_t* trx; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ trx = UT_LIST_GET_LAST(trx_sys->trx_list); @@ -289,7 +305,9 @@ trx_is_active( { trx_t* trx; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); +#endif /* UNIV_SYNC_DEBUG */ if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) { @@ -325,7 +343,9 @@ trx_sys_get_new_trx_id(void) { dulint id; +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ /* VERY important: after the database is started, max_trx_id value is divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if @@ -355,7 +375,9 @@ trx_sys_get_new_trx_no(void) /*========================*/ /* out: new, allocated trx number */ { +#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); +#endif /* UNIV_SYNC_DEBUG */ return(trx_sys_get_new_trx_id()); } diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 6b08b674db8..d9b91ee62dc 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -203,13 +203,9 @@ trx_sig_send( ulint type, /* in: signal type */ ulint sender, /* in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */ - ibool reply, /* in: TRUE if the sender of the signal - wants reply after the operation induced - by the signal is completed; if type - is TRX_SIG_END_WAIT, this must be - FALSE */ que_thr_t* receiver_thr, /* in: query thread which wants the - reply, or NULL */ + reply, or NULL; if type is + TRX_SIG_END_WAIT, this must be NULL */ trx_savept_t* savept, /* in: possible rollback savepoint, or NULL */ que_thr_t** next_thr); /* in/out: next query thread to run; @@ -225,7 +221,6 @@ been handled. */ void trx_sig_reply( /*==========*/ - trx_t* trx, /* in: trx handle */ trx_sig_t* sig, /* in: signal */ que_thr_t** next_thr); /* in/out: next query thread to run; if the value which is passed in is @@ -297,15 +292,9 @@ struct trx_sig_struct{ TRX_SIG_BEING_HANDLED */ ulint sender; /* TRX_SIG_SELF or TRX_SIG_OTHER_SESS */ - ibool reply; /* TRUE if the sender of the signal + que_thr_t* receiver; /* non-NULL if the sender of the signal wants reply after the operation induced - by the signal is completed; if this - field is TRUE and the receiver field - below is NULL, then a SUCCESS message - is sent to the client of the session - to which this trx belongs */ - que_thr_t* receiver; /* query thread which wants the reply, - or NULL */ + by the signal is completed */ trx_savept_t savept; /* possible rollback savepoint */ UT_LIST_NODE_T(trx_sig_t) signals; /* queue of pending signals to the diff --git a/innobase/include/trx0undo.h b/innobase/include/trx0undo.h index 7f0378c68d3..20002076cc3 100644 --- a/innobase/include/trx0undo.h +++ b/innobase/include/trx0undo.h @@ -251,20 +251,6 @@ trx_undo_update_cleanup( page_t* undo_page, /* in: update undo log header page, x-latched */ mtr_t* mtr); /* in: mtr */ -/************************************************************************** -Discards an undo log and puts the segment to the list of cached update undo -log segments. This optimized function is called if there is no need to -keep the update undo log because there exist no read views and the transaction -made no delete markings, which would make purge necessary. We restrict this -to undo logs of size 1 to make things simpler. */ - -dulint -trx_undo_update_cleanup_by_discard( -/*===============================*/ - /* out: log sequence number at which mtr is - committed */ - trx_t* trx, /* in: trx owning the update undo log */ - mtr_t* mtr); /* in: mtr */ /********************************************************************** Frees or caches an insert undo log after a transaction commit or rollback. Knowledge of inserts is not needed after a commit or rollback, therefore diff --git a/innobase/include/trx0undo.ic b/innobase/include/trx0undo.ic index bedbc02b00b..a04b234b495 100644 --- a/innobase/include/trx0undo.ic +++ b/innobase/include/trx0undo.ic @@ -126,7 +126,9 @@ trx_undo_page_get( page = buf_page_get(space, page_no, RW_X_LATCH, mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_TRX_UNDO_PAGE); +#endif /* UNIV_SYNC_DEBUG */ return(page); } @@ -146,7 +148,9 @@ trx_undo_page_get_s_latched( page = buf_page_get(space, page_no, RW_S_LATCH, mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_TRX_UNDO_PAGE); +#endif /* UNIV_SYNC_DEBUG */ return(page); } diff --git a/innobase/include/univold.i b/innobase/include/univold.i deleted file mode 100644 index 8bcd28e180f..00000000000 --- a/innobase/include/univold.i +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************** -Version control for database, common definitions, and include files - -(c) 1994 - 2000 Innobase Oy - -Created 1/20/1994 Heikki Tuuri -****************************************************************************/ - -#ifndef univ_i -#define univ_i - -#define UNIV_INTEL -#define UNIV_PENTIUM -/* If UNIV_WINNT is not defined, we assume Windows 95 */ - -#define UNIV_WINNT -#define UNIV_WINNT4 -#define __NT__ - -#define UNIV_VISUALC - -#define __WIN__ -#define _WIN32_WINNT 0x0400 - -/* DEBUG VERSION CONTROL - ===================== */ -/* Make a non-inline debug version */ -/* -#define UNIV_DEBUG -#define UNIV_MEM_DEBUG -#define UNIV_SYNC_DEBUG -#define UNIV_SEARCH_DEBUG - -#define UNIV_IBUF_DEBUG - -#define UNIV_SEARCH_PERF_STAT -#define UNIV_SYNC_PERF_STAT -*/ -#define UNIV_LIGHT_MEM_DEBUG - -#define YYDEBUG 1 -/* -#define UNIV_SQL_DEBUG -#define UNIV_LOG_DEBUG -*/ - /* the above option prevents forcing of log to disk - at a buffer page write: it should be tested with this - option off; also some ibuf tests are suppressed */ -/* -#define UNIV_BASIC_LOG_DEBUG -*/ - /* the above option enables basic recovery debugging: - new allocated file pages are reset */ - -/* The debug version is slower, thus we may change the length of test loops -depending on the UNIV_DBC parameter */ -#ifdef UNIV_DEBUG -#define UNIV_DBC 1 -#else -#define UNIV_DBC 100 -#endif - -#ifndef UNIV_DEBUG -/* Definition for inline version */ - -#ifdef UNIV_VISUALC -#define UNIV_INLINE __inline -#elif defined(UNIV_GNUC) -#define UNIV_INLINE extern __inline__ -#endif - -#else -/* If we want to compile a noninlined version we use the following macro -definitions: */ - -#define UNIV_NONINL -#define UNIV_INLINE - -#endif /* UNIV_DEBUG */ -/* If the compiler does not know inline specifier, we use: */ -/* -#define UNIV_INLINE static -*/ - - -/* - MACHINE VERSION CONTROL - ======================= -*/ - -#ifdef UNIV_PENTIUM - -/* In a 32-bit computer word size is 4 */ -#define UNIV_WORD_SIZE 4 - -/* The following alignment is used in memory allocations in memory heap -management to ensure correct alignment for doubles etc. */ -#define UNIV_MEM_ALIGNMENT 8 - -/* The following alignment is used in aligning lints etc. */ -#define UNIV_WORD_ALIGNMENT UNIV_WORD_SIZE - -#endif - -/* - DATABASE VERSION CONTROL - ======================== -*/ - -/* The universal page size of the database */ -#define UNIV_PAGE_SIZE (2 * 8192)/* NOTE! Currently, this has to be a - power of 2 and divisible by - UNIV_MEM_ALIGNMENT */ - -/* Do non-buffered io in buffer pool read/write operations */ -#define UNIV_NON_BUFFERED_IO - -/* Maximum number of parallel threads in a parallelized operation */ -#define UNIV_MAX_PARALLELISM 32 - -/* - UNIVERSAL TYPE DEFINITIONS - ========================== -*/ - - -typedef unsigned char byte; - -/* An other basic type we use is unsigned long integer which is intended to be -equal to the word size of the machine. */ - -typedef unsigned long int ulint; - -typedef long int lint; - -/* The following type should be at least a 64-bit floating point number */ -typedef double utfloat; - -/* The 'undefined' value for a ulint */ -#define ULINT_UNDEFINED ((ulint)(-1)) - -/* The undefined 32-bit unsigned integer */ -#define ULINT32_UNDEFINED 0xFFFFFFFF - -/* Maximum value for a ulint */ -#define ULINT_MAX ((ulint)(-2)) - - -/* Definition of the boolean type */ -typedef ulint bool; - -#define TRUE 1 -#define FALSE 0 - -/* The following number as the length of a logical field means that the field -has the SQL NULL as its value. */ -#define UNIV_SQL_NULL ULINT_UNDEFINED - -#include <stdio.h> -#include "ut0dbg.h" -#include "ut0ut.h" -#include "db0err.h" - -#endif diff --git a/innobase/include/univoldmysql.i b/innobase/include/univoldmysql.i deleted file mode 100644 index 269b584d073..00000000000 --- a/innobase/include/univoldmysql.i +++ /dev/null @@ -1,181 +0,0 @@ -/*************************************************************************** -Version control for database, common definitions, and include files - -(c) 1994 - 1996 Innobase Oy - -Created 1/20/1994 Heikki Tuuri -****************************************************************************/ - -#ifndef univ_i -#define univ_i - -#define UNIV_INTEL -#define UNIV_PENTIUM -/* If UNIV_WINNT is not defined, we assume Windows 95 */ - -#define UNIV_WINNT -#define UNIV_WINNT4 - -#define UNIV_VISUALC - -/* DEBUG VERSION CONTROL - ===================== */ -/* Make a profiler version where mutex_fence does not use CPUID and therefore -is not totally safe. The sync-library must be recompiled before profiling. */ -/* -#define UNIV_PROFILE -*/ -/* When the following flag is defined, also mutex lock word reset to 0 -in mutex_exit is performed using a serializing instruction, which does not -allow speculative reads be performed before memory writes */ -/* -#define SYNC_SERIALIZE_MUTEX_RESET -*/ -/* Make a non-inline debug version */ - -#define UNIV_DEBUG -#define UNIV_MEM_DEBUG -#define UNIV_SYNC_DEBUG -#define UNIV_SEARCH_DEBUG - -#define UNIV_IBUF_DEBUG - -#define UNIV_SEARCH_PERF_STAT -#define UNIV_SYNC_PERF_STAT - - -#define UNIV_LIGHT_MEM_DEBUG - -#define YYDEBUG 1 -/* -#define UNIV_SQL_DEBUG -#define UNIV_LOG_DEBUG -*/ - /* the above option prevents forcing of log to disk - at a buffer page write: it should be tested with this - option off; also some ibuf tests are suppressed */ -/* -#define UNIV_BASIC_LOG_DEBUG -*/ - /* the above option enables basic recovery debugging: - new allocated file pages are reset */ - -/* The debug version is slower, thus we may change the length of test loops -depending on the UNIV_DBC parameter */ -#ifdef UNIV_DEBUG -#define UNIV_DBC 1 -#else -#define UNIV_DBC 100 -#endif - -#ifndef UNIV_DEBUG -/* Definition for inline version */ - -#ifdef UNIV_VISUALC -#define UNIV_INLINE __inline -#elif defined(UNIV_GNUC) -#define UNIV_INLINE extern __inline__ -#endif - -#else -/* If we want to compile a noninlined version we use the following macro -definitions: */ - -#define UNIV_NONINL -#define UNIV_INLINE - -#endif /* UNIV_DEBUG */ -/* If the compiler does not know inline specifier, we use: */ -/* -#define UNIV_INLINE static -*/ - - -/* - MACHINE VERSION CONTROL - ======================= -*/ - -#ifdef UNIV_PENTIUM - -/* In a 32-bit computer word size is 4 */ -#define UNIV_WORD_SIZE 4 - -/* The following alignment is used in memory allocations in memory heap -management to ensure correct alignment for doubles etc. */ -#define UNIV_MEM_ALIGNMENT 8 - -/* The following alignment is used in aligning lints etc. */ -#define UNIV_WORD_ALIGNMENT UNIV_WORD_SIZE - -#endif - -/* - DATABASE VERSION CONTROL - ======================== -*/ - -/* The universal page size of the database */ -#define UNIV_PAGE_SIZE 8192 /* NOTE! Currently, this has to be a - power of 2 and divisible by - UNIV_MEM_ALIGNMENT */ -/* 2-based logarithm of UNIV_PAGE_SIZE */ -#define UNIV_PAGE_SIZE_SHIFT 13 - -/* Do asynchronous io in buffer pool read/write operations */ -#ifdef UNIV_WINNT -#define UNIV_ASYNC_IO -#endif - -/* Do non-buffered io in buffer pool read/write operations */ -#define UNIV_NON_BUFFERED_IO - -/* Maximum number of parallel threads in a parallelized operation */ -#define UNIV_MAX_PARALLELISM 32 - -/* - UNIVERSAL TYPE DEFINITIONS - ========================== -*/ - -/* -typedef unsigned char byte; -*/ - -/* An other basic type we use is unsigned long integer which is intended to be -equal to the word size of the machine. */ - -typedef unsigned long int ulint; - -typedef long int lint; - -/* The following type should be at least a 64-bit floating point number */ -typedef double utfloat; - -/* The 'undefined' value for a ulint */ -#define ULINT_UNDEFINED ((ulint)(-1)) - -/* The undefined 32-bit unsigned integer */ -#define ULINT32_UNDEFINED 0xFFFFFFFF - -/* Maximum value for a ulint */ -#define ULINT_MAX ((ulint)(-2)) - -/* Definition of the boolean type */ -#ifndef bool -typedef ulint bool; -#endif - -#define TRUE 1 -#define FALSE 0 - -/* The following number as the length of a logical field means that the field -has the SQL NULL as its value. */ -#define UNIV_SQL_NULL ULINT_UNDEFINED - -#include <stdio.h> -#include "ut0dbg.h" -#include "ut0ut.h" -#include "db0err.h" - -#endif diff --git a/innobase/include/usr0sess.h b/innobase/include/usr0sess.h index 365f828ecfc..c7bcfb20fed 100644 --- a/innobase/include/usr0sess.h +++ b/innobase/include/usr0sess.h @@ -11,7 +11,6 @@ Created 6/25/1996 Heikki Tuuri #include "univ.i" #include "ut0byte.h" -#include "hash0hash.h" #include "trx0types.h" #include "srv0srv.h" #include "trx0types.h" @@ -19,74 +18,14 @@ Created 6/25/1996 Heikki Tuuri #include "que0types.h" #include "data0data.h" #include "rem0rec.h" -#include "com0com.h" -/* The session system global data structure */ -extern sess_sys_t* sess_sys; - -/************************************************************************* -Sets the session id in a client message. */ - -void -sess_cli_msg_set_sess( -/*==================*/ - byte* str, /* in/out: message string */ - dulint sess_id);/* in: session id */ -/*************************************************************************** -Sets the message type of a message from the client. */ -UNIV_INLINE -void -sess_cli_msg_set_type( -/*==================*/ - byte* str, /* in: message string */ - ulint type); /* in: message type */ -/*************************************************************************** -Gets the message type of a message from the server. */ -UNIV_INLINE -ulint -sess_srv_msg_get_type( -/*==================*/ - /* out: message type */ - byte* str); /* in: message string */ -/*************************************************************************** -Creates a session sytem at database start. */ - -void -sess_sys_init_at_db_start(void); -/*===========================*/ /************************************************************************* Opens a session. */ sess_t* -sess_open( -/*======*/ +sess_open(void); +/*============*/ /* out, own: session object */ - com_endpoint_t* endpoint, /* in: communication endpoint used - for communicating with the client */ - byte* addr_buf, /* in: client address */ - ulint addr_len); /* in: client address length */ -/************************************************************************* -Closes a session, freeing the memory occupied by it. */ - -void -sess_close( -/*=======*/ - sess_t* sess); /* in, own: session object */ -/************************************************************************* -Raises an SQL error. */ - -void -sess_raise_error_low( -/*=================*/ - trx_t* trx, /* in: transaction */ - ulint err_no, /* in: error number */ - ulint type, /* in: more info of the error, or 0 */ - dict_table_t* table, /* in: dictionary table or NULL */ - dict_index_t* index, /* in: table index or NULL */ - dtuple_t* tuple, /* in: tuple to insert or NULL */ - rec_t* rec, /* in: record or NULL */ - char* err_str);/* in: arbitrary null-terminated error string, - or NULL */ /************************************************************************* Closes a session, freeing the memory occupied by it, if it is in a state where it should be closed. */ @@ -96,221 +35,25 @@ sess_try_close( /*===========*/ /* out: TRUE if closed */ sess_t* sess); /* in, own: session object */ -/************************************************************************* -Initializes the first fields of a message to client. */ - -void -sess_srv_msg_init( -/*==============*/ - sess_t* sess, /* in: session object */ - byte* buf, /* in: message buffer, must be at least of size - SESS_SRV_MSG_DATA */ - ulint type); /* in: message type */ -/************************************************************************* -Sends a simple message to client. */ - -void -sess_srv_msg_send_simple( -/*=====================*/ - sess_t* sess, /* in: session object */ - ulint type, /* in: message type */ - ulint rel_kernel); /* in: SESS_RELEASE_KERNEL or - SESS_NOT_RELEASE_KERNEL */ -/*************************************************************************** -Processes a message from a client. NOTE: May release the kernel mutex -temporarily. */ - -void -sess_receive_msg_rel_kernel( -/*========================*/ - sess_t* sess, /* in: session */ - byte* str, /* in: message string */ - ulint len); /* in: message length */ -/*************************************************************************** -When a command has been completed, this function sends the message about it -to the client. */ - -void -sess_command_completed_message( -/*===========================*/ - sess_t* sess, /* in: session */ - byte* msg, /* in: message buffer */ - ulint len); /* in: message data length */ -/*********************************************************************** -Starts a new connection and a session, or starts a query based on a client -message. This is called by a SRV_COM thread. */ - -void -sess_process_cli_msg( -/*=================*/ - byte* str, /* in: message string */ - ulint len, /* in: string length */ - byte* addr, /* in: address string */ - ulint alen); /* in: address length */ - /* The session handle. All fields are protected by the kernel mutex */ struct sess_struct{ - dulint id; /* session id */ - dulint usr_id; /* user id */ - hash_node_t hash; /* hash chain node */ - ulint refer_count; /* reference count to the session - object: when this drops to zero - and the session has no query graphs - left, discarding the session object - is allowed */ - dulint error_count; /* if this counter has increased while - a thread is parsing an SQL command, - its graph should be discarded */ - ibool disconnecting; /* TRUE if the session is to be - disconnected when its reference - count drops to 0 */ ulint state; /* state of the session */ - dulint msgs_sent; /* count of messages sent to the - client */ - dulint msgs_recv; /* count of messages received from the - client */ - ibool client_waits; /* when the session receives a message - from the client, this set to TRUE, and - when the session sends a message to - the client this is set to FALSE */ trx_t* trx; /* transaction object permanently assigned for the session: the transaction instance designated by the trx id changes, but the memory structure is preserved */ - ulint next_graph_id; /* next query graph id to assign */ UT_LIST_BASE_NODE_T(que_t) graphs; /* query graphs belonging to this session */ - /*------------------------------*/ - ulint err_no; /* latest error number, 0 if none */ - char* err_str; /* latest error string */ - ulint err_len; /* error string length */ - /*------------------------------*/ - com_endpoint_t* endpoint; /* server communications endpoint used - to communicate with the client */ - char* addr_buf; /* client address string */ - ulint addr_len; /* client address string length */ - /*------------------------------*/ - byte* big_msg; /* if the client sends a message which - does not fit in a single packet, - it is assembled in this buffer; if - this field is not NULL, it is assumed - that the message should be catenated - here */ - ulint big_msg_size; /* size of the big message buffer */ - ulint big_msg_len; /* length of data in the big message - buffer */ -}; - -/* The session system; this is protected by the kernel mutex */ -struct sess_sys_struct{ - ulint state; /* state of the system: - SESS_SYS_RUNNING or - SESS_SYS_SHUTTING_DOWN */ - sess_t* shutdown_req; /* if shutdown was requested by some - session, confirmation of shutdown - completion should be sent to this - session */ - dulint free_sess_id; /* first unused session id */ - hash_table_t* hash; /* hash table of the sessions */ }; - -/*---------------------------------------------------*/ -/* The format of an incoming message from a client */ -#define SESS_CLI_MSG_CHECKSUM 0 /* the checksum should be the first - field in the message */ -#define SESS_CLI_MSG_SESS_ID 4 /* this is set to 0 if the client - wants to connect and establish - a new session */ -#define SESS_CLI_MSG_SESS_ID_CHECK 12 /* checksum of the sess id field */ -#define SESS_CLI_MSG_TYPE 16 -#define SESS_CLI_MSG_NO 20 -#define SESS_CLI_MSG_CONTINUE 28 /* 0, or SESS_MSG_FIRST_PART - SESS_MSG_MIDDLE_PART, or - SESS_MSG_LAST_PART */ -#define SESS_CLI_MSG_CONT_SIZE 32 /* size of a multipart message in - kilobytes (rounded upwards) */ -#define SESS_CLI_MSG_DATA 36 -/*---------------------------------------------------*/ - -/* Client-to-session message types */ -#define SESS_CLI_CONNECT 1 -#define SESS_CLI_PREPARE 2 -#define SESS_CLI_EXECUTE 3 -#define SESS_CLI_BREAK_EXECUTION 4 - -/* Client-to-session statement command types */ -#define SESS_COMM_FETCH_NEXT 1 -#define SESS_COMM_FETCH_PREV 2 -#define SESS_COMM_FETCH_FIRST 3 -#define SESS_COMM_FETCH_LAST 4 -#define SESS_COMM_FETCH_NTH 5 -#define SESS_COMM_FETCH_NTH_LAST 6 -#define SESS_COMM_EXECUTE 7 -#define SESS_COMM_NO_COMMAND 8 - -/*---------------------------------------------------*/ -/* The format of an outgoing message from a session to the client */ -#define SESS_SRV_MSG_CHECKSUM 0 /* the checksum should be the first - field in the message */ -#define SESS_SRV_MSG_SESS_ID 4 -#define SESS_SRV_MSG_TYPE 12 -#define SESS_SRV_MSG_NO 16 -#define SESS_SRV_MSG_CONTINUE 24 /* 0, or SESS_MSG_FIRST_PART - SESS_MSG_MIDDLE_PART, or - SESS_MSG_LAST_PART */ -#define SESS_SRV_MSG_CONT_SIZE 28 /* size of a multipart message - in kilobytes (rounded upward) */ -#define SESS_SRV_MSG_DATA 32 -/*---------------------------------------------------*/ - -/* Session-to-client message types */ -#define SESS_SRV_ACCEPT_CONNECT 1 -#define SESS_SRV_SUCCESS 2 -#define SESS_SRV_ERROR 3 - -/* Multipart messages */ -#define SESS_MSG_SINGLE_PART 0 -#define SESS_MSG_FIRST_PART 1 -#define SESS_MSG_MIDDLE_PART 2 -#define SESS_MSG_LAST_PART 3 - -/* Error numbers */ -#define SESS_ERR_NONE 0 -#define SESS_ERR_TRX_COMMITTED 1 -#define SESS_ERR_TRX_ROLLED_BACK 2 -#define SESS_ERR_SESSION_DISCONNECTED 3 -#define SESS_ERR_REPLY_FAILED 4 -#define SESS_ERR_CANNOT_BREAK_OP 5 -#define SESS_ERR_MSG_LOST 6 -#define SESS_ERR_MSG_CORRUPTED 7 -#define SESS_ERR_EXTRANEOUS_MSG 8 -#define SESS_ERR_OUT_OF_MEMORY 9 -#define SESS_ERR_SQL_ERROR 10 -#define SESS_ERR_STMT_NOT_FOUND 11 -#define SESS_ERR_STMT_NOT_READY 12 -#define SESS_ERR_EXTRANEOUS_SRV_MSG 13 -#define SESS_ERR_BREAK_BY_CLIENT 14 - /* Session states */ #define SESS_ACTIVE 1 #define SESS_ERROR 2 /* session contains an error message which has not yet been communicated to the client */ -/* Session system states */ -#define SESS_SYS_RUNNING 1 -#define SESS_SYS_SHUTTING_DOWN 2 - -/* Session hash table size */ -#define SESS_HASH_SIZE 1024 - -/* Flags used in sess_srv_msg_send */ -#define SESS_RELEASE_KERNEL 1 -#define SESS_NOT_RELEASE_KERNEL 2 - #ifndef UNIV_NONINL #include "usr0sess.ic" #endif diff --git a/innobase/include/usr0sess.ic b/innobase/include/usr0sess.ic index ee2592c7963..c851d5745b9 100644 --- a/innobase/include/usr0sess.ic +++ b/innobase/include/usr0sess.ic @@ -5,27 +5,3 @@ Sessions Created 6/25/1996 Heikki Tuuri *******************************************************/ - -/*************************************************************************** -Sets the message type of a message from the client. */ -UNIV_INLINE -void -sess_cli_msg_set_type( -/*==================*/ - byte* str, /* in: message string */ - ulint type) /* in: message type */ -{ - mach_write_to_4(str + SESS_CLI_MSG_TYPE, type); -} - -/*************************************************************************** -Gets the message type of a message from the server. */ -UNIV_INLINE -ulint -sess_srv_msg_get_type( -/*==================*/ - /* out: message type */ - byte* str) /* in: message string */ -{ - return(mach_read_from_4(str + SESS_SRV_MSG_TYPE)); -} diff --git a/innobase/include/usr0types.h b/innobase/include/usr0types.h index 67070ccce27..29359425169 100644 --- a/innobase/include/usr0types.h +++ b/innobase/include/usr0types.h @@ -10,7 +10,5 @@ Created 6/25/1996 Heikki Tuuri #define usr0types_h typedef struct sess_struct sess_t; -typedef struct sess_sys_struct sess_sys_t; -typedef struct sess_sig_struct sess_sig_t; #endif diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index 9b07d5da488..085b4811a73 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -10,7 +10,6 @@ Created 1/30/1994 Heikki Tuuri #define ut0dbg_h #include "univ.i" -#include <assert.h> #include <stdlib.h> #include "os0thread.h" @@ -24,7 +23,7 @@ extern const char* ut_dbg_msg_assert_fail; extern const char* ut_dbg_msg_trap; extern const char* ut_dbg_msg_stop; -#define ut_a(EXPR)\ +#define ut_a(EXPR) do {\ if (!((ulint)(EXPR) + ut_dbg_zero)) {\ ut_print_timestamp(stderr);\ fprintf(stderr, ut_dbg_msg_assert_fail,\ @@ -33,38 +32,32 @@ extern const char* ut_dbg_msg_stop; fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\ fputs(ut_dbg_msg_trap, stderr);\ ut_dbg_stop_threads = TRUE;\ - (*ut_dbg_null_ptr)++;\ + if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\ }\ if (ut_dbg_stop_threads) {\ fprintf(stderr, ut_dbg_msg_stop,\ os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\ os_thread_sleep(1000000000);\ - } + }\ +} while (0) -#define ut_error\ +#define ut_error do {\ ut_print_timestamp(stderr);\ fprintf(stderr, ut_dbg_msg_assert_fail,\ os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\ fprintf(stderr, ut_dbg_msg_trap);\ ut_dbg_stop_threads = TRUE;\ - (*ut_dbg_null_ptr)++; + if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\ +} while (0) #ifdef UNIV_DEBUG #define ut_ad(EXPR) ut_a(EXPR) -#define ut_d(EXPR) {EXPR;} +#define ut_d(EXPR) do {EXPR;} while (0) #else #define ut_ad(EXPR) #define ut_d(EXPR) #endif - #define UT_NOT_USED(A) A = A - - - - - - #endif - diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index ba6905a8618..b7dfe77a08e 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -95,10 +95,26 @@ ut_str_catenate( /* out, own: catenated null-terminated string */ char* str1, /* in: null-terminated string */ char* str2); /* in: null-terminated string */ +/************************************************************************** +Return a copy of the given string. The returned string must be freed +using mem_free. */ + +char* +ut_strdup( +/*======*/ + /* out, own: cnull-terminated string */ + char* str); /* in: null-terminated string */ +/************************************************************************** +Checks if a null-terminated string contains a certain character. */ + +ibool +ut_str_contains( +/*============*/ + char* str, /* in: null-terminated string */ + char c); /* in: character */ #ifndef UNIV_NONINL #include "ut0mem.ic" #endif #endif - diff --git a/innobase/include/ut0rnd.ic b/innobase/include/ut0rnd.ic index e166a26fe86..5493c37404a 100644 --- a/innobase/include/ut0rnd.ic +++ b/innobase/include/ut0rnd.ic @@ -176,19 +176,19 @@ ut_fold_string( /* out: folded value */ char* str) /* in: null-terminated string */ { - #ifdef UNIV_DEBUG +#ifdef UNIV_DEBUG ulint i = 0; - #endif +#endif ulint fold = 0; ut_ad(str); while (*str != '\0') { - #ifdef UNIV_DEBUG +#ifdef UNIV_DEBUG i++; ut_a(i < 100); - #endif +#endif fold = ut_fold_ulint_pair(fold, (ulint)(*str)); str++; |