diff --git a/Makefile.am b/Makefile.am index dfc3a511d52..ef170819f6b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,57 +26,65 @@ SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \ ha ibuf lock log mach mem mtr page \ pars que read rem row srv sync thr trx usr -EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \ - include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \ - include/btr0types.h \ - include/buf0buf.h include/buf0buf.ic include/buf0flu.h include/buf0flu.ic \ - include/buf0lru.h include/buf0lru.ic include/buf0rea.h include/buf0types.h \ - include/data0data.h include/data0data.ic include/data0type.h include/data0type.ic \ - include/data0types.h include/db0err.h \ - include/dict0boot.h include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \ - include/dict0dict.h include/dict0dict.ic include/dict0load.h include/dict0load.ic \ - include/dict0mem.h include/dict0mem.ic include/dict0types.h \ - include/dyn0dyn.h include/dyn0dyn.ic \ - include/eval0eval.h include/eval0eval.ic include/eval0proc.h include/eval0proc.ic \ - include/fil0fil.h include/fsp0fsp.h include/fsp0fsp.ic \ - include/fut0fut.h include/fut0fut.ic include/fut0lst.h include/fut0lst.ic \ - include/ha0ha.h include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \ +EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h \ + include/btr0cur.ic include/btr0pcur.h include/btr0pcur.ic \ + include/btr0sea.h include/btr0sea.ic include/btr0types.h \ + include/buf0buf.h include/buf0buf.ic include/buf0flu.h \ + include/buf0flu.ic include/buf0lru.h include/buf0lru.ic \ + include/buf0rea.h include/buf0types.h include/data0data.h \ + include/data0data.ic include/data0type.h include/data0type.ic \ + include/data0types.h include/db0err.h include/dict0boot.h \ + include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \ + include/dict0dict.h include/dict0dict.ic include/dict0load.h \ + include/dict0load.ic include/dict0mem.h include/dict0mem.ic \ + include/dict0types.h include/dyn0dyn.h include/dyn0dyn.ic \ + include/eval0eval.h include/eval0eval.ic include/eval0proc.h \ + include/eval0proc.ic include/fil0fil.h include/fsp0fsp.h \ + include/fsp0fsp.ic include/fut0fut.h include/fut0fut.ic \ + include/fut0lst.h include/fut0lst.ic include/ha0ha.h \ + include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \ include/ibuf0ibuf.h include/ibuf0ibuf.ic include/ibuf0types.h \ include/lock0lock.h include/lock0lock.ic include/lock0types.h \ - include/log0log.h include/log0log.ic include/log0recv.h include/log0recv.ic \ - include/mach0data.h include/mach0data.ic include/mem0dbg.h include/mem0dbg.ic \ - include/mem0mem.h include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \ - include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h include/mtr0mtr.ic \ - include/mtr0types.h include/os0file.h \ - include/os0proc.h include/os0proc.ic include/os0sync.h include/os0sync.ic \ - include/os0thread.h include/os0thread.ic \ - include/page0cur.h include/page0cur.ic include/page0page.h include/page0page.ic \ - include/page0types.h \ - include/pars0grm.h include/pars0opt.h include/pars0opt.ic \ - include/pars0pars.h include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \ - include/pars0types.h \ - include/que0que.h include/que0que.ic include/que0types.h \ - include/read0read.h include/read0read.ic include/read0types.h \ - include/rem0cmp.h include/rem0cmp.ic include/rem0rec.h include/rem0rec.ic \ - include/rem0types.h \ - include/row0ins.h include/row0ins.ic include/row0mysql.h include/row0mysql.ic \ - include/row0purge.h include/row0purge.ic include/row0row.h include/row0row.ic \ - include/row0sel.h include/row0sel.ic include/row0types.h \ - include/row0uins.h include/row0uins.ic include/row0umod.h include/row0umod.ic \ - include/row0undo.h include/row0undo.ic include/row0upd.h include/row0upd.ic \ - include/row0vers.h include/row0vers.ic \ - include/srv0que.h include/srv0srv.h include/srv0srv.ic include/srv0start.h \ - include/sync0arr.h include/sync0arr.ic include/sync0rw.h include/sync0rw.ic \ - include/sync0sync.h include/sync0sync.ic include/sync0types.h \ - include/thr0loc.h include/thr0loc.ic \ - include/trx0purge.h include/trx0purge.ic include/trx0rec.h include/trx0rec.ic \ - include/trx0roll.h include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \ - include/trx0sys.h include/trx0sys.ic include/trx0trx.h include/trx0trx.ic \ - include/trx0types.h include/trx0undo.h include/trx0undo.ic include/trx0xa.h \ - include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \ - include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \ - include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \ - include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic + include/log0log.h include/log0log.ic include/log0recv.h \ + include/log0recv.ic include/mach0data.h include/mach0data.ic \ + include/mem0dbg.h include/mem0dbg.ic include/mem0mem.h \ + include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \ + include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h \ + include/mtr0mtr.ic include/mtr0types.h include/os0file.h \ + include/os0proc.h include/os0proc.ic include/os0sync.h \ + include/os0sync.ic include/os0thread.h include/os0thread.ic \ + include/page0cur.h include/page0cur.ic include/page0page.h \ + include/page0page.ic include/page0types.h include/pars0grm.h \ + include/pars0opt.h include/pars0opt.ic include/pars0pars.h \ + include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \ + include/pars0types.h include/que0que.h include/que0que.ic \ + include/que0types.h include/read0read.h include/read0read.ic \ + include/read0types.h include/rem0cmp.h include/rem0cmp.ic \ + include/rem0rec.h include/rem0rec.ic include/rem0types.h \ + include/row0ins.h include/row0ins.ic include/row0mysql.h \ + include/row0mysql.ic include/row0purge.h include/row0purge.ic \ + include/row0row.h include/row0row.ic include/row0sel.h \ + include/row0sel.ic include/row0types.h include/row0uins.h \ + include/row0uins.ic include/row0umod.h include/row0umod.ic \ + include/row0undo.h include/row0undo.ic include/row0upd.h \ + include/row0upd.ic include/row0vers.h include/row0vers.ic \ + include/srv0que.h include/srv0srv.h include/srv0srv.ic \ + include/srv0start.h include/sync0arr.h include/sync0arr.ic \ + include/sync0rw.h include/sync0rw.ic include/sync0sync.h \ + include/sync0sync.ic include/sync0types.h include/thr0loc.h \ + include/thr0loc.ic include/trx0purge.h include/trx0purge.ic \ + include/trx0rec.h include/trx0rec.ic include/trx0roll.h \ + include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \ + include/trx0sys.h include/trx0sys.ic include/trx0trx.h \ + include/trx0trx.ic include/trx0types.h include/trx0undo.h \ + include/trx0undo.ic include/trx0xa.h include/univ.i \ + include/usr0sess.h include/usr0sess.ic include/usr0types.h \ + include/ut0byte.h include/ut0byte.ic include/ut0dbg.h \ + include/ut0lst.h include/ut0mem.h include/ut0mem.ic \ + include/ut0rnd.h include/ut0rnd.ic include/ut0sort.h \ + include/ut0ut.h include/ut0ut.ic include/ut0vec.h \ + include/ut0vec.ic include/ut0list.h include/ut0list.ic \ + include/ut0wqueue.h cmakelists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/btr/btr0sea.c b/btr/btr0sea.c index 7072b1c71e9..899cc464335 100644 --- a/btr/btr0sea.c +++ b/btr/btr0sea.c @@ -136,13 +136,12 @@ btr_search_sys_create( btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t)); - rw_lock_create(&btr_search_latch); + rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS); btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); btr_search_sys->hash_index = ha_create(TRUE, hash_size, 0, 0); - rw_lock_set_level(&btr_search_latch, SYNC_SEARCH_SYS); } /********************************************************************* diff --git a/buf/buf0buf.c b/buf/buf0buf.c index 457430dc9c4..43c6e2d1b33 100644 --- a/buf/buf0buf.c +++ b/buf/buf0buf.c @@ -612,12 +612,11 @@ buf_block_init( page_zip_des_init(&block->page_zip); - rw_lock_create(&(block->lock)); + rw_lock_create(&block->lock, SYNC_LEVEL_VARYING); ut_ad(rw_lock_validate(&(block->lock))); #ifdef UNIV_SYNC_DEBUG - rw_lock_create(&(block->debug_latch)); - rw_lock_set_level(&(block->debug_latch), SYNC_NO_ORDER_CHECK); + rw_lock_create(&block->debug_latch, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ } @@ -660,8 +659,7 @@ buf_pool_init( /* 1. Initialize general fields ------------------------------- */ - mutex_create(&(buf_pool->mutex)); - mutex_set_level(&(buf_pool->mutex), SYNC_BUF_POOL); + mutex_create(&buf_pool->mutex, SYNC_BUF_POOL); mutex_enter(&(buf_pool->mutex)); @@ -1953,7 +1951,6 @@ buf_page_io_complete( buf_block_t* block) /* in: pointer to the block in question */ { ulint io_type; - ulint read_page_no; ut_ad(block); @@ -1978,16 +1975,36 @@ buf_page_io_complete( } /* If this page is not uninitialized and not in the - doublewrite buffer, then the page number should be the - same as in block */ - - read_page_no = mach_read_from_4((block->frame) + doublewrite buffer, then the page number and space id + should be the same as in block. */ + ulint read_page_no = mach_read_from_4((block->frame) + FIL_PAGE_OFFSET); - if (read_page_no && read_page_no != block->offset) { + ulint read_space_id = mach_read_from_4((block->frame) + + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + if (!block->space && trx_doublewrite_page_inside( + block->offset)) { + + ut_print_timestamp(stderr); fprintf(stderr, -"InnoDB: Error: page n:o stored in the page read in is %lu, should be %lu!\n", - (ulong) read_page_no, (ulong) block->offset); +" InnoDB: Error: reading page %lu\n" +"InnoDB: which is in the doublewrite buffer!\n", + (ulong) block->offset); + } else if (!read_space_id && !read_page_no) { + /* This is likely an uninitialized page. */ + } else if ((block->space && block->space != read_space_id) + || block->offset != read_page_no) { + /* We did not compare space_id to read_space_id + if block->space == 0, because the field on the + page may contain garbage in MySQL < 4.1.1, + which only supported block->space == 0. */ + + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: space id and page n:o stored in the page\n" +"InnoDB: read in are %lu:%lu, should be %lu:%lu!\n", + (ulong) read_space_id, (ulong) read_page_no, + (ulong) block->space, (ulong) block->offset); } /* From version 3.23.38 up we store the page checksum @@ -2345,7 +2362,8 @@ buf_get_latched_pages_number(void) } mutex_exit(&(buf_pool->mutex)); - return fixed_pages_number; + + return(fixed_pages_number); } /************************************************************************* diff --git a/buf/buf0flu.c b/buf/buf0flu.c index 627f08f8c53..e95eeff69d1 100644 --- a/buf/buf0flu.c +++ b/buf/buf0flu.c @@ -27,7 +27,7 @@ Created 11/11/1995 Heikki Tuuri #include "trx0sys.h" #include "srv0srv.h" -/* When flushed, dirty blocks are searched in neigborhoods of this size, and +/* When flushed, dirty blocks are searched in neighborhoods of this size, and flushed along with the original page. */ #define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\ diff --git a/cmakelists.txt b/cmakelists.txt index def51873725..8b8c3af6582 100644 --- a/cmakelists.txt +++ b/cmakelists.txt @@ -32,4 +32,4 @@ ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c thr/thr0loc.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c usr/usr0sess.c - ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c) + ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c) diff --git a/dict/dict0crea.c b/dict/dict0crea.c index e0b62c0c7bd..8962b63d103 100644 --- a/dict/dict0crea.c +++ b/dict/dict0crea.c @@ -1139,11 +1139,8 @@ dict_create_or_check_foreign_constraint_tables(void) { dict_table_t* table1; dict_table_t* table2; - que_thr_t* thr; - que_t* graph; ulint error; trx_t* trx; - const char* str; mutex_enter(&(dict_sys->mutex)); @@ -1195,7 +1192,7 @@ dict_create_or_check_foreign_constraint_tables(void) VARBINARY, like in other InnoDB system tables, to get a clean design. */ - str = + error = que_eval_sql(NULL, "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n" "BEGIN\n" "CREATE TABLE\n" @@ -1207,22 +1204,8 @@ dict_create_or_check_foreign_constraint_tables(void) "SYS_FOREIGN_COLS(ID CHAR, POS INT, FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" "CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);\n" "COMMIT WORK;\n" - "END;\n"; - - graph = pars_sql(NULL, str); - - ut_a(graph); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - - ut_a(thr = que_fork_start_command(graph)); - - que_run_threads(thr); - - error = trx->error_state; + "END;\n" + , trx); if (error != DB_SUCCESS) { fprintf(stderr, "InnoDB: error %lu in creation\n", @@ -1241,8 +1224,6 @@ dict_create_or_check_foreign_constraint_tables(void) error = DB_MUST_GET_MORE_FILE_SPACE; } - que_graph_free(graph); - trx->op_info = ""; row_mysql_unlock_data_dictionary(trx); diff --git a/dict/dict0dict.c b/dict/dict0dict.c index fe4cd74656e..41093cd7558 100644 --- a/dict/dict0dict.c +++ b/dict/dict0dict.c @@ -235,11 +235,10 @@ dict_remove_db_name( const char* name) /* in: table name in the form dbname '/' tablename */ { - const char* s; - s = strchr(name, '/'); + const char* s = strchr(name, '/'); ut_a(s); - if (s) s++; - return(s); + + return(s + 1); } /************************************************************************ @@ -600,7 +599,7 @@ dict_index_get_nth_field_pos( } /************************************************************************** -Returns a table object, based on table id, and memoryfixes it. */ +Returns a table object based on table id. */ dict_table_t* dict_table_get_on_id( @@ -622,12 +621,12 @@ dict_table_get_on_id( ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ - return(dict_table_get_on_id_low(table_id, trx)); + return(dict_table_get_on_id_low(table_id)); } mutex_enter(&(dict_sys->mutex)); - table = dict_table_get_on_id_low(table_id, trx); + table = dict_table_get_on_id_low(table_id); mutex_exit(&(dict_sys->mutex)); @@ -709,8 +708,7 @@ dict_init(void) { dict_sys = mem_alloc(sizeof(dict_sys_t)); - mutex_create(&(dict_sys->mutex)); - mutex_set_level(&(dict_sys->mutex), SYNC_DICT); + mutex_create(&dict_sys->mutex, SYNC_DICT); dict_sys->table_hash = hash_create(buf_pool_get_max_size() / (DICT_POOL_PER_TABLE_HASH * @@ -725,32 +723,28 @@ dict_init(void) UT_LIST_INIT(dict_sys->table_LRU); - rw_lock_create(&dict_operation_lock); - rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); + rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION); dict_foreign_err_file = os_file_create_tmpfile(); ut_a(dict_foreign_err_file); - mutex_create(&dict_foreign_err_mutex); - mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH); + + mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH); } /************************************************************************** -Returns a table object and memoryfixes it. NOTE! This is a high-level -function to be used mainly from outside the 'dict' directory. Inside this -directory dict_table_get_low is usually the appropriate function. */ +Returns a table object. NOTE! This is a high-level function to be used +mainly from outside the 'dict' directory. Inside this directory +dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ /* out: table, NULL if does not exist */ - const char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + const char* table_name) /* in: table name */ { dict_table_t* table; - UT_NOT_USED(trx); - mutex_enter(&(dict_sys->mutex)); table = dict_table_get_low(table_name); @@ -774,13 +768,10 @@ dict_table_get_and_increment_handle_count( /*======================================*/ /* out: table, NULL if does not exist */ - const char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + const char* table_name) /* in: table name */ { dict_table_t* table; - UT_NOT_USED(trx); - mutex_enter(&(dict_sys->mutex)); table = dict_table_get_low(table_name); @@ -890,10 +881,7 @@ dict_table_add_to_cache( /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); - /* If the dictionary cache grows too big, trim the table LRU list */ - dict_sys->size += mem_heap_get_size(table->heap); - /* dict_table_LRU_trim(); */ } /************************************************************************** @@ -1258,38 +1246,6 @@ dict_table_remove_from_cache( dict_mem_table_free(table); } -/************************************************************************** -Frees tables from the end of table_LRU if the dictionary cache occupies -too much space. Currently not used! */ - -void -dict_table_LRU_trim(void) -/*=====================*/ -{ - dict_table_t* table; - dict_table_t* prev_table; - - ut_error; - -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - - table = UT_LIST_GET_LAST(dict_sys->table_LRU); - - while (table && (dict_sys->size > - buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) { - - prev_table = UT_LIST_GET_PREV(table_LRU, table); - - if (table->mem_fix == 0) { - dict_table_remove_from_cache(table); - } - - table = prev_table; - } -} - /************************************************************************** Adds a column to the data dictionary hash table. */ static @@ -1519,10 +1475,7 @@ dict_index_add_to_cache( /* Add the index to the list of indexes stored in the tree */ tree->tree_index = new_index; - /* If the dictionary cache grows too big, trim the table LRU list */ - dict_sys->size += mem_heap_get_size(new_index->heap); - /* dict_table_LRU_trim(); */ dict_mem_index_free(index); @@ -2994,7 +2947,8 @@ loop: if so, immediately reject the command if the table is a temporary one. For now, this kludge will work. */ if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0)) { - return DB_CANNOT_ADD_CONSTRAINT; + + return(DB_CANNOT_ADD_CONSTRAINT); } /**********************************************************/ @@ -3664,9 +3618,7 @@ dict_tree_create( tree->magic_n = DICT_TREE_MAGIC_N; - rw_lock_create(&(tree->lock)); - - rw_lock_set_level(&(tree->lock), SYNC_INDEX_TREE); + rw_lock_create(&tree->lock, SYNC_INDEX_TREE); return(tree); } diff --git a/dict/dict0load.c b/dict/dict0load.c index 71459f35ed5..0d83b9b1655 100644 --- a/dict/dict0load.c +++ b/dict/dict0load.c @@ -660,7 +660,7 @@ dict_load_indexes( break; } - if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) { + if (rec_get_deleted_flag(rec, 0)) { dict_load_report_deleted_index(table->name, ULINT_UNDEFINED); diff --git a/dict/dict0mem.c b/dict/dict0mem.c index 6e46f795e72..8f3858363cb 100644 --- a/dict/dict0mem.c +++ b/dict/dict0mem.c @@ -57,7 +57,6 @@ dict_mem_table_create( table->tablespace_discarded = FALSE; table->n_def = 0; table->n_cols = n_cols + DATA_N_SYS_COLS; - table->mem_fix = 0; table->n_mysql_handles_opened = 0; table->n_foreign_key_checks_running = 0; @@ -82,8 +81,7 @@ dict_mem_table_create( table->stat_modified_counter = 0; - mutex_create(&(table->autoinc_mutex)); - mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX); + mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX); table->autoinc_inited = FALSE; diff --git a/export.sh b/export.sh index 9307726ba2a..fd98777649b 100755 --- a/export.sh +++ b/export.sh @@ -1,19 +1,29 @@ #!/bin/bash # -# export current working directory in a format suitable for sending to -# MySQL as a snapshot. +# export current working directory in a format suitable for sending to MySQL +# as a snapshot. also generates the actual snapshot and sends it to MySQL. set -eu -if [ $# -ne 1 ] ; then - echo "Usage: export.sh revision-number-of-last-snapshot" +die () { + echo $* exit 1 +} + +if [ $# -ne 2 ] ; then + die "Usage: export.sh revision-number-of-last-snapshot current-revision-number" fi +set +u +if test -z $EDITOR; then + die "\$EDITOR is not set" +fi +set -u + rm -rf to-mysql mkdir -p to-mysql/storage/ -svn log -v -r "$1:BASE" > to-mysql/log -svn export . to-mysql/storage/innobase +svn log -v -r "$(($1 + 1)):BASE" > to-mysql/log +svn export -q . to-mysql/storage/innobase cd to-mysql mkdir -p sql mysql-test/t mysql-test/r mysql-test/include @@ -27,5 +37,18 @@ mv mysql-test/*.result ../../mysql-test/r mv mysql-test/*.inc ../../mysql-test/include rmdir mysql-test -rm setup.sh export.sh compile-innodb-debug +rm setup.sh export.sh revert_gen.sh compile-innodb-debug compile-innodb +cd ../.. +$EDITOR log +cd .. + +fname="innodb-5.1-ss$2.tar.gz" + +rm -f $fname +tar czf $fname to-mysql +scp $fname mysql:snapshots +rm $fname +rm -rf to-mysql + +echo "Sent $fname to MySQL" diff --git a/fil/fil0fil.c b/fil/fil0fil.c index 5e538ee6541..81794b84f24 100644 --- a/fil/fil0fil.c +++ b/fil/fil0fil.c @@ -1067,8 +1067,7 @@ try_again: space->ibuf_data = NULL; - rw_lock_create(&(space->latch)); - rw_lock_set_level(&(space->latch), SYNC_FSP); + rw_lock_create(&space->latch, SYNC_FSP); HASH_INSERT(fil_space_t, hash, system->spaces, id, space); @@ -1362,9 +1361,7 @@ fil_system_create( system = mem_alloc(sizeof(fil_system_t)); - mutex_create(&(system->mutex)); - - mutex_set_level(&(system->mutex), SYNC_ANY_LATCH); + mutex_create(&system->mutex, SYNC_ANY_LATCH); system->spaces = hash_create(hash_size); system->name_hash = hash_create(hash_size); diff --git a/ha/hash0hash.c b/ha/hash0hash.c index 659aeb815d8..6084a19fa27 100644 --- a/ha/hash0hash.c +++ b/ha/hash0hash.c @@ -144,9 +144,7 @@ hash_create_mutexes( table->mutexes = mem_alloc(n_mutexes * sizeof(mutex_t)); for (i = 0; i < n_mutexes; i++) { - mutex_create(table->mutexes + i); - - mutex_set_level(table->mutexes + i, sync_level); + mutex_create(table->mutexes + i, sync_level); } table->n_mutexes = n_mutexes; diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index c8e311d14b9..702b294be2f 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -238,7 +238,8 @@ handlerton innobase_hton = { NULL, /* Fill FILES table */ HTON_NO_FLAGS, NULL, /* binlog_func */ - NULL /* binlog_log_query */ + NULL, /* binlog_log_query */ + innobase_release_temporary_latches }; @@ -1768,25 +1769,6 @@ innobase_report_binlog_offset_and_commit( trx->mysql_log_file_name = log_file_name; trx->mysql_log_offset = (ib_longlong)end_offset; -#ifdef HAVE_REPLICATION - if (thd->variables.sync_replication) { - /* Let us store the binlog file name and the position, so that - we know how long to wait for the binlog to the replicated to - the slave in synchronous replication. */ - - if (trx->repl_wait_binlog_name == NULL) { - - trx->repl_wait_binlog_name = - (char*)mem_alloc_noninline(FN_REFLEN + 100); - } - - ut_a(strlen(log_file_name) < FN_REFLEN + 100); - - strcpy(trx->repl_wait_binlog_name, log_file_name); - - trx->repl_wait_binlog_pos = (ib_longlong)end_offset; - } -#endif /* HAVE_REPLICATION */ trx->flush_log_later = TRUE; innobase_commit(thd, TRUE); @@ -1855,224 +1837,9 @@ innobase_commit_complete( trx_commit_complete_for_mysql(trx); } -#ifdef HAVE_REPLICATION - if (thd->variables.sync_replication - && trx->repl_wait_binlog_name - && innobase_repl_state != 0) { - - struct timespec abstime; - int cmp; - int ret; - - /* In synchronous replication, let us wait until the MySQL - replication has sent the relevant binlog segment to the - replication slave. */ - - pthread_mutex_lock(&innobase_repl_cond_mutex); -try_again: - if (innobase_repl_state == 0) { - - pthread_mutex_unlock(&innobase_repl_cond_mutex); - - return(0); - } - - cmp = strcmp(innobase_repl_file_name, - trx->repl_wait_binlog_name); - if (cmp > 0 - || (cmp == 0 && innobase_repl_pos - >= (my_off_t)trx->repl_wait_binlog_pos)) { - /* We have already sent the relevant binlog to the - slave: no need to wait here */ - - pthread_mutex_unlock(&innobase_repl_cond_mutex); - -/* printf("Binlog now sent\n"); */ - - return(0); - } - - /* Let us update the info about the minimum binlog position - of waiting threads in the innobase_repl_... variables */ - - if (innobase_repl_wait_file_name_inited != 0) { - cmp = strcmp(trx->repl_wait_binlog_name, - innobase_repl_wait_file_name); - if (cmp < 0 - || (cmp == 0 - && (my_off_t)trx->repl_wait_binlog_pos - <= innobase_repl_wait_pos)) { - /* This thd has an even lower position, let - us update the minimum info */ - - strcpy(innobase_repl_wait_file_name, - trx->repl_wait_binlog_name); - - innobase_repl_wait_pos = - trx->repl_wait_binlog_pos; - } - } else { - strcpy(innobase_repl_wait_file_name, - trx->repl_wait_binlog_name); - - innobase_repl_wait_pos = trx->repl_wait_binlog_pos; - - innobase_repl_wait_file_name_inited = 1; - } - set_timespec(abstime, thd->variables.sync_replication_timeout); - - /* Let us suspend this thread to wait on the condition; - when replication has progressed far enough, we will release - these waiting threads. The following call - pthread_cond_timedwait also atomically unlocks - innobase_repl_cond_mutex. */ - - innobase_repl_n_wait_threads++; - -/* printf("Waiting for binlog to be sent\n"); */ - - ret = pthread_cond_timedwait(&innobase_repl_cond, - &innobase_repl_cond_mutex, &abstime); - innobase_repl_n_wait_threads--; - - if (ret != 0) { - ut_print_timestamp(stderr); - - sql_print_error("MySQL synchronous replication was " - "not able to send the binlog to the " - "slave within the timeout %lu. We " - "assume that the slave has become " - "inaccessible, and switch off " - "synchronous replication until the " - "communication to the slave works " - "again. MySQL synchronous replication " - "has sent binlog to the slave up to " - "file %s, position %lu. This " - "transaction needs it to be sent up " - "to file %s, position %lu.", - thd->variables.sync_replication_timeout, - innobase_repl_file_name, - (ulong) innobase_repl_pos, - trx->repl_wait_binlog_name, - (ulong) trx->repl_wait_binlog_pos); - - innobase_repl_state = 0; - - pthread_mutex_unlock(&innobase_repl_cond_mutex); - - return(0); - } - - goto try_again; - } -#endif // HAVE_REPLICATION return(0); } -#ifdef HAVE_REPLICATION -/********************************************************************* -In synchronous replication, reports to InnoDB up to which binlog position -we have sent the binlog to the slave. Note that replication is synchronous -for one slave only. For other slaves, we do nothing in this function. This -function is used in a replication master. */ - -int -innobase_repl_report_sent_binlog( -/*=============================*/ - /* out: 0 */ - THD* thd, /* in: thread doing the binlog communication to - the slave */ - char* log_file_name, /* in: binlog file name */ - my_off_t end_offset) /* in: the offset in the binlog file up to - which we sent the contents to the slave */ -{ - int cmp; - ibool can_release_threads = 0; - - if (!innodb_inited) { - - return 0; - } - - /* If synchronous replication is not switched on, or this thd is - sending binlog to a slave where we do not need synchronous replication, - then return immediately */ - - if (thd->server_id != thd->variables.sync_replication_slave_id) { - - /* Do nothing */ - - return(0); - } - - pthread_mutex_lock(&innobase_repl_cond_mutex); - - if (innobase_repl_state == 0) { - - ut_print_timestamp(stderr); - sql_print_warning("Switching MySQL synchronous replication on " - "again at binlog file %s, position %lu", - log_file_name, (ulong) end_offset); - - innobase_repl_state = 1; - } - - /* The position should increase monotonically, since just one thread - is sending the binlog to the slave for which we want synchronous - replication. Let us check this, and print an error to the .err log - if that is not the case. */ - - if (innobase_repl_file_name_inited) { - cmp = strcmp(log_file_name, innobase_repl_file_name); - - if (cmp < 0 - || (cmp == 0 && end_offset < innobase_repl_pos)) { - - ut_print_timestamp(stderr); - sql_print_error("MySQL synchronous replication has " - "sent binlog to the slave up to file " - "%s, position %lu, but now MySQL " - "reports that it sent the binlog only " - "up to file %s, position %lu", - innobase_repl_file_name, - (ulong) innobase_repl_pos, - log_file_name, (ulong) end_offset); - } - } - - strcpy(innobase_repl_file_name, log_file_name); - innobase_repl_pos = end_offset; - innobase_repl_file_name_inited = 1; - - if (innobase_repl_n_wait_threads > 0) { - /* Let us check if some of the waiting threads doing a trx - commit can now proceed */ - - cmp = strcmp(innobase_repl_file_name, - innobase_repl_wait_file_name); - if (cmp > 0 - || (cmp == 0 && innobase_repl_pos - >= innobase_repl_wait_pos)) { - - /* Yes, at least one waiting thread can now proceed: - let us release all waiting threads with a broadcast */ - - can_release_threads = 1; - - innobase_repl_wait_file_name_inited = 0; - } - } - - pthread_mutex_unlock(&innobase_repl_cond_mutex); - - if (can_release_threads) { - - pthread_cond_broadcast(&innobase_repl_cond); - } - - return(0); -} -#endif /* HAVE_REPLICATION */ /********************************************************************* Rolls back a transaction or the latest SQL statement. */ @@ -2444,8 +2211,7 @@ ha_innobase::open( /* Get pointer to a table object in InnoDB dictionary cache */ - ib_table = dict_table_get_and_increment_handle_count( - norm_name, NULL); + ib_table = dict_table_get_and_increment_handle_count(norm_name); if (NULL == ib_table) { ut_print_timestamp(stderr); @@ -5026,7 +4792,7 @@ ha_innobase::create( log_buffer_flush_to_disk(); - innobase_table = dict_table_get(norm_name, NULL); + innobase_table = dict_table_get(norm_name); DBUG_ASSERT(innobase_table != 0); diff --git a/handler/ha_innodb.h b/handler/ha_innodb.h index 6bbe3a562d7..4f0c9eb151b 100644 --- a/handler/ha_innodb.h +++ b/handler/ha_innodb.h @@ -316,9 +316,6 @@ int innobase_rollback_by_xid( XID *xid); /* in : X/Open XA Transaction Identification */ -int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name, - my_off_t end_offset); - /*********************************************************************** Create a consistent view for a cursor based on current transaction which is created if the corresponding MySQL thread still lacks one. diff --git a/ibuf/ibuf0ibuf.c b/ibuf/ibuf0ibuf.c index 1fae913fcfb..c30e75dd7be 100644 --- a/ibuf/ibuf0ibuf.c +++ b/ibuf/ibuf0ibuf.c @@ -144,6 +144,7 @@ static ulint ibuf_rnd = 986058871; ulint ibuf_flush_count = 0; +#ifdef UNIV_IBUF_DEBUG /* Dimensions for the ibuf_count array */ #define IBUF_COUNT_N_SPACES 500 #define IBUF_COUNT_N_PAGES 2000 @@ -152,6 +153,7 @@ ulint ibuf_flush_count = 0; static ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; static ibool ibuf_counts_inited = FALSE; +#endif /* The start address for an insert buffer bitmap page bitmap */ #define IBUF_BITMAP PAGE_DATA @@ -314,6 +316,7 @@ ibuf_tree_root_get( return(page); } +#ifdef UNIV_IBUF_DEBUG /********************************************************************** Gets the ibuf count for a given page. */ @@ -338,7 +341,6 @@ ibuf_count_get( /********************************************************************** Sets the ibuf count for a given page. */ -#ifdef UNIV_IBUF_DEBUG static void ibuf_count_set( @@ -389,23 +391,18 @@ ibuf_init_at_db_start(void) ibuf_count_set(i, j, 0); } } + + ibuf_counts_inited = TRUE; } #endif - mutex_create(&ibuf_pessimistic_insert_mutex); + mutex_create(&ibuf_pessimistic_insert_mutex, + SYNC_IBUF_PESS_INSERT_MUTEX); - mutex_set_level(&ibuf_pessimistic_insert_mutex, - SYNC_IBUF_PESS_INSERT_MUTEX); - mutex_create(&ibuf_mutex); + mutex_create(&ibuf_mutex, SYNC_IBUF_MUTEX); - mutex_set_level(&ibuf_mutex, SYNC_IBUF_MUTEX); - - mutex_create(&ibuf_bitmap_mutex); - - mutex_set_level(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX); + mutex_create(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX); fil_ibuf_init_at_db_start(); - - ibuf_counts_inited = TRUE; } /********************************************************************** diff --git a/include/dict0dict.h b/include/dict0dict.h index 2120868b764..50e167fb91c 100644 --- a/include/dict0dict.h +++ b/include/dict0dict.h @@ -265,17 +265,16 @@ dict_foreign_parse_drop_constraints( const char*** constraints_to_drop); /* out: id's of the constraints to drop */ /************************************************************************** -Returns a table object and memoryfixes it. NOTE! This is a high-level -function to be used mainly from outside the 'dict' directory. Inside this -directory dict_table_get_low is usually the appropriate function. */ +Returns a table object. NOTE! This is a high-level function to be used +mainly from outside the 'dict' directory. Inside this directory +dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ /* out: table, NULL if does not exist */ - const char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + const char* table_name); /* in: table name */ /************************************************************************** Returns a table object and increments MySQL open handle count on the table. */ @@ -285,10 +284,9 @@ dict_table_get_and_increment_handle_count( /*======================================*/ /* out: table, NULL if does not exist */ - const char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle or NULL */ + const char* table_name); /* in: table name */ /************************************************************************** -Returns a table object, based on table id, and memoryfixes it. */ +Returns a table object based on table id. */ dict_table_t* dict_table_get_on_id( @@ -297,21 +295,13 @@ dict_table_get_on_id( dulint table_id, /* in: table id */ trx_t* trx); /* in: transaction handle */ /************************************************************************** -Returns a table object, based on table id, and memoryfixes it. */ +Returns a table object based on table id. */ UNIV_INLINE dict_table_t* dict_table_get_on_id_low( /*=====================*/ /* out: table, NULL if does not exist */ - dulint table_id, /* in: table id */ - trx_t* trx); /* in: transaction handle */ -/************************************************************************** -Releases a table from being memoryfixed. Currently this has no relevance. */ -UNIV_INLINE -void -dict_table_release( -/*===============*/ - dict_table_t* table); /* in: table to be released */ + dulint table_id); /* in: table id */ /************************************************************************** Checks if a table is in the dictionary cache. */ UNIV_INLINE diff --git a/include/dict0dict.ic b/include/dict0dict.ic index 3dcc0b35707..1a99d2d8b45 100644 --- a/include/dict0dict.ic +++ b/include/dict0dict.ic @@ -577,14 +577,13 @@ dict_table_get_low( } /************************************************************************** -Returns a table object, based on table id, and memoryfixes it. */ +Returns a table object based on table id. */ UNIV_INLINE dict_table_t* dict_table_get_on_id_low( /*=====================*/ /* out: table, NULL if does not exist */ - dulint table_id, /* in: table id */ - trx_t* trx) /* in: transaction handle */ + dulint table_id) /* in: table id */ { dict_table_t* table; ulint fold; @@ -592,7 +591,6 @@ dict_table_get_on_id_low( #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 */ fold = ut_fold_dulint(table_id); @@ -603,32 +601,11 @@ dict_table_get_on_id_low( table = dict_load_table_on_id(table_id); } - if (table != NULL) { - table->mem_fix++; - - /* lock_push(trx, table, LOCK_DICT_MEM_FIX) */ - } - /* TODO: should get the type information from MySQL */ return(table); } -/************************************************************************** -Releases a table from being memoryfixed. Currently this has no relevance. */ -UNIV_INLINE -void -dict_table_release( -/*===============*/ - dict_table_t* table) /* in: table to be released */ -{ - mutex_enter(&(dict_sys->mutex)); - - table->mem_fix--; - - mutex_exit(&(dict_sys->mutex)); -} - /************************************************************************** Returns an index object. */ UNIV_INLINE diff --git a/include/dict0mem.h b/include/dict0mem.h index 67d40bb732a..45fc682178e 100644 --- a/include/dict0mem.h +++ b/include/dict0mem.h @@ -172,10 +172,6 @@ struct dict_tree_struct{ the same memory cache line */ rw_lock_t lock; /* read-write lock protecting the upper levels of the index tree */ - ulint mem_fix;/* count of how many times this tree - struct has been memoryfixed (by mini- - transactions wanting to access the index - tree) */ dict_index_t* tree_index; /* the index stored in the index tree */ ulint magic_n;/* magic number */ @@ -318,9 +314,6 @@ struct dict_table_struct{ which refer to this table */ UT_LIST_NODE_T(dict_table_t) table_LRU; /* node of the LRU list of tables */ - ulint mem_fix;/* count of how many times the table - and its indexes has been fixed in memory; - currently NOT used */ ulint n_mysql_handles_opened; /* count of how many handles MySQL has opened to this table; dropping of the table is diff --git a/include/fsp0fsp.h b/include/fsp0fsp.h index 9006e31178f..25dd2ef27c9 100644 --- a/include/fsp0fsp.h +++ b/include/fsp0fsp.h @@ -369,24 +369,28 @@ description takes less than 1 byte; a descriptor page is repeated every this many file pages */ #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE -/* The space low address page map, and also offsets for extent descriptor and -bitmap pages which are repeated always after XDES_DESCRIBED_PER_PAGE more -pages: */ +/* The space low address page map */ /*--------------------------------------*/ -#define FSP_XDES_OFFSET 0 -#define FSP_IBUF_BITMAP_OFFSET 1 + /* The following two pages are repeated + every XDES_DESCRIBED_PER_PAGE pages in + every tablespace. */ +#define FSP_XDES_OFFSET 0 /* extent descriptor */ +#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */ /* The ibuf bitmap pages are the ones whose page number is the number above plus a multiple of XDES_DESCRIBED_PER_PAGE */ -#define FSP_FIRST_INODE_PAGE_NO 2 -#define FSP_IBUF_HEADER_PAGE_NO 3 -#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 + +#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */ + /* The following pages exist + in the system tablespace (space 0). */ +#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */ +#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */ /* The ibuf tree root page number in tablespace 0; its fseg inode is on the page number FSP_FIRST_INODE_PAGE_NO */ -#define FSP_TRX_SYS_PAGE_NO 5 -#define FSP_FIRST_RSEG_PAGE_NO 6 -#define FSP_DICT_HDR_PAGE_NO 7 +#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */ +#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */ +#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */ /*--------------------------------------*/ #ifndef UNIV_NONINL diff --git a/include/ibuf0ibuf.h b/include/ibuf0ibuf.h index 34f29ae5dec..77fefe2020b 100644 --- a/include/ibuf0ibuf.h +++ b/include/ibuf0ibuf.h @@ -267,6 +267,7 @@ ibuf_parse_bitmap_init( byte* end_ptr,/* in: buffer end */ page_t* page, /* in: page or NULL */ mtr_t* mtr); /* in: mtr or NULL */ +#ifdef UNIV_IBUF_DEBUG /********************************************************************** Gets the ibuf count for a given page. */ @@ -277,6 +278,7 @@ ibuf_count_get( currently buffered for this page */ ulint space, /* in: space id */ ulint page_no);/* in: page number */ +#endif /********************************************************************** Looks if the insert buffer is empty. */ diff --git a/include/mem0mem.h b/include/mem0mem.h index e2f8be98b01..99f863ea6fe 100644 --- a/include/mem0mem.h +++ b/include/mem0mem.h @@ -297,8 +297,8 @@ char* mem_heap_strdup( /*============*/ /* out, own: a copy of the string */ - mem_heap_t* heap, /* in: memory heap where string is allocated */ - const char* str); /* in: string to be copied */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str); /* in: string to be copied */ /************************************************************************** Makes a NUL-terminated copy of a nonterminated string, allocated from a memory heap. */ @@ -311,6 +311,28 @@ mem_heap_strdupl( const char* str, /* in: string to be copied */ ulint len); /* in: length of str, in bytes */ +/************************************************************************** +Concatenate two strings and return the result, using a memory heap. */ + +char* +mem_heap_strcat( +/*============*/ + /* out, own: the result */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* s1, /* in: string 1 */ + const char* s2); /* in: string 2 */ + +/************************************************************************** +Duplicate a block of data, allocated from a memory heap. */ + +void* +mem_heap_dup( +/*=========*/ + /* out, own: a copy of the data */ + mem_heap_t* heap, /* in: memory heap where copy is allocated */ + const void* data, /* in: data to be copied */ + ulint len); /* in: length of data, in bytes */ + #ifdef MEM_PERIODIC_CHECK /********************************************************************** Goes through the list of all allocated mem blocks, checks their magic diff --git a/include/os0thread.h b/include/os0thread.h index 4685ffad351..3cf05feb3a9 100644 --- a/include/os0thread.h +++ b/include/os0thread.h @@ -77,7 +77,7 @@ os_thread_create( void* arg, /* in: argument to start function */ os_thread_id_t* thread_id); /* out: id of the created - thread */ + thread, or NULL */ int os_thread_join( /*===========*/ diff --git a/include/pars0pars.h b/include/pars0pars.h index 68b8ae41cc0..b3140008a3c 100644 --- a/include/pars0pars.h +++ b/include/pars0pars.h @@ -531,6 +531,16 @@ pars_info_add_function( pars_user_func_cb_t func, /* in: function address */ void* arg); /* in: user-supplied argument */ +/******************************************************************** +Add bound id. */ + +void +pars_info_add_id( +/*=============*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const char* id); /* in: id */ + /******************************************************************** Get user function with the given name.*/ @@ -553,6 +563,17 @@ pars_info_get_bound_lit( pars_info_t* info, /* in: info struct */ const char* name); /* in: bound literal name to find */ +/******************************************************************** +Get bound id with the given name.*/ + +pars_bound_id_t* +pars_info_get_bound_id( +/*===================*/ + /* out: bound id, or NULL if not + found */ + pars_info_t* info, /* in: info struct */ + const char* name); /* in: bound id name to find */ + /* Extra information supplied for pars_sql(). */ struct pars_info_struct { @@ -562,6 +583,8 @@ struct pars_info_struct { (pars_user_func_t*) */ ib_vector_t* bound_lits; /* bound literals, or NULL (pars_bound_lit_t*) */ + ib_vector_t* bound_ids; /* bound ids, or NULL + (pars_bound_id_t*) */ ibool graph_owns_us; /* if TRUE (which is the default), que_graph_free() will free us */ @@ -583,6 +606,12 @@ struct pars_bound_lit_struct { ulint prtype; /* precise type, e.g. DATA_UNSIGNED */ }; +/* Bound id. */ +struct pars_bound_id_struct { + const char* name; /* name */ + const char* id; /* id */ +}; + /* Struct used to denote a reserved word in a parsing tree */ struct pars_res_word_struct{ int code; /* the token code for the reserved word from diff --git a/include/pars0sym.h b/include/pars0sym.h index 14f762d5b7a..fc7df92ff60 100644 --- a/include/pars0sym.h +++ b/include/pars0sym.h @@ -82,6 +82,16 @@ sym_tab_add_id( byte* name, /* in: identifier name */ ulint len); /* in: identifier length */ +/********************************************************************** +Add a bound identifier to a symbol table. */ + +sym_node_t* +sym_tab_add_bound_id( +/*===========*/ + /* out: symbol table node */ + sym_tab_t* sym_tab, /* in: symbol table */ + const char* name); /* in: name of bound id */ + #define SYM_CLUST_FIELD_NO 0 #define SYM_SEC_FIELD_NO 1 diff --git a/include/pars0types.h b/include/pars0types.h index 6fcfaf23024..bf7df89a883 100644 --- a/include/pars0types.h +++ b/include/pars0types.h @@ -12,6 +12,7 @@ Created 1/11/1998 Heikki Tuuri typedef struct pars_info_struct pars_info_t; typedef struct pars_user_func_struct pars_user_func_t; typedef struct pars_bound_lit_struct pars_bound_lit_t; +typedef struct pars_bound_id_struct pars_bound_id_t; typedef struct sym_node_struct sym_node_t; typedef struct sym_tab_struct sym_tab_t; typedef struct pars_res_word_struct pars_res_word_t; diff --git a/include/row0purge.h b/include/row0purge.h index 52dd2fce551..2653f8a354d 100644 --- a/include/row0purge.h +++ b/include/row0purge.h @@ -56,9 +56,7 @@ struct purge_node_struct{ determined by ref was found in the clustered index, and we were able to position pcur on it */ - dict_table_t* table; /* table where purge is done; NOTE that the - table has to be released explicitly with - dict_table_release */ + dict_table_t* table; /* table where purge is done */ ulint cmpl_info;/* compiler analysis info of an update */ upd_t* update; /* update vector for a clustered index record */ dtuple_t* ref; /* NULL, or row reference to the next row to diff --git a/include/row0undo.h b/include/row0undo.h index 5e3f514ad8d..29cfbc9ac20 100644 --- a/include/row0undo.h +++ b/include/row0undo.h @@ -84,9 +84,7 @@ struct undo_node_struct{ record */ btr_pcur_t pcur; /* persistent cursor used in searching the clustered index record */ - dict_table_t* table; /* table where undo is done; NOTE that the - table has to be released explicitly with - dict_table_release */ + dict_table_t* table; /* table where undo is done */ ulint cmpl_info;/* compiler analysis of an update */ upd_t* update; /* update vector for a clustered index record */ dtuple_t* ref; /* row reference to the next row to handle */ diff --git a/include/srv0srv.h b/include/srv0srv.h index 906f0e3875c..ff82cb2999a 100644 --- a/include/srv0srv.h +++ b/include/srv0srv.h @@ -157,33 +157,12 @@ extern ulint srv_pool_size; extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; -extern ulint srv_sim_disk_wait_pct; -extern ulint srv_sim_disk_wait_len; -extern ibool srv_sim_disk_wait_by_yield; -extern ibool srv_sim_disk_wait_by_wait; - -extern ibool srv_measure_contention; -extern ibool srv_measure_by_spin; - extern ibool srv_print_thread_releases; extern ibool srv_print_lock_waits; extern ibool srv_print_buf_io; extern ibool srv_print_log_io; -extern ibool srv_print_parsed_sql; extern ibool srv_print_latch_waits; -extern ibool srv_test_nocache; -extern ibool srv_test_cache_evict; - -extern ibool srv_test_extra_mutexes; -extern ibool srv_test_sync; -extern ulint srv_test_n_threads; -extern ulint srv_test_n_loops; -extern ulint srv_test_n_free_rnds; -extern ulint srv_test_n_reserved_rnds; -extern ulint srv_test_n_mutexes; -extern ulint srv_test_array_size; - extern ulint srv_activity_count; extern ulint srv_fatal_semaphore_wait_threshold; extern ulint srv_dml_needed_delay; @@ -365,11 +344,7 @@ srv_release_threads( /************************************************************************* The master thread controlling the server. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_master_thread( /*==============*/ /* out: a dummy parameter */ @@ -451,11 +426,7 @@ srv_release_mysql_thread_if_suspended( A thread which wakes up threads whose lock wait may have lasted too long. This also prints the info output by various InnoDB monitors. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_lock_timeout_and_monitor_thread( /*================================*/ /* out: a dummy parameter */ @@ -465,11 +436,7 @@ srv_lock_timeout_and_monitor_thread( A thread which prints warnings about semaphore waits which have lasted too long. These can be used to track bugs which cause hangs. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_error_monitor_thread( /*=====================*/ /* out: a dummy parameter */ @@ -567,9 +534,6 @@ struct export_var_struct{ /* The server system struct */ struct srv_sys_struct{ - os_event_t operational; /* created threads must wait for the - server to become operational by - waiting for this event */ srv_table_t* threads; /* server thread table */ UT_LIST_BASE_NODE_T(que_thr_t) tasks; /* task queue */ diff --git a/include/sync0rw.h b/include/sync0rw.h index e6ca3258099..616d3eeb978 100644 --- a/include/sync0rw.h +++ b/include/sync0rw.h @@ -61,7 +61,7 @@ Creates, or rather, initializes an rw-lock object in a specified memory location (which must be appropriately aligned). The rw-lock is initialized to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free is necessary only if the memory block containing it is freed. */ -#define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__, #L) +#define rw_lock_create(L, level) rw_lock_create_func((L), (level), __FILE__, __LINE__, #L) /*=====================*/ /********************************************************************** @@ -74,9 +74,10 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ + ulint level, /* in: level */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name); /* in: mutex name */ + ulint cline, /* in: file line where created */ + const char* cmutex_name); /* in: mutex name */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing the rw-lock is freed. Removes an rw-lock object from the global list. The @@ -299,14 +300,6 @@ rw_lock_x_unlock_direct( /*====================*/ rw_lock_t* lock); /* in: rw-lock */ /********************************************************************** -Sets the rw-lock latching level field. */ - -void -rw_lock_set_level( -/*==============*/ - rw_lock_t* lock, /* in: rw-lock */ - ulint level); /* in: level */ -/********************************************************************** Returns the value of writer_count for the lock. Does not reserve the lock mutex, so the caller must be sure it is not changed during the call. */ UNIV_INLINE @@ -448,8 +441,8 @@ struct rw_lock_struct { /* In the debug version: pointer to the debug info list of the lock */ #endif /* UNIV_SYNC_DEBUG */ - ulint level; /* Level in the global latching - order; default SYNC_LEVEL_NONE */ + + ulint level; /* Level in the global latching order. */ const char* cfile_name;/* File name where lock created */ ulint cline; /* Line where created */ const char* last_s_file_name;/* File name where last s-locked */ diff --git a/include/sync0sync.h b/include/sync0sync.h index 0a233843b50..64b245246f8 100644 --- a/include/sync0sync.h +++ b/include/sync0sync.h @@ -39,7 +39,7 @@ location (which must be appropriately aligned). The mutex is initialized in the reset state. Explicit freeing of the mutex with mutex_free is necessary only if the memory block containing it is freed. */ -#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__, #M) +#define mutex_create(M, level) mutex_create_func((M), (level), __FILE__, __LINE__, #M) /*===================*/ /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory @@ -51,6 +51,7 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ + ulint level, /* in: level */ const char* cfile_name, /* in: file name where created */ ulint cline, /* in: file line where created */ const char* cmutex_name); /* in: mutex name */ @@ -155,14 +156,6 @@ mutex_validate( /*===========*/ mutex_t* mutex); /********************************************************************** -Sets the mutex latching level field. */ - -void -mutex_set_level( -/*============*/ - mutex_t* mutex, /* in: mutex */ - ulint level); /* in: level */ -/********************************************************************** Adds a latch and its level in the thread level array. Allocates the memory for the array if called first time for this OS thread. Makes the checks against other latch levels stored in the array for this thread. */ @@ -171,8 +164,8 @@ void sync_thread_add_level( /*==================*/ void* latch, /* in: pointer to a mutex or an rw-lock */ - ulint level); /* in: level in the latching order; if SYNC_LEVEL_NONE, - nothing is done */ + ulint level); /* in: level in the latching order; if + SYNC_LEVEL_VARYING, nothing is done */ /********************************************************************** Removes a latch from the thread level array if it is found there. */ @@ -383,7 +376,12 @@ or row lock! */ #define SYNC_USER_TRX_LOCK 9999 #define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress latching order checking */ -#define SYNC_LEVEL_NONE 2000 /* default: level not defined */ +#define SYNC_LEVEL_VARYING 2000 /* Level is varying. Only used with + buffer pool page locks, which do not + have a fixed level, but instead have + their level set after the page is + locked; see e.g. + ibuf_bitmap_get_map_page(). */ #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve this in X-mode, implicit or backround operations purge, rollback, foreign @@ -426,6 +424,7 @@ or row lock! */ #define SYNC_TRX_SYS_HEADER 290 #define SYNC_LOG 170 #define SYNC_RECV 168 +#define SYNC_WORK_QUEUE 161 #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory heap that can be extended to the buffer pool, its logical level is @@ -472,8 +471,7 @@ struct mutex_struct { os_thread_id_t thread_id; /* Debug version: The thread id of the thread which locked the mutex. */ #endif /* UNIV_SYNC_DEBUG */ - ulint level; /* Level in the global latching - order; default SYNC_LEVEL_NONE */ + ulint level; /* Level in the global latching order */ const char* cfile_name;/* File name where mutex created */ ulint cline; /* Line where created */ ulint magic_n; diff --git a/include/trx0roll.h b/include/trx0roll.h index 7b450f9da39..25546430ba0 100644 --- a/include/trx0roll.h +++ b/include/trx0roll.h @@ -107,11 +107,7 @@ transaction already was committed, then we clean up a possible insert undo log. If the transaction was not yet committed, then we roll it back. Note: this is done in a background thread. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t trx_rollback_or_clean_all_without_sess( /*===================================*/ /* out: a dummy parameter */ diff --git a/include/trx0sys.h b/include/trx0sys.h index 7cf0ae87cb9..f9fb84ad411 100644 --- a/include/trx0sys.h +++ b/include/trx0sys.h @@ -75,6 +75,15 @@ multiple tablespace format. */ void trx_sys_mark_upgraded_to_multiple_tablespaces(void); /*===============================================*/ +/******************************************************************** +Determines if a page number is located inside the doublewrite buffer. */ + +ibool +trx_doublewrite_page_inside( +/*========================*/ + /* out: TRUE if the location is inside + the two blocks of the doublewrite buffer */ + ulint page_no); /* in: page number */ /******************************************************************* Checks if a page address is the trx sys header page. */ UNIV_INLINE diff --git a/include/univ.i b/include/univ.i index d307560990d..cf7589ddc40 100644 --- a/include/univ.i +++ b/include/univ.i @@ -82,17 +82,18 @@ memory is read outside the allocated blocks. */ /* Make a non-inline debug version */ +#if 0 #define UNIV_DEBUG -/* #define UNIV_MEM_DEBUG #define UNIV_IBUF_DEBUG #define UNIV_SYNC_DEBUG #define UNIV_SEARCH_DEBUG #define UNIV_SYNC_PERF_STAT #define UNIV_SEARCH_PERF_STAT -#define UNIV_SRV_PRINT_LATCH_WAITS; +#define UNIV_SRV_PRINT_LATCH_WAITS #define UNIV_ZIP_DEBUG -*/ +#endif + #define UNIV_LIGHT_MEM_DEBUG #define YYDEBUG 1 @@ -274,6 +275,18 @@ it is read or written. */ /* Compile-time constant of the given array's size. */ #define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0])) +/* The return type from a thread's start function differs between Unix and +Windows, so define a typedef for it and a macro to use at the end of such +functions. */ + +#ifdef __WIN__ +typedef ulint os_thread_ret_t; +#define OS_THREAD_DUMMY_RETURN return(0) +#else +typedef void* os_thread_ret_t; +#define OS_THREAD_DUMMY_RETURN return(NULL) +#endif + #include #include "ut0dbg.h" #include "ut0ut.h" diff --git a/include/ut0list.h b/include/ut0list.h new file mode 100644 index 00000000000..dc8e5d67e14 --- /dev/null +++ b/include/ut0list.h @@ -0,0 +1,134 @@ +/*********************************************************************** +A double-linked list. This differs from the one in ut0lst.h in that in this +one, each list node contains a pointer to the data, whereas the one in +ut0lst.h uses a strategy where the list pointers are embedded in the data +items themselves. + +Use this one when you need to store arbitrary data in the list where you +can't embed the list pointers in the data, if a data item needs to be +stored in multiple lists, etc. + +Note about the memory management: ib_list_t is a fixed-size struct whose +allocation/deallocation is done through ib_list_create/ib_list_free, but the +memory for the list nodes is allocated through a user-given memory heap, +which can either be the same for all nodes or vary per node. Most users will +probably want to create a memory heap to store the item-specific data, and +pass in this same heap to the list node creation functions, thus +automatically freeing the list node when the item's heap is freed. + +************************************************************************/ + + +#ifndef IB_LIST_H +#define IB_LIST_H + +#include "mem0mem.h" + +typedef struct ib_list_struct ib_list_t; +typedef struct ib_list_node_struct ib_list_node_t; +typedef struct ib_list_helper_struct ib_list_helper_t; + +/******************************************************************** +Create a new list. */ + +ib_list_t* +ib_list_create(void); +/*=================*/ + /* out: list */ + +/******************************************************************** +Free a list. */ + +void +ib_list_free( +/*=========*/ + ib_list_t* list); /* in: list */ + +/******************************************************************** +Add the data to the start of the list. */ + +ib_list_node_t* +ib_list_add_first( +/*==============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + void* data, /* in: data */ + mem_heap_t* heap); /* in: memory heap to use */ + +/******************************************************************** +Add the data to the end of the list. */ + +ib_list_node_t* +ib_list_add_last( +/*=============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + void* data, /* in: data */ + mem_heap_t* heap); /* in: memory heap to use */ + +/******************************************************************** +Add the data after the indicated node. */ + +ib_list_node_t* +ib_list_add_after( +/*==============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + ib_list_node_t* prev_node, /* in: node preceding new node (can + be NULL) */ + void* data, /* in: data */ + mem_heap_t* heap); /* in: memory heap to use */ + +/******************************************************************** +Remove the node from the list. */ + +void +ib_list_remove( +/*===========*/ + ib_list_t* list, /* in: list */ + ib_list_node_t* node); /* in: node to remove */ + +/******************************************************************** +Get the first node in the list. */ +UNIV_INLINE +ib_list_node_t* +ib_list_get_first( +/*==============*/ + /* out: first node, or NULL */ + ib_list_t* list); /* in: list */ + +/******************************************************************** +Get the last node in the list. */ +UNIV_INLINE +ib_list_node_t* +ib_list_get_last( +/*=============*/ + /* out: last node, or NULL */ + ib_list_t* list); /* in: list */ + +/* List. */ +struct ib_list_struct { + ib_list_node_t* first; /* first node */ + ib_list_node_t* last; /* last node */ +}; + +/* A list node. */ +struct ib_list_node_struct { + ib_list_node_t* prev; /* previous node */ + ib_list_node_t* next; /* next node */ + void* data; /* user data */ +}; + +/* Quite often, the only additional piece of data you need is the per-item +memory heap, so we have this generic struct available to use in those +cases. */ +struct ib_list_helper_struct { + mem_heap_t* heap; /* memory heap */ + void* data; /* user data */ +}; + +#ifndef UNIV_NONINL +#include "ut0list.ic" +#endif + +#endif diff --git a/include/ut0list.ic b/include/ut0list.ic new file mode 100644 index 00000000000..c2d3e4557f0 --- /dev/null +++ b/include/ut0list.ic @@ -0,0 +1,23 @@ +/******************************************************************** +Get the first node in the list. */ +UNIV_INLINE +ib_list_node_t* +ib_list_get_first( +/*==============*/ + /* out: first node, or NULL */ + ib_list_t* list) /* in: list */ +{ + return(list->first); +} + +/******************************************************************** +Get the last node in the list. */ +UNIV_INLINE +ib_list_node_t* +ib_list_get_last( +/*=============*/ + /* out: last node, or NULL */ + ib_list_t* list) /* in: list */ +{ + return(list->last); +} diff --git a/include/ut0wqueue.h b/include/ut0wqueue.h new file mode 100644 index 00000000000..57f2297beee --- /dev/null +++ b/include/ut0wqueue.h @@ -0,0 +1,60 @@ +/*********************************************************************** +A Work queue. Threads can add work items to the queue and other threads can +wait for work items to be available and take them off the queue for +processing. + +************************************************************************/ + +#ifndef IB_WORK_QUEUE_H +#define IB_WORK_QUEUE_H + +#include "ut0list.h" +#include "mem0mem.h" +#include "os0sync.h" +#include "sync0types.h" + +typedef struct ib_wqueue_struct ib_wqueue_t; + +/******************************************************************** +Create a new work queue. */ + +ib_wqueue_t* +ib_wqueue_create(void); +/*===================*/ + /* out: work queue */ + +/******************************************************************** +Free a work queue. */ + +void +ib_wqueue_free( +/*===========*/ + ib_wqueue_t* wq); /* in: work queue */ + +/******************************************************************** +Add a work item to the queue. */ + +void +ib_wqueue_add( +/*==========*/ + ib_wqueue_t* wq, /* in: work queue */ + void* item, /* in: work item */ + mem_heap_t* heap); /* in: memory heap to use for allocating the + list node */ + +/******************************************************************** +Wait for a work item to appear in the queue. */ + +void* +ib_wqueue_wait( + /* out: work item */ + ib_wqueue_t* wq); /* in: work queue */ + +/* Work queue. */ +struct ib_wqueue_struct { + mutex_t mutex; /* mutex protecting everything */ + ib_list_t* items; /* work item list */ + os_event_t event; /* event we use to signal additions to list */ +}; + +#endif diff --git a/log/log0log.c b/log/log0log.c index ea3b74c00f9..db6b8fabf6f 100644 --- a/log/log0log.c +++ b/log/log0log.c @@ -741,8 +741,7 @@ log_init(void) log_sys = mem_alloc(sizeof(log_t)); - mutex_create(&(log_sys->mutex)); - mutex_set_level(&(log_sys->mutex), SYNC_LOG); + mutex_create(&log_sys->mutex, SYNC_LOG); mutex_enter(&(log_sys->mutex)); @@ -798,8 +797,7 @@ log_init(void) log_sys->last_checkpoint_lsn = log_sys->lsn; log_sys->n_pending_checkpoint_writes = 0; - rw_lock_create(&(log_sys->checkpoint_lock)); - rw_lock_set_level(&(log_sys->checkpoint_lock), SYNC_NO_ORDER_CHECK); + rw_lock_create(&log_sys->checkpoint_lock, SYNC_NO_ORDER_CHECK); log_sys->checkpoint_buf = ut_align( mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE), @@ -815,8 +813,7 @@ log_init(void) log_sys->n_pending_archive_ios = 0; - rw_lock_create(&(log_sys->archive_lock)); - rw_lock_set_level(&(log_sys->archive_lock), SYNC_NO_ORDER_CHECK); + rw_lock_create(&log_sys->archive_lock, SYNC_NO_ORDER_CHECK); log_sys->archive_buf = NULL; diff --git a/log/log0recv.c b/log/log0recv.c index e8b80eac4a6..e1be3b183f5 100644 --- a/log/log0recv.c +++ b/log/log0recv.c @@ -113,8 +113,7 @@ recv_sys_create(void) recv_sys = mem_alloc(sizeof(recv_sys_t)); - mutex_create(&(recv_sys->mutex)); - mutex_set_level(&(recv_sys->mutex), SYNC_RECV); + mutex_create(&recv_sys->mutex, SYNC_RECV); recv_sys->heap = NULL; recv_sys->addr_hash = NULL; @@ -2969,7 +2968,6 @@ recv_recovery_from_checkpoint_finish(void) /*======================================*/ { int i; - os_thread_id_t recovery_thread_id; /* Apply the hashed log records to the respective file pages */ @@ -3013,7 +3011,7 @@ recv_recovery_from_checkpoint_finish(void) session */ os_thread_create(trx_rollback_or_clean_all_without_sess, - (void *)&i, &recovery_thread_id); + (void *)&i, NULL); } } diff --git a/mem/mem0dbg.c b/mem/mem0dbg.c index 86c33a22531..1220c2c8e82 100644 --- a/mem/mem0dbg.c +++ b/mem/mem0dbg.c @@ -122,8 +122,7 @@ mem_init( /* Initialize the hash table */ ut_a(FALSE == mem_hash_initialized); - mutex_create(&mem_hash_mutex); - mutex_set_level(&mem_hash_mutex, SYNC_MEM_HASH); + mutex_create(&mem_hash_mutex, SYNC_MEM_HASH); for (i = 0; i < MEM_HASH_SIZE; i++) { UT_LIST_INIT(*mem_hash_get_nth_cell(i)); diff --git a/mem/mem0mem.c b/mem/mem0mem.c index 90d3f4fa6b1..c3bf48e0098 100644 --- a/mem/mem0mem.c +++ b/mem/mem0mem.c @@ -107,11 +107,49 @@ char* mem_heap_strdup( /*============*/ /* out, own: a copy of the string */ - mem_heap_t* heap, /* in: memory heap where string is allocated */ - const char* str) /* in: string to be copied */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* str) /* in: string to be copied */ { - ulint len = strlen(str) + 1; - return(memcpy(mem_heap_alloc(heap, len), str, len)); + return(mem_heap_dup(heap, str, strlen(str) + 1)); +} + +/************************************************************************** +Duplicate a block of data, allocated from a memory heap. */ + +void* +mem_heap_dup( +/*=========*/ + /* out, own: a copy of the data */ + mem_heap_t* heap, /* in: memory heap where copy is allocated */ + const void* data, /* in: data to be copied */ + ulint len) /* in: length of data, in bytes */ +{ + return(memcpy(mem_heap_alloc(heap, len), data, len)); +} + +/************************************************************************** +Concatenate two strings and return the result, using a memory heap. */ + +char* +mem_heap_strcat( +/*============*/ + /* out, own: the result */ + mem_heap_t* heap, /* in: memory heap where string is allocated */ + const char* s1, /* in: string 1 */ + const char* s2) /* in: string 2 */ +{ + char* s; + ulint s1_len = strlen(s1); + ulint s2_len = strlen(s2); + + s = mem_heap_alloc(heap, s1_len + s2_len + 1); + + memcpy(s, s1, s1_len); + memcpy(s + s1_len, s2, s2_len); + + s[s1_len + s2_len] = '\0'; + + return(s); } /******************************************************************* diff --git a/mem/mem0pool.c b/mem/mem0pool.c index a61ab1ce170..5606921758c 100644 --- a/mem/mem0pool.c +++ b/mem/mem0pool.c @@ -204,8 +204,7 @@ mem_pool_create( pool->buf = ut_malloc_low(size, FALSE, TRUE); pool->size = size; - mutex_create(&(pool->mutex)); - mutex_set_level(&(pool->mutex), SYNC_MEM_POOL); + mutex_create(&pool->mutex, SYNC_MEM_POOL); /* Initialize the free lists */ diff --git a/mysql-test/innodb.result b/mysql-test/innodb.result index 745d31c7734..e6031fe92c0 100644 --- a/mysql-test/innodb.result +++ b/mysql-test/innodb.result @@ -1632,6 +1632,30 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +create table t1 (a int) engine=innodb; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +begin; +delete from t1; +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 2 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +drop table t1; create table t1 (c char(10), index (c,c)) engine=innodb; ERROR 42S21: Duplicate column name 'c' create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb; @@ -3125,9 +3149,7 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL, - KEY `t2_ibfk_0` (`a`), - CONSTRAINT `t2_ibfk_0` FOREIGN KEY (`a`) REFERENCES `t1` (`a`), - CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) + KEY `t2_ibfk_0` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t2,t1; create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb; @@ -3206,6 +3228,46 @@ UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu'; ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry DROP TABLE t2; DROP TABLE t1; +create table t1 ( +c1 bigint not null, +c2 bigint not null, +primary key (c1), +unique key (c2) +) engine=innodb; +create table t2 ( +c1 bigint not null, +primary key (c1) +) engine=innodb; +alter table t1 add constraint c2_fk foreign key (c2) +references t2(c1) on delete cascade; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `c2` bigint(20) NOT NULL, + PRIMARY KEY (`c1`), + UNIQUE KEY `c2` (`c2`), + CONSTRAINT `c2_fk` FOREIGN KEY (`c2`) REFERENCES `t2` (`c1`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +alter table t1 drop foreign key c2_fk; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `c2` bigint(20) NOT NULL, + PRIMARY KEY (`c1`), + UNIQUE KEY `c2` (`c2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1, t2; +create table t1(a date) engine=innodb; +create table t2(a date, key(a)) engine=innodb; +insert into t1 values('2005-10-01'); +insert into t2 values('2005-10-01'); +select * from t1, t2 +where t2.a between t1.a - interval 2 day and t1.a + interval 2 day; +a a +2005-10-01 2005-10-01 +drop table t1, t2; create table t1 (id int not null, f_id int not null, f int not null, primary key(f_id, id)) engine=innodb; create table t2 (id int not null,s_id int not null,s varchar(200), diff --git a/mysql-test/innodb.test b/mysql-test/innodb.test index a0ecca785af..0dc9627944b 100644 --- a/mysql-test/innodb.test +++ b/mysql-test/innodb.test @@ -1,3 +1,16 @@ +####################################################################### +# # +# Please, DO NOT TOUCH this file as well as the innodb.result file. # +# These files are to be modified ONLY BY INNOBASE guys. # +# # +# Use innodb_mysql.[test|result] files instead. # +# # +# If nevertheless you need to make some changes here, please, forward # +# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# (otherwise your changes may be erased). # +# # +####################################################################### + -- source include/have_innodb.inc # @@ -1133,6 +1146,41 @@ show create table t2; drop table t2, t1; +# +# Let us test binlog_cache_use and binlog_cache_disk_use status vars. +# Actually this test has nothing to do with innodb per se, it just requires +# transactional table. +# +flush status; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +create table t1 (a int) engine=innodb; + +# Now we are going to create transaction which is long enough so its +# transaction binlog will be flushed to disk... +let $1=2000; +disable_query_log; +begin; +while ($1) +{ + eval insert into t1 values( $1 ); + dec $1; +} +commit; +enable_query_log; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +# Transaction which should not be flushed to disk and so should not +# increase binlog_cache_disk_use. +begin; +delete from t1; +commit; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; +drop table t1; + # # Bug #6126: Duplicate columns in keys gives misleading error message # @@ -2106,6 +2154,42 @@ UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu'; DROP TABLE t2; DROP TABLE t1; +# +# Bug#18477 - MySQL/InnoDB Ignoring Foreign Keys in ALTER TABLE +# +create table t1 ( + c1 bigint not null, + c2 bigint not null, + primary key (c1), + unique key (c2) +) engine=innodb; +# +create table t2 ( + c1 bigint not null, + primary key (c1) +) engine=innodb; +# +alter table t1 add constraint c2_fk foreign key (c2) + references t2(c1) on delete cascade; +show create table t1; +# +alter table t1 drop foreign key c2_fk; +show create table t1; +# +drop table t1, t2; + +# +# Bug #14360: problem with intervals +# + +create table t1(a date) engine=innodb; +create table t2(a date, key(a)) engine=innodb; +insert into t1 values('2005-10-01'); +insert into t2 values('2005-10-01'); +select * from t1, t2 + where t2.a between t1.a - interval 2 day and t1.a + interval 2 day; +drop table t1, t2; + create table t1 (id int not null, f_id int not null, f int not null, primary key(f_id, id)) engine=innodb; create table t2 (id int not null,s_id int not null,s varchar(200), diff --git a/mysql-test/innodb_mysql.result b/mysql-test/innodb_mysql.result new file mode 100644 index 00000000000..878c5cb5451 --- /dev/null +++ b/mysql-test/innodb_mysql.result @@ -0,0 +1 @@ +drop table if exists t1; diff --git a/mysql-test/innodb_mysql.test b/mysql-test/innodb_mysql.test new file mode 100644 index 00000000000..b942b9fbc0d --- /dev/null +++ b/mysql-test/innodb_mysql.test @@ -0,0 +1,5 @@ +-- source include/have_innodb.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings diff --git a/os/os0file.c b/os/os0file.c index bbfef77ef29..6b9bd6cebce 100644 --- a/os/os0file.c +++ b/os/os0file.c @@ -3679,6 +3679,37 @@ os_aio_posix_handle( } #endif +/************************************************************************** +Do a 'last millisecond' check that the end of an uncompressed page is sensible; +reported page checksum errors from Linux seem to wipe over the page end. */ +static +void +os_file_check_page_trailers( +/*========================*/ + byte* combined_buf, /* in: combined write buffer */ + ulint total_len) /* in: size of combined_buf, in bytes + (a multiple of UNIV_PAGE_SIZE) */ +{ + ulint len; + + for (len = 0; len + UNIV_PAGE_SIZE <= total_len; + len += UNIV_PAGE_SIZE) { + byte* buf = combined_buf + len; + + if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n", + (ulong)total_len, (ulong)len); + buf_page_print(buf, 0); + fprintf(stderr, +"InnoDB: ERROR: The page to be written seems corrupt!\n"); + } + } +} + /************************************************************************** Does simulated aio. This function should be called by an i/o-handler thread. */ @@ -3716,7 +3747,6 @@ os_aio_simulated_handle( ibool ret; ulint n; ulint i; - ulint len2; segment = os_aio_get_array_and_local_segment(&array, global_segment); @@ -3924,34 +3954,15 @@ consecutive_loop: ut_error; } - /* Do a 'last millisecond' check that the page end - is sensible; reported page checksum errors from - Linux seem to wipe over the page end */ - - /* TODO: disable this for compressed pages */ - - for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len; - len2 += UNIV_PAGE_SIZE) { - if (mach_read_from_4(combined_buf + len2 - + FIL_PAGE_LSN + 4) - != mach_read_from_4(combined_buf + len2 - + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: ERROR: The page to be written seems corrupt!\n"); - fprintf(stderr, -"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n", - (ulong)total_len, (ulong)len2); - buf_page_print(combined_buf + len2, 0); - fprintf(stderr, -"InnoDB: ERROR: The page to be written seems corrupt!\n"); - } - } + os_file_check_page_trailers(combined_buf, total_len); } ret = os_file_write(slot->name, slot->file, combined_buf, slot->offset, slot->offset_high, total_len); + + if (array == os_aio_write_array) { + os_file_check_page_trailers(combined_buf, total_len); + } } else { ret = os_file_read(slot->file, combined_buf, slot->offset, slot->offset_high, total_len); diff --git a/os/os0thread.c b/os/os0thread.c index ff0362840c7..138db6426ea 100644 --- a/os/os0thread.c +++ b/os/os0thread.c @@ -96,7 +96,7 @@ os_thread_create( void* arg, /* in: argument to start function */ os_thread_id_t* thread_id) /* out: id of the created - thread */ + thread, or NULL */ { #ifdef __WIN__ os_thread_t thread; @@ -122,7 +122,9 @@ os_thread_create( ut_a(SetThreadPriority(thread, srv_query_thread_priority)); } - *thread_id = win_thread_id; + if (thread_id) { + *thread_id = win_thread_id; + } return(thread); #else @@ -180,7 +182,9 @@ os_thread_create( my_pthread_setprio(pthread, srv_query_thread_priority); } - *thread_id = pthread; + if (thread_id) { + *thread_id = pthread; + } return(pthread); #endif @@ -216,7 +220,7 @@ os_thread_join( /*===========*/ os_thread_id_t thread_id) /* in: id of the thread to join */ { - return pthread_join(thread_id, NULL); + return(pthread_join(thread_id, NULL)); } #endif /********************************************************************* diff --git a/pars/lexyy.c b/pars/lexyy.c index bbe78db1613..6d4e692e86b 100644 --- a/pars/lexyy.c +++ b/pars/lexyy.c @@ -356,8 +356,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 116 -#define YY_END_OF_BUFFER 117 +#define YY_NUM_RULES 117 +#define YY_END_OF_BUFFER 118 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -365,51 +365,51 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[394] = +static yyconst flex_int16_t yy_accept[396] = { 0, - 0, 0, 111, 111, 0, 0, 0, 0, 117, 115, - 114, 114, 7, 106, 4, 95, 101, 104, 102, 99, - 103, 115, 105, 1, 115, 100, 98, 96, 97, 109, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 107, 108, - 111, 112, 5, 6, 8, 9, 114, 90, 110, 2, - 1, 3, 91, 92, 94, 93, 89, 89, 89, 89, - 89, 89, 44, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 27, - 16, 24, 89, 89, 89, 89, 54, 61, 89, 13, + 0, 0, 112, 112, 0, 0, 0, 0, 118, 116, + 115, 115, 8, 116, 107, 5, 96, 102, 105, 103, + 100, 104, 116, 106, 1, 116, 101, 99, 97, 98, + 110, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 108, + 109, 112, 113, 6, 7, 9, 10, 115, 4, 91, + 111, 2, 1, 3, 92, 93, 95, 94, 90, 90, + 90, 90, 90, 90, 45, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 28, 17, 25, 90, 90, 90, 90, 55, 62, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 111, 112, 112, - 113, 5, 6, 8, 9, 2, 12, 45, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 26, 89, 89, 89, - 40, 89, 89, 89, 89, 20, 89, 89, 14, 89, - 89, 89, 17, 89, 89, 89, 89, 89, 80, 89, - 89, 89, 51, 11, 89, 35, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 19, 23, 89, 89, 89, 89, 89, 89, 89, 89, + 90, 14, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 112, + 113, 113, 114, 6, 7, 9, 10, 2, 13, 46, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 27, 90, + 90, 90, 41, 90, 90, 90, 90, 21, 90, 90, + 15, 90, 90, 90, 18, 90, 90, 90, 90, 90, + 81, 90, 90, 90, 52, 12, 90, 36, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 20, 24, 90, 90, 90, 90, 90, 90, - 89, 89, 89, 46, 89, 89, 29, 89, 87, 89, - 89, 38, 89, 89, 89, 89, 89, 48, 89, 31, - 89, 10, 64, 89, 89, 89, 42, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 28, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 85, 89, 25, 89, - 66, 89, 89, 89, 89, 36, 89, 89, 89, 89, - 89, 89, 89, 30, 65, 22, 89, 57, 89, 75, - 89, 89, 89, 43, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 56, 89, 89, 89, 89, 89, - 89, 89, 39, 32, 79, 18, 89, 83, 74, 89, + 90, 90, 90, 90, 90, 47, 90, 90, 30, 90, + 88, 90, 90, 39, 90, 90, 90, 90, 90, 49, + 90, 32, 90, 11, 65, 90, 90, 90, 43, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 29, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 86, 90, + 26, 90, 67, 90, 90, 90, 90, 37, 90, 90, + 90, 90, 90, 90, 90, 31, 66, 23, 90, 58, + 90, 76, 90, 90, 90, 44, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 57, 90, 90, 90, + 90, 90, 90, 90, 40, 33, 80, 19, 90, 84, - 55, 89, 63, 89, 52, 89, 89, 89, 47, 89, - 76, 89, 78, 89, 89, 33, 89, 89, 89, 34, - 72, 89, 89, 89, 89, 58, 89, 50, 49, 89, - 89, 89, 53, 62, 89, 89, 89, 21, 89, 89, - 73, 81, 89, 89, 77, 89, 68, 89, 89, 89, - 89, 89, 37, 89, 88, 67, 89, 84, 89, 89, - 89, 86, 89, 59, 89, 89, 15, 89, 70, 69, - 89, 41, 89, 82, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 71, 89, 89, 89, 89, 89, - 89, 60, 0 + 75, 90, 56, 90, 64, 90, 53, 90, 90, 90, + 48, 90, 77, 90, 79, 90, 90, 34, 90, 90, + 90, 35, 73, 90, 90, 90, 90, 59, 90, 51, + 50, 90, 90, 90, 54, 63, 90, 90, 90, 22, + 90, 90, 74, 82, 90, 90, 78, 90, 69, 90, + 90, 90, 90, 90, 38, 90, 89, 68, 90, 85, + 90, 90, 90, 87, 90, 60, 90, 90, 16, 90, + 71, 70, 90, 42, 90, 83, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 72, 90, 90, 90, + 90, 90, 90, 61, 0 } ; @@ -418,17 +418,17 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 4, 1, 1, 5, 1, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 17, 18, - 19, 20, 21, 1, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 31, - 1, 1, 1, 1, 47, 1, 31, 31, 31, 31, + 1, 2, 1, 4, 1, 5, 6, 1, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 17, 18, 19, + 20, 21, 22, 1, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 32, + 1, 1, 1, 1, 48, 1, 32, 32, 32, 32, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 48, 1, 49, 1, 1, 1, 1, 1, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 49, 1, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -445,228 +445,228 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[50] = +static yyconst flex_int32_t yy_meta[51] = { 0, - 1, 1, 1, 2, 1, 3, 1, 1, 4, 1, - 1, 1, 1, 1, 5, 1, 1, 1, 6, 1, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 2, 1, 1, 3, 1, 1, 4, + 1, 1, 1, 1, 1, 5, 1, 1, 1, 6, + 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 1, 1 + 5, 5, 5, 5, 5, 5, 5, 5, 1, 1 } ; -static yyconst flex_int16_t yy_base[403] = +static yyconst flex_int16_t yy_base[406] = { 0, - 0, 0, 434, 433, 435, 434, 435, 434, 437, 444, - 48, 50, 444, 444, 444, 444, 444, 444, 444, 444, - 444, 423, 426, 41, 415, 444, 38, 444, 414, 444, - 20, 33, 32, 46, 40, 44, 0, 54, 52, 48, - 60, 393, 65, 66, 74, 27, 409, 69, 444, 444, - 0, 97, 0, 424, 0, 425, 111, 444, 444, 413, - 54, 408, 444, 444, 444, 444, 0, 401, 69, 397, - 389, 387, 0, 400, 79, 82, 395, 381, 94, 379, - 392, 377, 391, 385, 373, 377, 373, 375, 375, 0, - 82, 0, 374, 372, 366, 373, 0, 0, 379, 379, + 0, 0, 435, 434, 436, 435, 437, 436, 439, 446, + 49, 51, 446, 0, 446, 446, 446, 446, 446, 446, + 446, 446, 424, 427, 41, 416, 446, 38, 446, 415, + 446, 20, 33, 32, 46, 40, 44, 0, 54, 52, + 48, 60, 394, 65, 66, 74, 27, 410, 69, 446, + 446, 0, 97, 0, 425, 0, 427, 112, 0, 446, + 446, 414, 54, 409, 446, 446, 446, 446, 0, 402, + 69, 398, 390, 388, 0, 401, 79, 82, 396, 382, + 94, 380, 393, 378, 392, 386, 374, 378, 374, 376, + 376, 0, 82, 0, 375, 373, 367, 374, 0, 0, - 362, 89, 98, 377, 93, 95, 368, 106, 360, 376, - 372, 350, 101, 371, 362, 112, 355, 0, 134, 135, - 444, 0, 387, 0, 388, 376, 0, 0, 364, 359, - 366, 364, 347, 345, 344, 349, 106, 347, 359, 93, - 347, 353, 354, 336, 336, 121, 0, 334, 350, 351, - 0, 338, 347, 344, 119, 126, 341, 331, 340, 333, - 330, 338, 0, 328, 338, 336, 327, 317, 311, 324, - 309, 329, 0, 0, 314, 0, 328, 319, 316, 130, - 312, 319, 326, 305, 307, 312, 312, 304, 307, 302, - 0, 0, 314, 298, 308, 315, 306, 294, 293, 307, + 380, 380, 363, 89, 98, 378, 93, 95, 369, 106, + 361, 377, 373, 351, 101, 372, 363, 112, 356, 0, + 134, 135, 446, 0, 388, 0, 390, 377, 0, 0, + 365, 360, 367, 365, 348, 346, 345, 350, 106, 348, + 360, 93, 348, 354, 355, 337, 337, 121, 0, 335, + 351, 352, 0, 339, 348, 345, 119, 126, 342, 332, + 341, 334, 331, 339, 0, 329, 339, 337, 328, 318, + 312, 325, 310, 330, 0, 0, 315, 0, 329, 320, + 317, 130, 313, 320, 327, 306, 308, 313, 313, 305, + 308, 303, 0, 0, 315, 299, 309, 316, 307, 295, - 296, 309, 289, 0, 299, 281, 0, 300, 0, 297, - 284, 0, 283, 278, 283, 282, 292, 0, 278, 0, - 282, 0, 0, 278, 275, 289, 0, 274, 274, 272, - 288, 273, 285, 267, 285, 280, 0, 275, 275, 261, - 260, 273, 259, 273, 272, 271, 0, 255, 0, 249, - 0, 268, 252, 251, 251, 0, 264, 254, 249, 248, - 260, 250, 249, 0, 0, 0, 253, 0, 241, 0, - 255, 251, 237, 0, 251, 252, 235, 240, 233, 251, - 233, 230, 231, 228, 0, 233, 245, 232, 239, 229, - 237, 222, 0, 0, 0, 214, 221, 0, 0, 218, + 294, 308, 297, 310, 290, 0, 300, 282, 0, 301, + 0, 298, 285, 0, 284, 279, 284, 283, 293, 0, + 279, 0, 283, 0, 0, 279, 276, 290, 0, 275, + 275, 273, 289, 274, 286, 268, 286, 281, 0, 276, + 276, 262, 261, 274, 260, 274, 273, 272, 0, 256, + 0, 250, 0, 269, 253, 252, 252, 0, 265, 255, + 250, 249, 261, 251, 250, 0, 0, 0, 254, 0, + 242, 0, 256, 252, 238, 0, 252, 253, 236, 241, + 234, 252, 234, 231, 232, 229, 0, 234, 246, 233, + 240, 230, 238, 223, 0, 0, 0, 215, 222, 0, - 0, 217, 0, 231, 0, 232, 219, 218, 0, 214, - 0, 217, 0, 209, 211, 0, 210, 224, 217, 0, - 0, 220, 223, 205, 220, 0, 216, 0, 0, 200, - 214, 213, 0, 0, 197, 196, 201, 0, 210, 195, - 0, 0, 201, 197, 0, 192, 0, 204, 204, 192, - 202, 191, 0, 178, 0, 0, 198, 0, 182, 176, - 182, 0, 173, 0, 178, 191, 0, 190, 0, 0, - 181, 0, 185, 0, 172, 172, 178, 164, 187, 175, - 174, 154, 125, 116, 0, 127, 133, 124, 121, 117, - 109, 0, 444, 165, 171, 177, 179, 145, 185, 191, + 0, 219, 0, 218, 0, 232, 0, 233, 220, 219, + 0, 215, 0, 218, 0, 210, 212, 0, 211, 225, + 218, 0, 0, 221, 224, 206, 221, 0, 217, 0, + 0, 201, 215, 214, 0, 0, 198, 197, 202, 0, + 211, 196, 0, 0, 202, 198, 0, 193, 0, 205, + 205, 193, 203, 192, 0, 179, 0, 0, 199, 0, + 183, 177, 183, 0, 174, 0, 179, 192, 0, 191, + 0, 0, 182, 0, 186, 0, 173, 173, 179, 165, + 188, 180, 179, 165, 150, 117, 0, 129, 135, 125, + 122, 118, 110, 0, 446, 166, 172, 178, 151, 180, - 197, 203 + 146, 186, 192, 198, 204 } ; -static yyconst flex_int16_t yy_def[403] = +static yyconst flex_int16_t yy_def[406] = { 0, - 393, 1, 394, 394, 395, 395, 396, 396, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 397, 393, 393, 393, 393, 393, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 393, 393, - 399, 400, 401, 393, 402, 393, 393, 393, 393, 393, - 393, 397, 393, 393, 393, 393, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 395, 1, 396, 396, 397, 397, 398, 398, 395, 395, + 395, 395, 395, 399, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 400, 395, 395, 395, 395, + 395, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 395, + 395, 402, 403, 404, 395, 405, 395, 395, 399, 395, + 395, 395, 395, 400, 395, 395, 395, 395, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 399, 400, 400, - 393, 401, 393, 402, 393, 393, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 402, + 403, 403, 395, 404, 395, 405, 395, 395, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 0, 393, 393, 393, 393, 393, 393, 393, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 0, 395, 395, 395, 395, 395, - 393, 393 + 395, 395, 395, 395, 395 } ; -static yyconst flex_int16_t yy_nxt[494] = +static yyconst flex_int16_t yy_nxt[497] = { 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, - 37, 37, 39, 37, 40, 41, 42, 37, 43, 44, - 45, 46, 47, 48, 37, 37, 37, 49, 50, 57, - 57, 57, 57, 60, 68, 61, 64, 65, 70, 69, - 74, 113, 71, 114, 75, 72, 60, 76, 61, 85, - 77, 79, 82, 78, 83, 80, 86, 93, 73, 87, - 90, 81, 88, 95, 84, 89, 97, 94, 91, 96, - 103, 106, 128, 92, 98, 110, 99, 116, 100, 104, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 38, + 39, 38, 38, 40, 38, 41, 42, 43, 38, 44, + 45, 46, 47, 48, 49, 38, 38, 38, 50, 51, + 58, 58, 58, 58, 62, 70, 63, 66, 67, 72, + 71, 76, 115, 73, 116, 77, 74, 62, 78, 63, + 87, 79, 81, 84, 80, 85, 82, 88, 95, 75, + 89, 92, 83, 90, 97, 86, 91, 99, 96, 93, + 98, 105, 108, 130, 94, 100, 112, 101, 118, 102, - 105, 101, 111, 107, 117, 120, 154, 108, 129, 112, - 121, 109, 57, 57, 134, 136, 137, 141, 164, 166, - 135, 155, 156, 138, 165, 170, 142, 172, 175, 196, - 181, 200, 201, 143, 167, 173, 171, 185, 168, 176, - 182, 186, 393, 120, 215, 197, 207, 393, 121, 67, - 208, 217, 238, 239, 392, 391, 390, 389, 388, 216, - 387, 218, 386, 385, 240, 51, 51, 51, 51, 51, - 51, 53, 53, 53, 53, 53, 53, 55, 55, 55, - 55, 55, 55, 62, 62, 118, 118, 118, 384, 118, - 118, 119, 119, 119, 119, 119, 119, 122, 122, 383, + 106, 107, 103, 113, 109, 119, 122, 156, 110, 131, + 114, 123, 111, 58, 58, 136, 138, 139, 143, 166, + 168, 137, 157, 158, 140, 167, 172, 144, 174, 177, + 198, 183, 202, 203, 145, 169, 175, 173, 187, 170, + 178, 184, 188, 395, 122, 217, 199, 209, 395, 123, + 69, 210, 219, 240, 241, 59, 394, 393, 392, 391, + 218, 390, 220, 389, 388, 242, 52, 52, 52, 52, + 52, 52, 54, 54, 54, 54, 54, 54, 56, 56, + 56, 56, 56, 56, 64, 64, 120, 120, 120, 387, + 120, 120, 121, 121, 121, 121, 121, 121, 124, 124, - 122, 122, 122, 124, 382, 124, 124, 124, 124, 381, - 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, - 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, - 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, - 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, - 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, - 330, 329, 328, 327, 326, 325, 324, 323, 322, 321, - 320, 319, 318, 317, 316, 315, 314, 313, 312, 311, - 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, - 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, + 386, 124, 124, 124, 126, 385, 126, 126, 126, 126, + 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, + 374, 373, 372, 371, 370, 369, 368, 367, 366, 365, + 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, + 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, + 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, + 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, + 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, + 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, + 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, - 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, - 280, 279, 278, 277, 276, 275, 274, 273, 272, 271, - 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, - 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, - 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, - 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, - 227, 226, 225, 224, 223, 222, 221, 220, 219, 214, - 213, 212, 211, 210, 209, 206, 205, 204, 203, 202, - 199, 198, 195, 194, 193, 192, 191, 190, 189, 188, - 126, 125, 123, 187, 184, 183, 180, 179, 178, 177, + 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, + 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, + 274, 273, 272, 271, 270, 269, 268, 267, 266, 265, + 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, + 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, + 244, 243, 239, 238, 237, 236, 235, 234, 233, 232, + 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, + 221, 216, 215, 214, 213, 212, 211, 208, 207, 206, + 205, 204, 201, 200, 197, 196, 195, 194, 193, 192, + 191, 190, 128, 127, 125, 189, 186, 185, 182, 181, - 174, 169, 163, 162, 161, 160, 159, 158, 157, 153, - 152, 151, 150, 149, 148, 147, 146, 145, 144, 140, - 139, 133, 132, 131, 130, 127, 393, 126, 125, 123, - 115, 102, 66, 63, 59, 58, 393, 56, 56, 54, - 54, 52, 52, 9, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393 + 180, 179, 176, 171, 165, 164, 163, 162, 161, 160, + 159, 155, 154, 153, 152, 151, 150, 149, 148, 147, + 146, 142, 141, 135, 134, 133, 132, 129, 395, 128, + 127, 125, 117, 104, 68, 65, 61, 60, 395, 57, + 57, 55, 55, 53, 53, 9, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395 } ; -static yyconst flex_int16_t yy_chk[494] = +static yyconst flex_int16_t yy_chk[497] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, - 11, 12, 12, 24, 31, 24, 27, 27, 32, 31, - 33, 46, 32, 46, 33, 32, 61, 33, 61, 36, - 33, 34, 35, 33, 35, 34, 36, 39, 32, 36, - 38, 34, 36, 40, 35, 36, 41, 39, 38, 40, - 43, 44, 69, 38, 41, 45, 41, 48, 41, 43, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 11, 12, 12, 25, 32, 25, 28, 28, 33, + 32, 34, 47, 33, 47, 34, 33, 63, 34, 63, + 37, 34, 35, 36, 34, 36, 35, 37, 40, 33, + 37, 39, 35, 37, 41, 36, 37, 42, 40, 39, + 41, 44, 45, 71, 39, 42, 46, 42, 49, 42, - 43, 41, 45, 44, 48, 52, 91, 44, 69, 45, - 52, 44, 57, 57, 75, 76, 76, 79, 102, 103, - 75, 91, 91, 76, 102, 105, 79, 106, 108, 137, - 113, 140, 140, 79, 103, 106, 105, 116, 103, 108, - 113, 116, 119, 120, 155, 137, 146, 119, 120, 398, - 146, 156, 180, 180, 391, 390, 389, 388, 387, 155, - 386, 156, 384, 383, 180, 394, 394, 394, 394, 394, - 394, 395, 395, 395, 395, 395, 395, 396, 396, 396, - 396, 396, 396, 397, 397, 399, 399, 399, 382, 399, - 399, 400, 400, 400, 400, 400, 400, 401, 401, 381, + 44, 44, 42, 46, 45, 49, 53, 93, 45, 71, + 46, 53, 45, 58, 58, 77, 78, 78, 81, 104, + 105, 77, 93, 93, 78, 104, 107, 81, 108, 110, + 139, 115, 142, 142, 81, 105, 108, 107, 118, 105, + 110, 115, 118, 121, 122, 157, 139, 148, 121, 122, + 401, 148, 158, 182, 182, 399, 393, 392, 391, 390, + 157, 389, 158, 388, 386, 182, 396, 396, 396, 396, + 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, + 398, 398, 398, 398, 400, 400, 402, 402, 402, 385, + 402, 402, 403, 403, 403, 403, 403, 403, 404, 404, - 401, 401, 401, 402, 380, 402, 402, 402, 402, 379, - 378, 377, 376, 375, 373, 371, 368, 366, 365, 363, - 361, 360, 359, 357, 354, 352, 351, 350, 349, 348, - 346, 344, 343, 340, 339, 337, 336, 335, 332, 331, - 330, 327, 325, 324, 323, 322, 319, 318, 317, 315, - 314, 312, 310, 308, 307, 306, 304, 302, 300, 297, - 296, 292, 291, 290, 289, 288, 287, 286, 284, 283, - 282, 281, 280, 279, 278, 277, 276, 275, 273, 272, - 271, 269, 267, 263, 262, 261, 260, 259, 258, 257, - 255, 254, 253, 252, 250, 248, 246, 245, 244, 243, + 384, 404, 404, 404, 405, 383, 405, 405, 405, 405, + 382, 381, 380, 379, 378, 377, 375, 373, 370, 368, + 367, 365, 363, 362, 361, 359, 356, 354, 353, 352, + 351, 350, 348, 346, 345, 342, 341, 339, 338, 337, + 334, 333, 332, 329, 327, 326, 325, 324, 321, 320, + 319, 317, 316, 314, 312, 310, 309, 308, 306, 304, + 302, 299, 298, 294, 293, 292, 291, 290, 289, 288, + 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, + 275, 274, 273, 271, 269, 265, 264, 263, 262, 261, + 260, 259, 257, 256, 255, 254, 252, 250, 248, 247, - 242, 241, 240, 239, 238, 236, 235, 234, 233, 232, - 231, 230, 229, 228, 226, 225, 224, 221, 219, 217, - 216, 215, 214, 213, 211, 210, 208, 206, 205, 203, - 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, - 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, - 179, 178, 177, 175, 172, 171, 170, 169, 168, 167, - 166, 165, 164, 162, 161, 160, 159, 158, 157, 154, - 153, 152, 150, 149, 148, 145, 144, 143, 142, 141, - 139, 138, 136, 135, 134, 133, 132, 131, 130, 129, - 126, 125, 123, 117, 115, 114, 112, 111, 110, 109, + 246, 245, 244, 243, 242, 241, 240, 238, 237, 236, + 235, 234, 233, 232, 231, 230, 228, 227, 226, 223, + 221, 219, 218, 217, 216, 215, 213, 212, 210, 208, + 207, 205, 204, 203, 202, 201, 200, 199, 198, 197, + 196, 195, 192, 191, 190, 189, 188, 187, 186, 185, + 184, 183, 181, 180, 179, 177, 174, 173, 172, 171, + 170, 169, 168, 167, 166, 164, 163, 162, 161, 160, + 159, 156, 155, 154, 152, 151, 150, 147, 146, 145, + 144, 143, 141, 140, 138, 137, 136, 135, 134, 133, + 132, 131, 128, 127, 125, 119, 117, 116, 114, 113, - 107, 104, 101, 100, 99, 96, 95, 94, 93, 89, - 88, 87, 86, 85, 84, 83, 82, 81, 80, 78, - 77, 74, 72, 71, 70, 68, 62, 60, 56, 54, - 47, 42, 29, 25, 23, 22, 9, 8, 7, 6, - 5, 4, 3, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393 + 112, 111, 109, 106, 103, 102, 101, 98, 97, 96, + 95, 91, 90, 89, 88, 87, 86, 85, 84, 83, + 82, 80, 79, 76, 74, 73, 72, 70, 64, 62, + 57, 55, 48, 43, 30, 26, 24, 23, 9, 8, + 7, 6, 5, 4, 3, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395 } ; @@ -908,7 +908,7 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 91 "pars0lex.l" +#line 92 "pars0lex.l" #line 914 "_flex_tmp.c" @@ -964,13 +964,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 394 ) + if ( yy_current_state >= 396 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 393 ); + while ( yy_current_state != 395 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -992,7 +992,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 93 "pars0lex.l" +#line 94 "pars0lex.l" { yylval = sym_tab_add_int_lit(pars_sym_tab_global, atoi(yytext)); @@ -1001,7 +1001,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 99 "pars0lex.l" +#line 100 "pars0lex.l" { ut_error; /* not implemented */ @@ -1010,7 +1010,7 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 105 "pars0lex.l" +#line 106 "pars0lex.l" { ulint type; @@ -1022,7 +1022,17 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 114 "pars0lex.l" +#line 115 "pars0lex.l" +{ + yylval = sym_tab_add_bound_id(pars_sym_tab_global, + yytext + 1); + + return(PARS_ID_TOKEN); +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 122 "pars0lex.l" { /* Quoted character string literals are handled in an explicit start state 'quoted'. This state is entered and the buffer for @@ -1033,19 +1043,19 @@ In the state 'quoted', only two actions are possible (defined below). */ stringbuf_len = 0; } YY_BREAK -case 5: -/* rule 5 can match eol */ +case 6: +/* rule 6 can match eol */ YY_RULE_SETUP -#line 123 "pars0lex.l" +#line 131 "pars0lex.l" { /* Got a sequence of characters other than "'": append to string buffer */ string_append(yytext, yyleng); } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 128 "pars0lex.l" +#line 136 "pars0lex.l" { /* Got a sequence of "'" characters: append half of them to string buffer, @@ -1070,9 +1080,9 @@ YY_RULE_SETUP } } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 152 "pars0lex.l" +#line 160 "pars0lex.l" { /* Quoted identifiers are handled in an explicit start state 'id'. This state is entered and the buffer for the scanned string is emptied @@ -1083,19 +1093,19 @@ In the state 'id', only two actions are possible (defined below). */ stringbuf_len = 0; } YY_BREAK -case 8: -/* rule 8 can match eol */ +case 9: +/* rule 9 can match eol */ YY_RULE_SETUP -#line 161 "pars0lex.l" +#line 169 "pars0lex.l" { /* Got a sequence of characters other than '"': append to string buffer */ string_append(yytext, yyleng); } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 166 "pars0lex.l" +#line 174 "pars0lex.l" { /* Got a sequence of '"' characters: append half of them to string buffer, @@ -1121,18 +1131,18 @@ YY_RULE_SETUP } } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 191 "pars0lex.l" +#line 199 "pars0lex.l" { yylval = sym_tab_add_null_lit(pars_sym_tab_global); return(PARS_NULL_LIT); } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 197 "pars0lex.l" +#line 205 "pars0lex.l" { /* Implicit cursor name */ yylval = sym_tab_add_str_lit(pars_sym_tab_global, @@ -1140,548 +1150,548 @@ YY_RULE_SETUP return(PARS_SQL_TOKEN); } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 204 "pars0lex.l" +#line 212 "pars0lex.l" { return(PARS_AND_TOKEN); } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 208 "pars0lex.l" +#line 216 "pars0lex.l" { return(PARS_OR_TOKEN); } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 212 "pars0lex.l" +#line 220 "pars0lex.l" { return(PARS_NOT_TOKEN); } YY_BREAK -case 15: +case 16: YY_RULE_SETUP -#line 216 "pars0lex.l" +#line 224 "pars0lex.l" { return(PARS_PROCEDURE_TOKEN); } YY_BREAK -case 16: +case 17: YY_RULE_SETUP -#line 220 "pars0lex.l" +#line 228 "pars0lex.l" { return(PARS_IN_TOKEN); } YY_BREAK -case 17: +case 18: YY_RULE_SETUP -#line 224 "pars0lex.l" +#line 232 "pars0lex.l" { return(PARS_OUT_TOKEN); } YY_BREAK -case 18: +case 19: YY_RULE_SETUP -#line 228 "pars0lex.l" +#line 236 "pars0lex.l" { return(PARS_BINARY_TOKEN); } YY_BREAK -case 19: +case 20: YY_RULE_SETUP -#line 232 "pars0lex.l" +#line 240 "pars0lex.l" { return(PARS_BLOB_TOKEN); } YY_BREAK -case 20: -YY_RULE_SETUP -#line 236 "pars0lex.l" -{ - return(PARS_INT_TOKEN); -} - YY_BREAK case 21: YY_RULE_SETUP -#line 240 "pars0lex.l" +#line 244 "pars0lex.l" { return(PARS_INT_TOKEN); } YY_BREAK case 22: YY_RULE_SETUP -#line 244 "pars0lex.l" +#line 248 "pars0lex.l" { - return(PARS_FLOAT_TOKEN); + return(PARS_INT_TOKEN); } YY_BREAK case 23: YY_RULE_SETUP -#line 248 "pars0lex.l" +#line 252 "pars0lex.l" { - return(PARS_CHAR_TOKEN); + return(PARS_FLOAT_TOKEN); } YY_BREAK case 24: YY_RULE_SETUP -#line 252 "pars0lex.l" +#line 256 "pars0lex.l" { - return(PARS_IS_TOKEN); + return(PARS_CHAR_TOKEN); } YY_BREAK case 25: YY_RULE_SETUP -#line 256 "pars0lex.l" +#line 260 "pars0lex.l" { - return(PARS_BEGIN_TOKEN); + return(PARS_IS_TOKEN); } YY_BREAK case 26: YY_RULE_SETUP -#line 260 "pars0lex.l" +#line 264 "pars0lex.l" { - return(PARS_END_TOKEN); + return(PARS_BEGIN_TOKEN); } YY_BREAK case 27: YY_RULE_SETUP -#line 264 "pars0lex.l" +#line 268 "pars0lex.l" { - return(PARS_IF_TOKEN); + return(PARS_END_TOKEN); } YY_BREAK case 28: YY_RULE_SETUP -#line 268 "pars0lex.l" +#line 272 "pars0lex.l" { - return(PARS_THEN_TOKEN); + return(PARS_IF_TOKEN); } YY_BREAK case 29: YY_RULE_SETUP -#line 272 "pars0lex.l" +#line 276 "pars0lex.l" { - return(PARS_ELSE_TOKEN); + return(PARS_THEN_TOKEN); } YY_BREAK case 30: YY_RULE_SETUP -#line 276 "pars0lex.l" +#line 280 "pars0lex.l" { - return(PARS_ELSIF_TOKEN); + return(PARS_ELSE_TOKEN); } YY_BREAK case 31: YY_RULE_SETUP -#line 280 "pars0lex.l" +#line 284 "pars0lex.l" { - return(PARS_LOOP_TOKEN); + return(PARS_ELSIF_TOKEN); } YY_BREAK case 32: YY_RULE_SETUP -#line 284 "pars0lex.l" +#line 288 "pars0lex.l" { - return(PARS_WHILE_TOKEN); + return(PARS_LOOP_TOKEN); } YY_BREAK case 33: YY_RULE_SETUP -#line 288 "pars0lex.l" +#line 292 "pars0lex.l" { - return(PARS_RETURN_TOKEN); + return(PARS_WHILE_TOKEN); } YY_BREAK case 34: YY_RULE_SETUP -#line 292 "pars0lex.l" +#line 296 "pars0lex.l" { - return(PARS_SELECT_TOKEN); + return(PARS_RETURN_TOKEN); } YY_BREAK case 35: YY_RULE_SETUP -#line 296 "pars0lex.l" +#line 300 "pars0lex.l" { - return(PARS_SUM_TOKEN); + return(PARS_SELECT_TOKEN); } YY_BREAK case 36: YY_RULE_SETUP -#line 300 "pars0lex.l" +#line 304 "pars0lex.l" { - return(PARS_COUNT_TOKEN); + return(PARS_SUM_TOKEN); } YY_BREAK case 37: YY_RULE_SETUP -#line 304 "pars0lex.l" +#line 308 "pars0lex.l" { - return(PARS_DISTINCT_TOKEN); + return(PARS_COUNT_TOKEN); } YY_BREAK case 38: YY_RULE_SETUP -#line 308 "pars0lex.l" +#line 312 "pars0lex.l" { - return(PARS_FROM_TOKEN); + return(PARS_DISTINCT_TOKEN); } YY_BREAK case 39: YY_RULE_SETUP -#line 312 "pars0lex.l" +#line 316 "pars0lex.l" { - return(PARS_WHERE_TOKEN); + return(PARS_FROM_TOKEN); } YY_BREAK case 40: YY_RULE_SETUP -#line 316 "pars0lex.l" +#line 320 "pars0lex.l" { - return(PARS_FOR_TOKEN); + return(PARS_WHERE_TOKEN); } YY_BREAK case 41: YY_RULE_SETUP -#line 320 "pars0lex.l" +#line 324 "pars0lex.l" { - return(PARS_CONSISTENT_TOKEN); + return(PARS_FOR_TOKEN); } YY_BREAK case 42: YY_RULE_SETUP -#line 324 "pars0lex.l" +#line 328 "pars0lex.l" { - return(PARS_READ_TOKEN); + return(PARS_CONSISTENT_TOKEN); } YY_BREAK case 43: YY_RULE_SETUP -#line 328 "pars0lex.l" +#line 332 "pars0lex.l" { - return(PARS_ORDER_TOKEN); + return(PARS_READ_TOKEN); } YY_BREAK case 44: YY_RULE_SETUP -#line 332 "pars0lex.l" +#line 336 "pars0lex.l" { - return(PARS_BY_TOKEN); + return(PARS_ORDER_TOKEN); } YY_BREAK case 45: YY_RULE_SETUP -#line 336 "pars0lex.l" +#line 340 "pars0lex.l" { - return(PARS_ASC_TOKEN); + return(PARS_BY_TOKEN); } YY_BREAK case 46: YY_RULE_SETUP -#line 340 "pars0lex.l" +#line 344 "pars0lex.l" { - return(PARS_DESC_TOKEN); + return(PARS_ASC_TOKEN); } YY_BREAK case 47: YY_RULE_SETUP -#line 344 "pars0lex.l" +#line 348 "pars0lex.l" { - return(PARS_INSERT_TOKEN); + return(PARS_DESC_TOKEN); } YY_BREAK case 48: YY_RULE_SETUP -#line 348 "pars0lex.l" +#line 352 "pars0lex.l" { - return(PARS_INTO_TOKEN); + return(PARS_INSERT_TOKEN); } YY_BREAK case 49: YY_RULE_SETUP -#line 352 "pars0lex.l" +#line 356 "pars0lex.l" { - return(PARS_VALUES_TOKEN); + return(PARS_INTO_TOKEN); } YY_BREAK case 50: YY_RULE_SETUP -#line 356 "pars0lex.l" +#line 360 "pars0lex.l" { - return(PARS_UPDATE_TOKEN); + return(PARS_VALUES_TOKEN); } YY_BREAK case 51: YY_RULE_SETUP -#line 360 "pars0lex.l" +#line 364 "pars0lex.l" { - return(PARS_SET_TOKEN); + return(PARS_UPDATE_TOKEN); } YY_BREAK case 52: YY_RULE_SETUP -#line 364 "pars0lex.l" +#line 368 "pars0lex.l" { - return(PARS_DELETE_TOKEN); + return(PARS_SET_TOKEN); } YY_BREAK case 53: YY_RULE_SETUP -#line 368 "pars0lex.l" +#line 372 "pars0lex.l" { - return(PARS_CURRENT_TOKEN); + return(PARS_DELETE_TOKEN); } YY_BREAK case 54: YY_RULE_SETUP -#line 372 "pars0lex.l" +#line 376 "pars0lex.l" { - return(PARS_OF_TOKEN); + return(PARS_CURRENT_TOKEN); } YY_BREAK case 55: YY_RULE_SETUP -#line 376 "pars0lex.l" +#line 380 "pars0lex.l" { - return(PARS_CREATE_TOKEN); + return(PARS_OF_TOKEN); } YY_BREAK case 56: YY_RULE_SETUP -#line 380 "pars0lex.l" +#line 384 "pars0lex.l" { - return(PARS_TABLE_TOKEN); + return(PARS_CREATE_TOKEN); } YY_BREAK case 57: YY_RULE_SETUP -#line 384 "pars0lex.l" +#line 388 "pars0lex.l" { - return(PARS_INDEX_TOKEN); + return(PARS_TABLE_TOKEN); } YY_BREAK case 58: YY_RULE_SETUP -#line 388 "pars0lex.l" +#line 392 "pars0lex.l" { - return(PARS_UNIQUE_TOKEN); + return(PARS_INDEX_TOKEN); } YY_BREAK case 59: YY_RULE_SETUP -#line 392 "pars0lex.l" +#line 396 "pars0lex.l" { - return(PARS_CLUSTERED_TOKEN); + return(PARS_UNIQUE_TOKEN); } YY_BREAK case 60: YY_RULE_SETUP -#line 396 "pars0lex.l" +#line 400 "pars0lex.l" { - return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); + return(PARS_CLUSTERED_TOKEN); } YY_BREAK case 61: YY_RULE_SETUP -#line 400 "pars0lex.l" +#line 404 "pars0lex.l" { - return(PARS_ON_TOKEN); + return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN); } YY_BREAK case 62: YY_RULE_SETUP -#line 404 "pars0lex.l" +#line 408 "pars0lex.l" { - return(PARS_DECLARE_TOKEN); + return(PARS_ON_TOKEN); } YY_BREAK case 63: YY_RULE_SETUP -#line 408 "pars0lex.l" +#line 412 "pars0lex.l" { - return(PARS_CURSOR_TOKEN); + return(PARS_DECLARE_TOKEN); } YY_BREAK case 64: YY_RULE_SETUP -#line 412 "pars0lex.l" +#line 416 "pars0lex.l" { - return(PARS_OPEN_TOKEN); + return(PARS_CURSOR_TOKEN); } YY_BREAK case 65: YY_RULE_SETUP -#line 416 "pars0lex.l" +#line 420 "pars0lex.l" { - return(PARS_FETCH_TOKEN); + return(PARS_OPEN_TOKEN); } YY_BREAK case 66: YY_RULE_SETUP -#line 420 "pars0lex.l" +#line 424 "pars0lex.l" { - return(PARS_CLOSE_TOKEN); + return(PARS_FETCH_TOKEN); } YY_BREAK case 67: YY_RULE_SETUP -#line 424 "pars0lex.l" +#line 428 "pars0lex.l" { - return(PARS_NOTFOUND_TOKEN); + return(PARS_CLOSE_TOKEN); } YY_BREAK case 68: YY_RULE_SETUP -#line 428 "pars0lex.l" +#line 432 "pars0lex.l" { - return(PARS_TO_CHAR_TOKEN); + return(PARS_NOTFOUND_TOKEN); } YY_BREAK case 69: YY_RULE_SETUP -#line 432 "pars0lex.l" +#line 436 "pars0lex.l" { - return(PARS_TO_NUMBER_TOKEN); + return(PARS_TO_CHAR_TOKEN); } YY_BREAK case 70: YY_RULE_SETUP -#line 436 "pars0lex.l" +#line 440 "pars0lex.l" { - return(PARS_TO_BINARY_TOKEN); + return(PARS_TO_NUMBER_TOKEN); } YY_BREAK case 71: YY_RULE_SETUP -#line 440 "pars0lex.l" +#line 444 "pars0lex.l" { - return(PARS_BINARY_TO_NUMBER_TOKEN); + return(PARS_TO_BINARY_TOKEN); } YY_BREAK case 72: YY_RULE_SETUP -#line 444 "pars0lex.l" +#line 448 "pars0lex.l" { - return(PARS_SUBSTR_TOKEN); + return(PARS_BINARY_TO_NUMBER_TOKEN); } YY_BREAK case 73: YY_RULE_SETUP -#line 448 "pars0lex.l" +#line 452 "pars0lex.l" { - return(PARS_REPLSTR_TOKEN); + return(PARS_SUBSTR_TOKEN); } YY_BREAK case 74: YY_RULE_SETUP -#line 452 "pars0lex.l" +#line 456 "pars0lex.l" { - return(PARS_CONCAT_TOKEN); + return(PARS_REPLSTR_TOKEN); } YY_BREAK case 75: YY_RULE_SETUP -#line 456 "pars0lex.l" +#line 460 "pars0lex.l" { - return(PARS_INSTR_TOKEN); + return(PARS_CONCAT_TOKEN); } YY_BREAK case 76: YY_RULE_SETUP -#line 460 "pars0lex.l" +#line 464 "pars0lex.l" { - return(PARS_LENGTH_TOKEN); + return(PARS_INSTR_TOKEN); } YY_BREAK case 77: YY_RULE_SETUP -#line 464 "pars0lex.l" +#line 468 "pars0lex.l" { - return(PARS_SYSDATE_TOKEN); + return(PARS_LENGTH_TOKEN); } YY_BREAK case 78: YY_RULE_SETUP -#line 468 "pars0lex.l" +#line 472 "pars0lex.l" { - return(PARS_PRINTF_TOKEN); + return(PARS_SYSDATE_TOKEN); } YY_BREAK case 79: YY_RULE_SETUP -#line 472 "pars0lex.l" +#line 476 "pars0lex.l" { - return(PARS_ASSERT_TOKEN); + return(PARS_PRINTF_TOKEN); } YY_BREAK case 80: YY_RULE_SETUP -#line 476 "pars0lex.l" +#line 480 "pars0lex.l" { - return(PARS_RND_TOKEN); + return(PARS_ASSERT_TOKEN); } YY_BREAK case 81: YY_RULE_SETUP -#line 480 "pars0lex.l" +#line 484 "pars0lex.l" { - return(PARS_RND_STR_TOKEN); + return(PARS_RND_TOKEN); } YY_BREAK case 82: YY_RULE_SETUP -#line 484 "pars0lex.l" +#line 488 "pars0lex.l" { - return(PARS_ROW_PRINTF_TOKEN); + return(PARS_RND_STR_TOKEN); } YY_BREAK case 83: YY_RULE_SETUP -#line 488 "pars0lex.l" +#line 492 "pars0lex.l" { - return(PARS_COMMIT_TOKEN); + return(PARS_ROW_PRINTF_TOKEN); } YY_BREAK case 84: YY_RULE_SETUP -#line 492 "pars0lex.l" +#line 496 "pars0lex.l" { - return(PARS_ROLLBACK_TOKEN); + return(PARS_COMMIT_TOKEN); } YY_BREAK case 85: YY_RULE_SETUP -#line 496 "pars0lex.l" +#line 500 "pars0lex.l" { - return(PARS_WORK_TOKEN); + return(PARS_ROLLBACK_TOKEN); } YY_BREAK case 86: YY_RULE_SETUP -#line 500 "pars0lex.l" +#line 504 "pars0lex.l" { - return(PARS_UNSIGNED_TOKEN); + return(PARS_WORK_TOKEN); } YY_BREAK case 87: YY_RULE_SETUP -#line 504 "pars0lex.l" +#line 508 "pars0lex.l" { - return(PARS_EXIT_TOKEN); + return(PARS_UNSIGNED_TOKEN); } YY_BREAK case 88: YY_RULE_SETUP -#line 508 "pars0lex.l" +#line 512 "pars0lex.l" { - return(PARS_FUNCTION_TOKEN); + return(PARS_EXIT_TOKEN); } YY_BREAK case 89: YY_RULE_SETUP -#line 512 "pars0lex.l" +#line 516 "pars0lex.l" +{ + return(PARS_FUNCTION_TOKEN); +} + YY_BREAK +case 90: +YY_RULE_SETUP +#line 520 "pars0lex.l" { yylval = sym_tab_add_id(pars_sym_tab_global, (byte*)yytext, @@ -1689,52 +1699,44 @@ YY_RULE_SETUP return(PARS_ID_TOKEN); } YY_BREAK -case 90: +case 91: YY_RULE_SETUP -#line 519 "pars0lex.l" +#line 527 "pars0lex.l" { return(PARS_DDOT_TOKEN); } YY_BREAK -case 91: +case 92: YY_RULE_SETUP -#line 523 "pars0lex.l" +#line 531 "pars0lex.l" { return(PARS_ASSIGN_TOKEN); } YY_BREAK -case 92: +case 93: YY_RULE_SETUP -#line 527 "pars0lex.l" +#line 535 "pars0lex.l" { return(PARS_LE_TOKEN); } YY_BREAK -case 93: +case 94: YY_RULE_SETUP -#line 531 "pars0lex.l" +#line 539 "pars0lex.l" { return(PARS_GE_TOKEN); } YY_BREAK -case 94: +case 95: YY_RULE_SETUP -#line 535 "pars0lex.l" +#line 543 "pars0lex.l" { return(PARS_NE_TOKEN); } YY_BREAK -case 95: -YY_RULE_SETUP -#line 539 "pars0lex.l" -{ - - return((int)(*yytext)); -} - YY_BREAK case 96: YY_RULE_SETUP -#line 544 "pars0lex.l" +#line 547 "pars0lex.l" { return((int)(*yytext)); @@ -1742,7 +1744,7 @@ YY_RULE_SETUP YY_BREAK case 97: YY_RULE_SETUP -#line 549 "pars0lex.l" +#line 552 "pars0lex.l" { return((int)(*yytext)); @@ -1750,7 +1752,7 @@ YY_RULE_SETUP YY_BREAK case 98: YY_RULE_SETUP -#line 554 "pars0lex.l" +#line 557 "pars0lex.l" { return((int)(*yytext)); @@ -1758,7 +1760,7 @@ YY_RULE_SETUP YY_BREAK case 99: YY_RULE_SETUP -#line 559 "pars0lex.l" +#line 562 "pars0lex.l" { return((int)(*yytext)); @@ -1766,7 +1768,7 @@ YY_RULE_SETUP YY_BREAK case 100: YY_RULE_SETUP -#line 564 "pars0lex.l" +#line 567 "pars0lex.l" { return((int)(*yytext)); @@ -1774,7 +1776,7 @@ YY_RULE_SETUP YY_BREAK case 101: YY_RULE_SETUP -#line 569 "pars0lex.l" +#line 572 "pars0lex.l" { return((int)(*yytext)); @@ -1782,7 +1784,7 @@ YY_RULE_SETUP YY_BREAK case 102: YY_RULE_SETUP -#line 574 "pars0lex.l" +#line 577 "pars0lex.l" { return((int)(*yytext)); @@ -1790,7 +1792,7 @@ YY_RULE_SETUP YY_BREAK case 103: YY_RULE_SETUP -#line 579 "pars0lex.l" +#line 582 "pars0lex.l" { return((int)(*yytext)); @@ -1798,7 +1800,7 @@ YY_RULE_SETUP YY_BREAK case 104: YY_RULE_SETUP -#line 584 "pars0lex.l" +#line 587 "pars0lex.l" { return((int)(*yytext)); @@ -1806,7 +1808,7 @@ YY_RULE_SETUP YY_BREAK case 105: YY_RULE_SETUP -#line 589 "pars0lex.l" +#line 592 "pars0lex.l" { return((int)(*yytext)); @@ -1814,7 +1816,7 @@ YY_RULE_SETUP YY_BREAK case 106: YY_RULE_SETUP -#line 594 "pars0lex.l" +#line 597 "pars0lex.l" { return((int)(*yytext)); @@ -1822,7 +1824,7 @@ YY_RULE_SETUP YY_BREAK case 107: YY_RULE_SETUP -#line 599 "pars0lex.l" +#line 602 "pars0lex.l" { return((int)(*yytext)); @@ -1830,7 +1832,7 @@ YY_RULE_SETUP YY_BREAK case 108: YY_RULE_SETUP -#line 604 "pars0lex.l" +#line 607 "pars0lex.l" { return((int)(*yytext)); @@ -1838,7 +1840,7 @@ YY_RULE_SETUP YY_BREAK case 109: YY_RULE_SETUP -#line 609 "pars0lex.l" +#line 612 "pars0lex.l" { return((int)(*yytext)); @@ -1846,35 +1848,43 @@ YY_RULE_SETUP YY_BREAK case 110: YY_RULE_SETUP -#line 614 "pars0lex.l" -BEGIN(comment); /* eat up comment */ +#line 617 "pars0lex.l" +{ + + return((int)(*yytext)); +} YY_BREAK case 111: -/* rule 111 can match eol */ YY_RULE_SETUP -#line 616 "pars0lex.l" - +#line 622 "pars0lex.l" +BEGIN(comment); /* eat up comment */ YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP -#line 617 "pars0lex.l" +#line 624 "pars0lex.l" YY_BREAK case 113: +/* rule 113 can match eol */ YY_RULE_SETUP -#line 618 "pars0lex.l" -BEGIN(INITIAL); +#line 625 "pars0lex.l" + YY_BREAK case 114: -/* rule 114 can match eol */ YY_RULE_SETUP -#line 620 "pars0lex.l" -/* eat up whitespace */ +#line 626 "pars0lex.l" +BEGIN(INITIAL); YY_BREAK case 115: +/* rule 115 can match eol */ YY_RULE_SETUP -#line 623 "pars0lex.l" +#line 628 "pars0lex.l" +/* eat up whitespace */ + YY_BREAK +case 116: +YY_RULE_SETUP +#line 631 "pars0lex.l" { fprintf(stderr,"Unrecognized character: %02x\n", *yytext); @@ -1884,12 +1894,12 @@ YY_RULE_SETUP return(0); } YY_BREAK -case 116: +case 117: YY_RULE_SETUP -#line 632 "pars0lex.l" +#line 640 "pars0lex.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1892 "_flex_tmp.c" +#line 1902 "_flex_tmp.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(comment): case YY_STATE_EOF(quoted): @@ -2177,7 +2187,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 394 ) + if ( yy_current_state >= 396 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2205,11 +2215,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 394 ) + if ( yy_current_state >= 396 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 393); + yy_is_jam = (yy_current_state == 395); return yy_is_jam ? 0 : yy_current_state; } @@ -2732,7 +2742,7 @@ void yyfree (void * ptr ) #undef YY_DECL_IS_OURS #undef YY_DECL #endif -#line 632 "pars0lex.l" +#line 640 "pars0lex.l" diff --git a/pars/pars0lex.l b/pars/pars0lex.l index ab1fe446924..8f6a8d39a36 100644 --- a/pars/pars0lex.l +++ b/pars/pars0lex.l @@ -84,6 +84,7 @@ string_append( DIGIT [0-9] ID [a-z_A-Z][a-z_A-Z0-9]* BOUND_LIT \:[a-z_A-Z0-9]+ +BOUND_ID \$[a-z_A-Z0-9]+ %x comment %x quoted @@ -111,6 +112,13 @@ BOUND_LIT \:[a-z_A-Z0-9]+ return(type); } +{BOUND_ID} { + yylval = sym_tab_add_bound_id(pars_sym_tab_global, + yytext + 1); + + return(PARS_ID_TOKEN); +} + "'" { /* Quoted character string literals are handled in an explicit start state 'quoted'. This state is entered and the buffer for diff --git a/pars/pars0pars.c b/pars/pars0pars.c index 6b748c37229..96ba8a20076 100644 --- a/pars/pars0pars.c +++ b/pars/pars0pars.c @@ -1931,6 +1931,7 @@ pars_info_create(void) info->heap = heap; info->funcs = NULL; info->bound_lits = NULL; + info->bound_ids = NULL; info->graph_owns_us = TRUE; return(info); @@ -1963,6 +1964,8 @@ pars_info_add_literal( { pars_bound_lit_t* pbl; + ut_ad(!pars_info_get_bound_lit(info, name)); + pbl = mem_heap_alloc(info->heap, sizeof(*pbl)); pbl->name = name; @@ -2053,6 +2056,8 @@ pars_info_add_function( { pars_user_func_t* puf; + ut_ad(!pars_info_get_user_func(info, name)); + puf = mem_heap_alloc(info->heap, sizeof(*puf)); puf->name = name; @@ -2066,6 +2071,32 @@ pars_info_add_function( ib_vector_push(info->funcs, puf); } +/******************************************************************** +Add bound id. */ + +void +pars_info_add_id( +/*=============*/ + pars_info_t* info, /* in: info struct */ + const char* name, /* in: name */ + const char* id) /* in: id */ +{ + pars_bound_id_t* bid; + + ut_ad(!pars_info_get_bound_id(info, name)); + + bid = mem_heap_alloc(info->heap, sizeof(*bid)); + + bid->name = name; + bid->id = id; + + if (!info->bound_ids) { + info->bound_ids = ib_vector_create(info->heap, 8); + } + + ib_vector_push(info->bound_ids, bid); +} + /******************************************************************** Get user function with the given name.*/ @@ -2127,3 +2158,34 @@ pars_info_get_bound_lit( return(NULL); } + +/******************************************************************** +Get bound id with the given name.*/ + +pars_bound_id_t* +pars_info_get_bound_id( +/*===================*/ + /* out: bound id, or NULL if not + found */ + pars_info_t* info, /* in: info struct */ + const char* name) /* in: bound id name to find */ +{ + ulint i; + ib_vector_t* vec; + + if (!info || !info->bound_ids) { + return(NULL); + } + + vec = info->bound_ids; + + for (i = 0; i < ib_vector_size(vec); i++) { + pars_bound_id_t* bid = ib_vector_get(vec, i); + + if (strcmp(bid->name, name) == 0) { + return(bid); + } + } + + return(NULL); +} diff --git a/pars/pars0sym.c b/pars/pars0sym.c index 79a1e555b06..bbbcc0f8f97 100644 --- a/pars/pars0sym.c +++ b/pars/pars0sym.c @@ -304,3 +304,42 @@ sym_tab_add_id( return(node); } + +/********************************************************************** +Add a bound identifier to a symbol table. */ + +sym_node_t* +sym_tab_add_bound_id( +/*===========*/ + /* out: symbol table node */ + sym_tab_t* sym_tab, /* in: symbol table */ + const char* name) /* in: name of bound id */ +{ + sym_node_t* node; + pars_bound_id_t* bid; + + bid = pars_info_get_bound_id(sym_tab->info, name); + ut_a(bid); + + node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)); + + node->common.type = QUE_NODE_SYMBOL; + + node->resolved = FALSE; + node->indirection = NULL; + + node->name = mem_heap_strdup(sym_tab->heap, bid->id); + node->name_len = strlen(node->name); + + UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node); + + dfield_set_data(&(node->common.val), NULL, UNIV_SQL_NULL); + + node->common.val_buf_size = 0; + node->prefetch_buf = NULL; + node->cursor_def = NULL; + + node->sym_table = sym_tab; + + return(node); +} diff --git a/que/que0que.c b/que/que0que.c index 59d90eb7e29..c6d287276c7 100644 --- a/que/que0que.c +++ b/que/que0que.c @@ -1340,14 +1340,6 @@ loop: next_thr = que_thr_step(thr); /*-------------------------*/ - /* Test the effect on performance of adding extra mutex - reservations */ - -/* if (srv_test_extra_mutexes) { - mutex_enter(&kernel_mutex); - mutex_exit(&kernel_mutex); - } -*/ loop_count++; if (next_thr != thr) { diff --git a/row/row0ins.c b/row/row0ins.c index 9ce02654266..4c1331dae61 100644 --- a/row/row0ins.c +++ b/row/row0ins.c @@ -1519,8 +1519,7 @@ row_ins_check_foreign_constraints( if (foreign->foreign_index == index) { if (foreign->referenced_table == NULL) { - dict_table_get(foreign->referenced_table_name, - trx); + dict_table_get(foreign->referenced_table_name); } if (0 == trx->dict_operation_lock_mode) { diff --git a/row/row0mysql.c b/row/row0mysql.c index 8070961d627..4b083f729ff 100644 --- a/row/row0mysql.c +++ b/row/row0mysql.c @@ -2384,11 +2384,9 @@ row_discard_tablespace_for_mysql( dict_foreign_t* foreign; dulint new_id; dict_table_t* table; - que_thr_t* thr; - que_t* graph = NULL; ibool success; ulint err; - char* buf; + pars_info_t* info = NULL; /* How do we prevent crashes caused by ongoing operations on the table? Old operations could try to access non-existent pages. @@ -2410,36 +2408,6 @@ discard ongoing operations. 5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the discard. We also reserve the data dictionary latch. */ - static const char discard_tablespace_proc1[] = - "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" - "old_id CHAR;\n" - "new_id CHAR;\n" - "new_id_low INT;\n" - "new_id_high INT;\n" - "table_name CHAR;\n" - "BEGIN\n" - "table_name := '"; - static const char discard_tablespace_proc2[] = - "';\n" - "new_id_high := %lu;\n" - "new_id_low := %lu;\n" - "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" - "SELECT ID INTO old_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = table_name;\n" - "IF (SQL %% NOTFOUND) THEN\n" - " COMMIT WORK;\n" - " RETURN;\n" - "END IF;\n" - "UPDATE SYS_TABLES SET ID = new_id\n" - "WHERE ID = old_id;\n" - "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "COMMIT WORK;\n" - "END;\n"; - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = "discarding tablespace"; @@ -2519,35 +2487,34 @@ do not allow the discard. We also reserve the data dictionary latch. */ new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - buf = mem_alloc((sizeof discard_tablespace_proc1) + - (sizeof discard_tablespace_proc2) + - 20 + ut_strlenq(name, '\'')); - - memcpy(buf, discard_tablespace_proc1, sizeof discard_tablespace_proc1); - sprintf(ut_strcpyq(buf + (sizeof discard_tablespace_proc1 - 1), - '\'', name), - discard_tablespace_proc2, - (ulong) ut_dulint_get_high(new_id), - (ulong) ut_dulint_get_low(new_id)); - - graph = pars_sql(NULL, buf); - - ut_a(graph); - /* Remove any locks there are on the table or its records */ - lock_reset_all_on_table(table); - graph->trx = trx; - trx->graph = NULL; + info = pars_info_create(); - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + pars_info_add_str_literal(info, "table_name", name); + pars_info_add_dulint_literal(info, "new_id", new_id); - ut_a(thr = que_fork_start_command(graph)); - - que_run_threads(thr); - - err = trx->error_state; + err = que_eval_sql(info, + "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n" + "old_id CHAR;\n" + "BEGIN\n" + "SELECT ID INTO old_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = :table_name;\n" + "IF (SQL % NOTFOUND) THEN\n" + " COMMIT WORK;\n" + " RETURN;\n" + "END IF;\n" + "UPDATE SYS_TABLES SET ID = :new_id\n" + " WHERE ID = old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = old_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -2571,13 +2538,10 @@ do not allow the discard. We also reserve the data dictionary latch. */ table->ibd_file_missing = TRUE; } } + funct_exit: row_mysql_unlock_data_dictionary(trx); - if (graph) { - que_graph_free(graph); - } - trx_commit_for_mysql(trx); trx->op_info = ""; @@ -2738,9 +2702,7 @@ row_truncate_table_for_mysql( btr_pcur_t pcur; mtr_t mtr; dulint new_id; - char* sql; - que_thr_t* thr; - que_t* graph = NULL; + pars_info_t* info = NULL; /* How do we prevent crashes caused by ongoing operations on the table? Old operations could try to access non-existent pages. @@ -2768,30 +2730,6 @@ by DISCARD TABLESPACE.) 5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the TRUNCATE. We also reserve the data dictionary latch. */ - static const char renumber_tablespace_proc[] = - "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" - "old_id CHAR;\n" - "new_id CHAR;\n" - "old_id_low INT;\n" - "old_id_high INT;\n" - "new_id_low INT;\n" - "new_id_high INT;\n" - "BEGIN\n" - "old_id_high := %lu;\n" - "old_id_low := %lu;\n" - "new_id_high := %lu;\n" - "new_id_low := %lu;\n" - "old_id := CONCAT(TO_BINARY(old_id_high, 4), TO_BINARY(old_id_low, 4));\n" - "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" - "UPDATE SYS_TABLES SET ID = new_id\n" - "WHERE ID = old_id;\n" - "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" - "WHERE TABLE_ID = old_id;\n" - "COMMIT WORK;\n" - "END;\n"; - ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(table); @@ -2952,35 +2890,27 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */ btr_pcur_close(&pcur); mtr_commit(&mtr); - new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - - mem_heap_empty(heap); - sql = mem_heap_alloc(heap, (sizeof renumber_tablespace_proc) + 40); - sprintf(sql, renumber_tablespace_proc, - (ulong) ut_dulint_get_high(table->id), - (ulong) ut_dulint_get_low(table->id), - (ulong) ut_dulint_get_high(new_id), - (ulong) ut_dulint_get_low(new_id)); - - graph = pars_sql(NULL, sql); - - ut_a(graph); - mem_heap_free(heap); - graph->trx = trx; - trx->graph = NULL; + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + info = pars_info_create(); - thr = que_fork_start_command(graph); - ut_a(thr); + pars_info_add_dulint_literal(info, "old_id", table->id); + pars_info_add_dulint_literal(info, "new_id", new_id); - que_run_threads(thr); - - que_graph_free(graph); - - err = trx->error_state; + err = que_eval_sql(info, + "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" + "BEGIN\n" + "UPDATE SYS_TABLES SET ID = :new_id\n" + " WHERE ID = :old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = :old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = :new_id\n" + " WHERE TABLE_ID = :old_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { trx->error_state = DB_SUCCESS; @@ -3030,83 +2960,13 @@ row_drop_table_for_mysql( dict_foreign_t* foreign; dict_table_t* table; ulint space_id; - que_thr_t* thr; - que_t* graph; ulint err; const char* table_name; ulint namelen; char* dir_path_of_temp_table = NULL; ibool success; ibool locked_dictionary = FALSE; - char* quoted_name; - char* sql; - - /* We use the private SQL parser of Innobase to generate the - query graphs needed in deleting the dictionary data from system - tables in Innobase. Deleting a row from SYS_INDEXES table also - frees the file segments of the B-tree associated with the index. */ - - static const char str1[] = - "PROCEDURE DROP_TABLE_PROC () IS\n" - "table_name CHAR;\n" - "sys_foreign_id CHAR;\n" - "table_id CHAR;\n" - "index_id CHAR;\n" - "foreign_id CHAR;\n" - "found INT;\n" - "BEGIN\n" - "table_name := "; - static const char str2[] = - ";\n" - "SELECT ID INTO table_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = table_name;\n" - "IF (SQL % NOTFOUND) THEN\n" - " COMMIT WORK;\n" - " RETURN;\n" - "END IF;\n" - "found := 1;\n" - "SELECT ID INTO sys_foreign_id\n" - "FROM SYS_TABLES\n" - "WHERE NAME = 'SYS_FOREIGN';\n" - "IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - "END IF;\n" - "IF (table_name = 'SYS_FOREIGN') THEN\n" - " found := 0;\n" - "END IF;\n" - "IF (table_name = 'SYS_FOREIGN_COLS') THEN\n" - " found := 0;\n" - "END IF;\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = table_name\n" - " AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE" - " DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n" - " DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n" - " END IF;\n" - "END LOOP;\n" - "found := 1;\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO index_id\n" - " FROM SYS_INDEXES\n" - " WHERE TABLE_ID = table_id;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE" - " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" - " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" - " AND TABLE_ID = table_id;\n" - " END IF;\n" - "END LOOP;\n" - "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" - "DELETE FROM SYS_TABLES WHERE ID = table_id;\n" - "COMMIT WORK;\n" - "END;\n"; + pars_info_t* info = NULL; ut_a(name != NULL); @@ -3161,14 +3021,6 @@ row_drop_table_for_mysql( srv_print_innodb_table_monitor = FALSE; } - quoted_name = mem_strdupq(name, '\''); - namelen = strlen(quoted_name); - sql = mem_alloc((sizeof str1) + (sizeof str2) - 2 + 1 + namelen); - memcpy(sql, str1, (sizeof str1) - 1); - memcpy(sql + (sizeof str1) - 1, quoted_name, namelen); - memcpy(sql + (sizeof str1) - 1 + namelen, str2, sizeof str2); - mem_free(quoted_name); - /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -3186,16 +3038,6 @@ row_drop_table_for_mysql( ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - graph = pars_sql(NULL, sql); - - ut_a(graph); - mem_free(sql); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - table = dict_table_get_low(name); if (!table) { @@ -3319,18 +3161,80 @@ fputs(" InnoDB: You are trying to drop table ", stderr); trx->dict_operation = TRUE; trx->table_id = table->id; - ut_a(thr = que_fork_start_command(graph)); + /* We use the private SQL parser of Innobase to generate the + query graphs needed in deleting the dictionary data from system + tables in Innobase. Deleting a row from SYS_INDEXES table also + frees the file segments of the B-tree associated with the index. */ - que_run_threads(thr); + info = pars_info_create(); - err = trx->error_state; + pars_info_add_str_literal(info, "table_name", name); + + err = que_eval_sql(info, + "PROCEDURE DROP_TABLE_PROC () IS\n" + "sys_foreign_id CHAR;\n" + "table_id CHAR;\n" + "index_id CHAR;\n" + "foreign_id CHAR;\n" + "found INT;\n" + "BEGIN\n" + "SELECT ID INTO table_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = :table_name;\n" + "IF (SQL % NOTFOUND) THEN\n" + " COMMIT WORK;\n" + " RETURN;\n" + "END IF;\n" + "found := 1;\n" + "SELECT ID INTO sys_foreign_id\n" + "FROM SYS_TABLES\n" + "WHERE NAME = 'SYS_FOREIGN';\n" + "IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + "END IF;\n" + "IF (:table_name = 'SYS_FOREIGN') THEN\n" + " found := 0;\n" + "END IF;\n" + "IF (:table_name = 'SYS_FOREIGN_COLS') THEN\n" + " found := 0;\n" + "END IF;\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = :table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(:table_name);\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE" + " DELETE FROM SYS_FOREIGN_COLS WHERE ID = foreign_id;\n" + " DELETE FROM SYS_FOREIGN WHERE ID = foreign_id;\n" + " END IF;\n" + "END LOOP;\n" + "found := 1;\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO index_id\n" + " FROM SYS_INDEXES\n" + " WHERE TABLE_ID = table_id;\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE" + " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" + " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" + " AND TABLE_ID = table_id;\n" + " END IF;\n" + "END LOOP;\n" + "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" + "DELETE FROM SYS_TABLES WHERE ID = table_id;\n" + "COMMIT WORK;\n" + "END;\n" + , trx); if (err != DB_SUCCESS) { ut_a(err == DB_OUT_OF_FILE_SPACE); err = DB_MUST_GET_MORE_FILE_SPACE; - row_mysql_handle_errors(&err, trx, thr, NULL); + row_mysql_handle_errors(&err, trx, NULL, NULL); ut_error; } else { @@ -3408,8 +3312,6 @@ funct_exit: mem_free(dir_path_of_temp_table); } - que_graph_free(graph); - trx_commit_for_mysql(trx); trx->op_info = ""; @@ -3514,6 +3416,62 @@ row_is_mysql_tmp_table_name( return(strstr(name, "/@0023sql") != NULL); } +/******************************************************************** +Delete a single constraint. */ +static +int +row_delete_constraint_low( +/*======================*/ + /* out: error code or DB_SUCCESS */ + const char* id, /* in: constraint id */ + trx_t* trx) /* in: transaction handle */ +{ + pars_info_t* info = pars_info_create(); + + pars_info_add_str_literal(info, "id", id); + + return(que_eval_sql(info, + "PROCEDURE DELETE_CONSTRAINT () IS\n" + "BEGIN\n" + "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" + "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" + "END;\n" + , trx)); +} + +/******************************************************************** +Delete a single constraint. */ +static +int +row_delete_constraint( +/*==================*/ + /* out: error code or DB_SUCCESS */ + const char* id, /* in: constraint id */ + const char* database_name, /* in: database name, with the + trailing '/' */ + mem_heap_t* heap, /* in: memory heap */ + trx_t* trx) /* in: transaction handle */ +{ + ulint err; + + /* New format constraints have ids /. */ + err = row_delete_constraint_low( + mem_heap_strcat(heap, database_name, id), trx); + + if ((err == DB_SUCCESS) && !strchr(id, '/')) { + /* Old format < 4.0.18 constraints have constraint ids + _. We only try deleting them if the + constraint name does not contain a '/' character, otherwise + deleting a new format constraint named 'foo/bar' from + database 'baz' would remove constraint 'bar' from database + 'foo', if it existed. */ + + err = row_delete_constraint_low(id, trx); + } + + return(err); +} + /************************************************************************* Renames a table for MySQL. */ @@ -3526,100 +3484,13 @@ row_rename_table_for_mysql( trx_t* trx) /* in: transaction handle */ { dict_table_t* table; - que_thr_t* thr; - que_t* graph = NULL; ulint err; - /* We use the private SQL parser of Innobase to generate the - query graphs needed in deleting the dictionary data from system - tables in Innobase. Deleting a row from SYS_INDEXES table also - frees the file segments of the B-tree associated with the index. */ - static const char str1[] = - "PROCEDURE RENAME_TABLE_PROC () IS\n" - "new_table_name CHAR;\n" - "old_table_name CHAR;\n" - "gen_constr_prefix CHAR;\n" - "new_db_name CHAR;\n" - "foreign_id CHAR;\n" - "new_foreign_id CHAR;\n" - "old_db_name_len INT;\n" - "old_t_name_len INT;\n" - "new_db_name_len INT;\n" - "id_len INT;\n" - "found INT;\n" - "BEGIN\n" - "new_table_name := '"; - static const char str2[] = - "';\nold_table_name := '"; - static const char str3[] = - "';\n" - "UPDATE SYS_TABLES SET NAME = new_table_name\n" - "WHERE NAME = old_table_name;\n"; - static const char str4a1[] = /* drop some constraints of tmp tables */ - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '"; - static const char str4a2[] = "';\n" - "DELETE FROM SYS_FOREIGN WHERE ID = '"; - static const char str4a3[] = "';\n"; - static const char str4b[] = /* rename all constraints */ - "found := 1;\n" - "old_db_name_len := INSTR(old_table_name, '/') - 1;\n" - "new_db_name_len := INSTR(new_table_name, '/') - 1;\n" - "new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);\n" - "old_t_name_len := LENGTH(old_table_name);\n" - "gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = old_table_name\n" - " AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE\n" - " UPDATE SYS_FOREIGN\n" - " SET FOR_NAME = new_table_name\n" - " WHERE ID = foreign_id;\n" - " id_len := LENGTH(foreign_id);\n" - " IF (INSTR(foreign_id, '/') > 0) THEN\n" - " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" - " THEN\n" - " new_foreign_id :=\n" - " CONCAT(new_table_name,\n" - " SUBSTR(foreign_id, old_t_name_len,\n" - " id_len - old_t_name_len));\n" - " ELSE\n" - " new_foreign_id :=\n" - " CONCAT(new_db_name,\n" - " SUBSTR(foreign_id,\n" - " old_db_name_len,\n" - " id_len - old_db_name_len));\n" - " END IF;\n" - " UPDATE SYS_FOREIGN\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " UPDATE SYS_FOREIGN_COLS\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - " END IF;\n" - "END LOOP;\n" - "UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n" - "WHERE REF_NAME = old_table_name\n" - " AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n"; - static const char str5[] = - "END;\n"; - mem_heap_t* heap = NULL; const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; ibool recovering_temp_table = FALSE; ibool old_is_tmp, new_is_tmp; - ulint len; - ulint i; - ibool success; - /* length of database name; 0 if not renaming to a temporary table */ - ulint db_name_len; - char* sql; - char* sqlend; + pars_info_t* info = NULL; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(old_name != NULL); @@ -3697,13 +3568,7 @@ row_rename_table_for_mysql( goto funct_exit; } - /* calculate the length of the SQL string */ - len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 - + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); - if (new_is_tmp) { - db_name_len = dict_get_db_name_len(old_name) + 1; - /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve the original foreign key constraint definitions despite the @@ -3713,110 +3578,124 @@ row_rename_table_for_mysql( heap = mem_heap_create(100); err = dict_foreign_parse_drop_constraints(heap, trx, - table, - &n_constraints_to_drop, - &constraints_to_drop); + table, &n_constraints_to_drop, &constraints_to_drop); + if (err != DB_SUCCESS) { goto funct_exit; } - - /* reserve space for all database names */ - len += 2 * n_constraints_to_drop - * (ut_strlenq(old_name, '\'') - - ut_strlenq(old_name + db_name_len, '\'')); - - for (i = 0; i < n_constraints_to_drop; i++) { - ulint addlen - = 2 * ut_strlenq(constraints_to_drop[i], '\'') - + ((sizeof str4a1) + (sizeof str4a2) - + (sizeof str4a3) - 3); - if (!strchr(constraints_to_drop[i], '/')) { - addlen *= 2; - } - len += addlen; - } - } else { - db_name_len = 0; - len += (sizeof str4b) - 1; } - sql = sqlend = mem_alloc(len + 1); - memcpy(sql, str1, (sizeof str1) - 1); - sqlend += (sizeof str1) - 1; - sqlend = ut_strcpyq(sqlend, '\'', new_name); - memcpy(sqlend, str2, (sizeof str2) - 1); - sqlend += (sizeof str2) - 1; - sqlend = ut_strcpyq(sqlend, '\'', old_name); - memcpy(sqlend, str3, (sizeof str3) - 1); - sqlend += (sizeof str3) - 1; + /* We use the private SQL parser of Innobase to generate the query + graphs needed in deleting the dictionary data from system tables in + Innobase. Deleting a row from SYS_INDEXES table also frees the file + segments of the B-tree associated with the index. */ - if (db_name_len) { - /* Internally, old format < 4.0.18 constraints have as the - constraint id _, while new format constraints - have /. */ + info = pars_info_create(); + + pars_info_add_str_literal(info, "new_table_name", new_name); + pars_info_add_str_literal(info, "old_table_name", old_name); + + err = que_eval_sql(info, + "PROCEDURE RENAME_TABLE () IS\n" + "BEGIN\n" + "UPDATE SYS_TABLES SET NAME = :new_table_name\n" + " WHERE NAME = :old_table_name;\n" + "END;\n" + , trx); + + if (err != DB_SUCCESS) { + + goto end; + } + + if (!new_is_tmp) { + /* Rename all constraints. */ + + info = pars_info_create(); + + pars_info_add_str_literal(info, "new_table_name", new_name); + pars_info_add_str_literal(info, "old_table_name", old_name); + + err = que_eval_sql(info, + "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n" + "gen_constr_prefix CHAR;\n" + "new_db_name CHAR;\n" + "foreign_id CHAR;\n" + "new_foreign_id CHAR;\n" + "old_db_name_len INT;\n" + "old_t_name_len INT;\n" + "new_db_name_len INT;\n" + "id_len INT;\n" + "found INT;\n" + "BEGIN\n" + "found := 1;\n" + "old_db_name_len := INSTR(:old_table_name, '/') - 1;\n" + "new_db_name_len := INSTR(:new_table_name, '/') - 1;\n" + "new_db_name := SUBSTR(:new_table_name, 0, new_db_name_len);\n" + "old_t_name_len := LENGTH(:old_table_name);\n" + "gen_constr_prefix := CONCAT(:old_table_name, '_ibfk_');\n" + "WHILE found = 1 LOOP\n" + " SELECT ID INTO foreign_id\n" + " FROM SYS_FOREIGN\n" + " WHERE FOR_NAME = :old_table_name\n" + " AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name);\n" + " IF (SQL % NOTFOUND) THEN\n" + " found := 0;\n" + " ELSE\n" + " UPDATE SYS_FOREIGN\n" + " SET FOR_NAME = :new_table_name\n" + " WHERE ID = foreign_id;\n" + " id_len := LENGTH(foreign_id);\n" + " IF (INSTR(foreign_id, '/') > 0) THEN\n" + " IF (INSTR(foreign_id,\n" + " gen_constr_prefix) > 0)\n" + " THEN\n" + " new_foreign_id :=\n" + " CONCAT(:new_table_name,\n" + " SUBSTR(foreign_id, old_t_name_len,\n" + " id_len - old_t_name_len));\n" + " ELSE\n" + " new_foreign_id :=\n" + " CONCAT(new_db_name,\n" + " SUBSTR(foreign_id,\n" + " old_db_name_len,\n" + " id_len - old_db_name_len));\n" + " END IF;\n" + " UPDATE SYS_FOREIGN\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " UPDATE SYS_FOREIGN_COLS\n" + " SET ID = new_foreign_id\n" + " WHERE ID = foreign_id;\n" + " END IF;\n" + " END IF;\n" + "END LOOP;\n" + "UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n" + "WHERE REF_NAME = :old_table_name\n" + " AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);\n" + "END;\n" + , trx); + + } else if (n_constraints_to_drop > 0) { + /* Drop some constraints of tmp tables. */ + + ulint db_name_len = dict_get_db_name_len(old_name) + 1; + char* db_name = mem_heap_strdupl(heap, old_name, + db_name_len); + ulint i; for (i = 0; i < n_constraints_to_drop; i++) { - memcpy(sqlend, str4a1, (sizeof str4a1) - 1); - sqlend += (sizeof str4a1) - 1; - sqlend = ut_memcpyq(sqlend, '\'', - old_name, db_name_len); - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a2, (sizeof str4a2) - 1); - sqlend += (sizeof str4a2) - 1; - sqlend = ut_memcpyq(sqlend, '\'', - old_name, db_name_len); - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a3, (sizeof str4a3) - 1); - sqlend += (sizeof str4a3) - 1; + err = row_delete_constraint(constraints_to_drop[i], + db_name, heap, trx); - if (!strchr(constraints_to_drop[i], '/')) { - /* If this happens to be an old format - constraint, let us delete it. Since all new - format constraints contain '/', it does no - harm to run these DELETEs anyway. */ - - memcpy(sqlend, str4a1, (sizeof str4a1) - 1); - sqlend += (sizeof str4a1) - 1; - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a2, (sizeof str4a2) - 1); - sqlend += (sizeof str4a2) - 1; - sqlend = ut_strcpyq(sqlend, '\'', - constraints_to_drop[i]); - memcpy(sqlend, str4a3, (sizeof str4a3) - 1); - sqlend += (sizeof str4a3) - 1; + if (err != DB_SUCCESS) { + break; } } } - else { - memcpy(sqlend, str4b, (sizeof str4b) - 1); - sqlend += (sizeof str4b) - 1; - } - - memcpy(sqlend, str5, sizeof str5); - sqlend += sizeof str5; - - ut_a(sqlend == sql + len + 1); - - graph = pars_sql(NULL, sql); - - ut_a(graph); - mem_free(sql); - - graph->trx = trx; - trx->graph = NULL; - - graph->fork_type = QUE_FORK_MYSQL_INTERFACE; - - ut_a(thr = que_fork_start_command(graph)); - - que_run_threads(thr); - - err = trx->error_state; +end: if (err != DB_SUCCESS) { if (err == DB_DUPLICATE_KEY) { ut_print_timestamp(stderr); @@ -3853,8 +3732,9 @@ row_rename_table_for_mysql( /* The following call will also rename the .ibd data file if the table is stored in a single-table tablespace */ - success = dict_table_rename_in_cache(table, new_name, + ibool success = dict_table_rename_in_cache(table, new_name, !new_is_tmp); + if (!success) { trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -3902,20 +3782,16 @@ row_rename_table_for_mysql( ut_a(dict_table_rename_in_cache(table, old_name, FALSE)); trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); + trx_general_rollback_for_mysql(trx, FALSE, NULL); trx->error_state = DB_SUCCESS; } } + funct_exit: if (!recovering_temp_table) { row_mysql_unlock_data_dictionary(trx); } - if (graph) { - que_graph_free(graph); - } - if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } diff --git a/row/row0purge.c b/row/row0purge.c index 93ea7dffbe7..c1406c74d9c 100644 --- a/row/row0purge.c +++ b/row/row0purge.c @@ -521,7 +521,7 @@ row_purge_parse_undo_rec( mutex_enter(&(dict_sys->mutex)); - node->table = dict_table_get_on_id_low(table_id, trx); + node->table = dict_table_get_on_id_low(table_id); mutex_exit(&(dict_sys->mutex)); diff --git a/row/row0sel.c b/row/row0sel.c index de3a9011130..408614aca06 100644 --- a/row/row0sel.c +++ b/row/row0sel.c @@ -2036,8 +2036,13 @@ row_fetch_print( dtype_print(type); fprintf(stderr, "\n"); - ut_print_buf(stderr, dfield_get_data(dfield), - dfield_get_len(dfield)); + if (dfield_get_len(dfield) != UNIV_SQL_NULL) { + ut_print_buf(stderr, dfield_get_data(dfield), + dfield_get_len(dfield)); + } else { + fprintf(stderr, " ;"); + } + fprintf(stderr, "\n"); exp = que_node_get_next(exp); @@ -4401,7 +4406,7 @@ row_search_check_if_query_cache_permitted( dict_table_t* table; ibool ret = FALSE; - table = dict_table_get(norm_name, trx); + table = dict_table_get(norm_name); if (table == NULL) { diff --git a/row/row0upd.c b/row/row0upd.c index 667b99622a7..c111932a42a 100644 --- a/row/row0upd.c +++ b/row/row0upd.c @@ -202,8 +202,7 @@ row_upd_check_references_constraints( foreign->n_fields))) { if (foreign->foreign_table == NULL) { - dict_table_get(foreign->foreign_table_name, - trx); + dict_table_get(foreign->foreign_table_name); } if (foreign->foreign_table) { diff --git a/srv/srv0srv.c b/srv/srv0srv.c index fe1eeab9c3f..dd976b4b465 100644 --- a/srv/srv0srv.c +++ b/srv/srv0srv.c @@ -362,30 +362,6 @@ ibool srv_print_innodb_lock_monitor = FALSE; ibool srv_print_innodb_tablespace_monitor = FALSE; ibool srv_print_innodb_table_monitor = FALSE; -/* The parameters below are obsolete: */ - -ibool srv_print_parsed_sql = FALSE; - -ulint srv_sim_disk_wait_pct = ULINT_MAX; -ulint srv_sim_disk_wait_len = ULINT_MAX; -ibool srv_sim_disk_wait_by_yield = FALSE; -ibool srv_sim_disk_wait_by_wait = FALSE; - -ibool srv_measure_contention = FALSE; -ibool srv_measure_by_spin = FALSE; - -ibool srv_test_extra_mutexes = FALSE; -ibool srv_test_nocache = FALSE; -ibool srv_test_cache_evict = FALSE; - -ibool srv_test_sync = FALSE; -ulint srv_test_n_threads = ULINT_MAX; -ulint srv_test_n_loops = ULINT_MAX; -ulint srv_test_n_free_rnds = ULINT_MAX; -ulint srv_test_n_reserved_rnds = ULINT_MAX; -ulint srv_test_array_size = ULINT_MAX; -ulint srv_test_n_mutexes = ULINT_MAX; - /* Array of English strings describing the current state of an i/o handler thread */ @@ -873,11 +849,9 @@ srv_init(void) srv_sys = mem_alloc(sizeof(srv_sys_t)); kernel_mutex_temp = mem_alloc(sizeof(mutex_t)); - mutex_create(&kernel_mutex); - mutex_set_level(&kernel_mutex, SYNC_KERNEL); + mutex_create(&kernel_mutex, SYNC_KERNEL); - mutex_create(&srv_innodb_monitor_mutex); - mutex_set_level(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK); srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)); @@ -911,10 +885,6 @@ srv_init(void) srv_meter_foreground[i] = 250; } - srv_sys->operational = os_event_create(NULL); - - ut_a(srv_sys->operational); - UT_LIST_INIT(srv_sys->tasks); /* create dummy table and index for old-style infimum and supremum */ @@ -1847,11 +1817,7 @@ srv_export_innodb_status(void) A thread which wakes up threads whose lock wait may have lasted too long. This also prints the info output by various InnoDB monitors. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_lock_timeout_and_monitor_thread( /*================================*/ /* out: a dummy parameter */ @@ -2023,22 +1989,15 @@ exit_func: thread should always use that to exit and not use return() to exit. */ os_thread_exit(NULL); -#ifndef __WIN__ - return(NULL); -#else - return(0); -#endif + + OS_THREAD_DUMMY_RETURN; } /************************************************************************* A thread which prints warnings about semaphore waits which have lasted too long. These can be used to track bugs which cause hangs. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_error_monitor_thread( /*=====================*/ /* out: a dummy parameter */ @@ -2120,11 +2079,7 @@ loop: os_thread_exit(NULL); -#ifndef __WIN__ - return(NULL); -#else - return(0); -#endif + OS_THREAD_DUMMY_RETURN; } /*********************************************************************** @@ -2169,11 +2124,7 @@ srv_wake_master_thread(void) /************************************************************************* The master thread controlling the server. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t srv_master_thread( /*==============*/ /* out: a dummy parameter */ @@ -2212,7 +2163,6 @@ srv_master_thread( mutex_exit(&kernel_mutex); - os_event_set(srv_sys->operational); loop: /*****************************************************************/ /* ---- When there is database activity by users, we cycle in this @@ -2607,22 +2557,9 @@ suspend_thread: os_thread_exit(NULL); } - /* When there is user activity, InnoDB will set the event and the main - thread goes back to loop: */ + /* When there is user activity, InnoDB will set the event and the + main thread goes back to loop. */ goto loop; - - /* We count the number of threads in os_thread_exit(). A created - thread should always use that to exit and not use return() to exit. - The thread actually never comes here because it is exited in an - os_event_wait(). */ - - os_thread_exit(NULL); - -#ifndef __WIN__ - return(NULL); /* Not reached */ -#else - return(0); -#endif } #endif /* !UNIV_HOTBACKUP */ diff --git a/srv/srv0start.c b/srv/srv0start.c index 8895e7cb052..65847171ae1 100644 --- a/srv/srv0start.c +++ b/srv/srv0start.c @@ -108,8 +108,10 @@ static char* srv_monitor_file_name; static int inno_bcmp(register const char *s1, register const char *s2, register uint len) { - while (len-- != 0 && *s1++ == *s2++) ; - return len+1; + while ((len-- != 0) && (*s1++ == *s2++)) + ; + + return(len + 1); } #define memcmp(A,B,C) inno_bcmp((A),(B),(C)) #endif @@ -426,11 +428,7 @@ srv_parse_log_group_home_dirs( I/o-handler thread function. */ static -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t io_handler_thread( /*==============*/ void* arg) @@ -459,11 +457,7 @@ io_handler_thread( os_thread_exit(NULL); -#ifndef __WIN__ - return(NULL); /* Not reached */ -#else - return(0); -#endif + OS_THREAD_DUMMY_RETURN; } #endif /* !UNIV_HOTBACKUP */ @@ -942,8 +936,7 @@ skip_size_check: ios = 0; - mutex_create(&ios_mutex); - mutex_set_level(&ios_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&ios_mutex, SYNC_NO_ORDER_CHECK); return(DB_SUCCESS); } @@ -1175,8 +1168,8 @@ NetWare. */ return((int) err); } - mutex_create(&srv_monitor_file_mutex); - mutex_set_level(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK); + if (srv_innodb_status) { srv_monitor_file_name = mem_alloc( strlen(fil_path_to_mysql_datadir) + @@ -1197,15 +1190,15 @@ NetWare. */ } } - mutex_create(&srv_dict_tmpfile_mutex); - mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION); + mutex_create(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION); + srv_dict_tmpfile = os_file_create_tmpfile(); if (!srv_dict_tmpfile) { return(DB_ERROR); } - mutex_create(&srv_misc_tmpfile_mutex); - mutex_set_level(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH); + mutex_create(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH); + srv_misc_tmpfile = os_file_create_tmpfile(); if (!srv_misc_tmpfile) { return(DB_ERROR); @@ -1539,11 +1532,6 @@ NetWare. */ } #endif /* UNIV_LOG_ARCHIVE */ - if (srv_measure_contention) { - /* os_thread_create(&test_measure_cont, NULL, thread_ids + - SRV_MAX_N_IO_THREADS); */ - } - /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ diff --git a/sync/sync0arr.c b/sync/sync0arr.c index fb7ec4cc78b..81986cdfd33 100644 --- a/sync/sync0arr.c +++ b/sync/sync0arr.c @@ -213,8 +213,7 @@ sync_array_create( if (protection == SYNC_ARRAY_OS_MUTEX) { arr->os_mutex = os_mutex_create(NULL); } else if (protection == SYNC_ARRAY_MUTEX) { - mutex_create(&(arr->mutex)); - mutex_set_level(&(arr->mutex), SYNC_NO_ORDER_CHECK); + mutex_create(&arr->mutex, SYNC_NO_ORDER_CHECK); } else { ut_error; } diff --git a/sync/sync0rw.c b/sync/sync0rw.c index 673e1080d89..ffc2633b467 100644 --- a/sync/sync0rw.c +++ b/sync/sync0rw.c @@ -89,19 +89,19 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ + ulint level, /* in: level */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name) /* in: mutex name */ + ulint cline, /* in: file line where created */ + const char* cmutex_name) /* in: mutex name */ { - /* If this is the very first time a synchronization - object is created, then the following call initializes - the sync system. */ + /* If this is the very first time a synchronization object is + created, then the following call initializes the sync system. */ - mutex_create(rw_lock_get_mutex(lock)); - mutex_set_level(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK); + mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK); lock->mutex.cfile_name = cfile_name; lock->mutex.cline = cline; + #ifndef UNIV_HOTBACKUP lock->mutex.cmutex_name = cmutex_name; lock->mutex.mutex_type = 1; @@ -116,9 +116,10 @@ rw_lock_create_func( #ifdef UNIV_SYNC_DEBUG UT_LIST_INIT(lock->debug_list); - - lock->level = SYNC_LEVEL_NONE; #endif /* UNIV_SYNC_DEBUG */ + + lock->level = level; + lock->magic_n = RW_LOCK_MAGIC_N; lock->cfile_name = cfile_name; @@ -669,18 +670,6 @@ rw_lock_remove_debug_info( } #endif /* UNIV_SYNC_DEBUG */ -/********************************************************************** -Sets the rw-lock latching level field. */ - -void -rw_lock_set_level( -/*==============*/ - rw_lock_t* lock, /* in: rw-lock */ - ulint level) /* in: level */ -{ - lock->level = level; -} - #ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks if the thread has locked the rw-lock in the specified mode, with diff --git a/sync/sync0sync.c b/sync/sync0sync.c index 6354830df70..04f03e89ec5 100644 --- a/sync/sync0sync.c +++ b/sync/sync0sync.c @@ -202,6 +202,7 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ + ulint level, /* in: level */ const char* cfile_name, /* in: file name where created */ ulint cline, /* in: file line where created */ const char* cmutex_name) /* in: mutex name */ @@ -218,7 +219,7 @@ mutex_create_func( mutex->line = 0; mutex->file_name = "not yet reserved"; #endif /* UNIV_SYNC_DEBUG */ - mutex->level = SYNC_LEVEL_NONE; + mutex->level = level; mutex->cfile_name = cfile_name; mutex->cline = cline; #ifndef UNIV_HOTBACKUP @@ -598,19 +599,6 @@ mutex_get_debug_info( } #endif /* UNIV_SYNC_DEBUG */ -/********************************************************************** -Sets the mutex latching level field. */ - -void -mutex_set_level( -/*============*/ - mutex_t* mutex, /* in: mutex */ - ulint level) /* in: level */ -{ - mutex->level = level; -} - - #ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug @@ -979,8 +967,8 @@ void sync_thread_add_level( /*==================*/ void* latch, /* in: pointer to a mutex or an rw-lock */ - ulint level) /* in: level in the latching order; if SYNC_LEVEL_NONE, - nothing is done */ + ulint level) /* in: level in the latching order; if + SYNC_LEVEL_VARYING, nothing is done */ { sync_level_t* array; sync_level_t* slot; @@ -1002,7 +990,7 @@ sync_thread_add_level( return; } - if (level == SYNC_LEVEL_NONE) { + if (level == SYNC_LEVEL_VARYING) { return; } @@ -1050,6 +1038,9 @@ sync_thread_add_level( case SYNC_RECV: ut_a(sync_thread_levels_g(array, SYNC_RECV)); break; + case SYNC_WORK_QUEUE: + ut_a(sync_thread_levels_g(array, SYNC_WORK_QUEUE)); + break; case SYNC_LOG: ut_a(sync_thread_levels_g(array, SYNC_LOG)); break; @@ -1290,21 +1281,17 @@ sync_init(void) /* Init the mutex list and create the mutex to protect it. */ UT_LIST_INIT(mutex_list); - mutex_create(&mutex_list_mutex); - mutex_set_level(&mutex_list_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK); - mutex_create(&sync_thread_mutex); - mutex_set_level(&sync_thread_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK); /* Init the rw-lock list and create the mutex to protect it. */ UT_LIST_INIT(rw_lock_list); - mutex_create(&rw_lock_list_mutex); - mutex_set_level(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK); #ifdef UNIV_SYNC_DEBUG - mutex_create(&rw_lock_debug_mutex); - mutex_set_level(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK); + mutex_create(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK); rw_lock_debug_event = os_event_create(NULL); rw_lock_debug_waiters = FALSE; diff --git a/thr/thr0loc.c b/thr/thr0loc.c index 2a7a6c1c21f..c63520e8a07 100644 --- a/thr/thr0loc.c +++ b/thr/thr0loc.c @@ -226,6 +226,5 @@ thr_local_init(void) thr_local_hash = hash_create(OS_THREAD_MAX_N + 100); - mutex_create(&thr_local_mutex); - mutex_set_level(&thr_local_mutex, SYNC_THR_LOCAL); + mutex_create(&thr_local_mutex, SYNC_THR_LOCAL); } diff --git a/trx/trx0purge.c b/trx/trx0purge.c index be949079f80..79f38b1ee52 100644 --- a/trx/trx0purge.c +++ b/trx/trx0purge.c @@ -211,11 +211,9 @@ trx_purge_sys_create(void) purge_sys->purge_undo_no = ut_dulint_zero; purge_sys->next_stored = FALSE; - rw_lock_create(&(purge_sys->latch)); - rw_lock_set_level(&(purge_sys->latch), SYNC_PURGE_LATCH); + rw_lock_create(&purge_sys->latch, SYNC_PURGE_LATCH); - mutex_create(&(purge_sys->mutex)); - mutex_set_level(&(purge_sys->mutex), SYNC_PURGE_SYS); + mutex_create(&purge_sys->mutex, SYNC_PURGE_SYS); purge_sys->heap = mem_heap_create(256); diff --git a/trx/trx0roll.c b/trx/trx0roll.c index fd733ef5fb8..f5a9c0eb6e6 100644 --- a/trx/trx0roll.c +++ b/trx/trx0roll.c @@ -391,11 +391,7 @@ transaction already was committed, then we clean up a possible insert undo log. If the transaction was not yet committed, then we roll it back. Note: this is done in a background thread. */ -#ifndef __WIN__ -void* -#else -ulint -#endif +os_thread_ret_t trx_rollback_or_clean_all_without_sess( /*===================================*/ /* out: a dummy parameter */ @@ -544,7 +540,7 @@ loop: (ulong) ut_dulint_get_high(trx->table_id), (ulong) ut_dulint_get_low(trx->table_id)); - table = dict_table_get_on_id_low(trx->table_id, trx); + table = dict_table_get_on_id_low(trx->table_id); if (table) { fputs("InnoDB: Table found: dropping table ", stderr); @@ -576,13 +572,7 @@ leave_function: os_thread_exit(NULL); - /* The following is dummy code to keep the compiler happy: */ - -#ifndef __WIN__ - return(NULL); -#else - return(0); -#endif + OS_THREAD_DUMMY_RETURN; } /*********************************************************************** diff --git a/trx/trx0rseg.c b/trx/trx0rseg.c index f396666e7c9..5136174d110 100644 --- a/trx/trx0rseg.c +++ b/trx/trx0rseg.c @@ -147,8 +147,7 @@ trx_rseg_mem_create( rseg->space = space; rseg->page_no = page_no; - mutex_create(&(rseg->mutex)); - mutex_set_level(&(rseg->mutex), SYNC_RSEG); + mutex_create(&rseg->mutex, SYNC_RSEG); UT_LIST_ADD_LAST(rseg_list, trx_sys->rseg_list, rseg); diff --git a/trx/trx0sys.c b/trx/trx0sys.c index ee6b0ba825c..ba7820394d6 100644 --- a/trx/trx0sys.c +++ b/trx/trx0sys.c @@ -54,6 +54,36 @@ char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN]; ib_longlong trx_sys_mysql_bin_log_pos = -1; +/******************************************************************** +Determines if a page number is located inside the doublewrite buffer. */ + +ibool +trx_doublewrite_page_inside( +/*========================*/ + /* out: TRUE if the location is inside + the two blocks of the doublewrite buffer */ + ulint page_no) /* in: page number */ +{ + if (trx_doublewrite == NULL) { + + return(FALSE); + } + + if (page_no >= trx_doublewrite->block1 + && page_no < trx_doublewrite->block1 + + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { + return(TRUE); + } + + if (page_no >= trx_doublewrite->block2 + && page_no < trx_doublewrite->block2 + + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { + return(TRUE); + } + + return(FALSE); +} + /******************************************************************** Creates or initialializes the doublewrite buffer at a database start. */ static @@ -71,8 +101,7 @@ trx_doublewrite_init( os_do_not_call_flush_at_each_write = TRUE; #endif /* UNIV_DO_FLUSH */ - mutex_create(&(trx_doublewrite->mutex)); - mutex_set_level(&(trx_doublewrite->mutex), SYNC_DOUBLEWRITE); + mutex_create(&trx_doublewrite->mutex, SYNC_DOUBLEWRITE); trx_doublewrite->first_free = 0; diff --git a/trx/trx0trx.c b/trx/trx0trx.c index a3115e332cd..5f191f4599b 100644 --- a/trx/trx0trx.c +++ b/trx/trx0trx.c @@ -144,8 +144,7 @@ trx_create( trx->repl_wait_binlog_name = NULL; trx->repl_wait_binlog_pos = 0; - mutex_create(&(trx->undo_mutex)); - mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO); + mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO); trx->rseg = NULL; diff --git a/ut/Makefile.am b/ut/Makefile.am index c833a6d5a4c..fa4eeb2e9c9 100644 --- a/ut/Makefile.am +++ b/ut/Makefile.am @@ -19,6 +19,6 @@ include ../include/Makefile.i noinst_LIBRARIES = libut.a -libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c +libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c ut0wqueue.c EXTRA_PROGRAMS = diff --git a/ut/ut0list.c b/ut/ut0list.c new file mode 100644 index 00000000000..bbf7626597a --- /dev/null +++ b/ut/ut0list.c @@ -0,0 +1,147 @@ +#include "ut0list.h" +#ifdef UNIV_NONINL +#include "ut0list.ic" +#endif + +/******************************************************************** +Create a new list. */ + +ib_list_t* +ib_list_create(void) +/*=================*/ + /* out: list */ +{ + ib_list_t* list = mem_alloc(sizeof(ib_list_t)); + + list->first = NULL; + list->last = NULL; + + return(list); +} + +/******************************************************************** +Free a list. */ + +void +ib_list_free( +/*=========*/ + ib_list_t* list) /* in: list */ +{ + /* We don't check that the list is empty because it's entirely valid + to e.g. have all the nodes allocated from a single heap that is then + freed after the list itself is freed. */ + + mem_free(list); +} + +/******************************************************************** +Add the data to the start of the list. */ + +ib_list_node_t* +ib_list_add_first( +/*==============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + void* data, /* in: data */ + mem_heap_t* heap) /* in: memory heap to use */ +{ + return(ib_list_add_after(list, ib_list_get_first(list), data, heap)); +} + +/******************************************************************** +Add the data to the end of the list. */ + +ib_list_node_t* +ib_list_add_last( +/*=============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + void* data, /* in: data */ + mem_heap_t* heap) /* in: memory heap to use */ +{ + return(ib_list_add_after(list, ib_list_get_last(list), data, heap)); +} + +/******************************************************************** +Add the data after the indicated node. */ + +ib_list_node_t* +ib_list_add_after( +/*==============*/ + /* out: new list node*/ + ib_list_t* list, /* in: list */ + ib_list_node_t* prev_node, /* in: node preceding new node (can + be NULL) */ + void* data, /* in: data */ + mem_heap_t* heap) /* in: memory heap to use */ +{ + ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t)); + + node->data = data; + + if (!list->first) { + /* Empty list. */ + + ut_a(!prev_node); + + node->prev = NULL; + node->next = NULL; + + list->first = node; + list->last = node; + } else if (!prev_node) { + /* Start of list. */ + + node->prev = NULL; + node->next = list->first; + + list->first->prev = node; + + list->first = node; + } else { + /* Middle or end of list. */ + + node->prev = prev_node; + node->next = prev_node->next; + + prev_node->next = node; + + if (node->next) { + node->next->prev = node; + } else { + list->last = node; + } + } + + return(node); +} + +/******************************************************************** +Remove the node from the list. */ + +void +ib_list_remove( +/*===========*/ + ib_list_t* list, /* in: list */ + ib_list_node_t* node) /* in: node to remove */ +{ + if (node->prev) { + node->prev->next = node->next; + } else { + /* First item in list. */ + + ut_ad(list->first == node); + + list->first = node->next; + } + + if (node->next) { + node->next->prev = node->prev; + } else { + /* Last item in list. */ + + ut_ad(list->last == node); + + list->last = node->prev; + } +} diff --git a/ut/ut0wqueue.c b/ut/ut0wqueue.c new file mode 100644 index 00000000000..2a6d8c19ef0 --- /dev/null +++ b/ut/ut0wqueue.c @@ -0,0 +1,92 @@ +#include "ut0wqueue.h" + +/******************************************************************** +Create a new work queue. */ + +ib_wqueue_t* +ib_wqueue_create(void) +/*===================*/ + /* out: work queue */ +{ + ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t)); + + mutex_create(&wq->mutex, SYNC_WORK_QUEUE); + + wq->items = ib_list_create(); + wq->event = os_event_create(NULL); + + return(wq); +} + +/******************************************************************** +Free a work queue. */ + +void +ib_wqueue_free( +/*===========*/ + ib_wqueue_t* wq) /* in: work queue */ +{ + ut_a(!ib_list_get_first(wq->items)); + + mutex_free(&wq->mutex); + ib_list_free(wq->items); + os_event_free(wq->event); + + mem_free(wq); +} + +/******************************************************************** +Add a work item to the queue. */ + +void +ib_wqueue_add( +/*==========*/ + ib_wqueue_t* wq, /* in: work queue */ + void* item, /* in: work item */ + mem_heap_t* heap) /* in: memory heap to use for allocating the + list node */ +{ + mutex_enter(&wq->mutex); + + ib_list_add_last(wq->items, item, heap); + os_event_set(wq->event); + + mutex_exit(&wq->mutex); +} + +/******************************************************************** +Wait for a work item to appear in the queue. */ + +void* +ib_wqueue_wait( + /* out: work item */ + ib_wqueue_t* wq) /* in: work queue */ +{ + ib_list_node_t* node; + + for (;;) { + os_event_wait(wq->event); + + mutex_enter(&wq->mutex); + + node = ib_list_get_first(wq->items); + + if (node) { + ib_list_remove(wq->items, node); + + if (!ib_list_get_first(wq->items)) { + /* We must reset the event when the list + gets emptied. */ + os_event_reset(wq->event); + } + + break; + } + + mutex_exit(&wq->mutex); + } + + mutex_exit(&wq->mutex); + + return(node->data); +}