summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <aivanov@mysql.com>2006-06-01 10:34:04 +0400
committerunknown <aivanov@mysql.com>2006-06-01 10:34:04 +0400
commitf68500fa3864e45cba10e01fa45be77785235041 (patch)
tree6e3a741f3a17d4092daffffbb0e8e1e0f47ab029
parent42c2c0b6a583d69fcb4282d150f53f2bee30ed32 (diff)
downloadmariadb-git-f68500fa3864e45cba10e01fa45be77785235041.tar.gz
Applied innodb-5.1-ss594 snapshot.
Fixed BUG#19542 "InnoDB doesn't increase the Handler_read_prev couter". Fixed BUG#19609 "Case sensitivity of innodb_data_file_path gives stupid error". Fixed BUG#19727 "InnoDB crashed server and crashed tables are ot recoverable". Also: * Remove remnants of the obsolete concept of memoryfixing tables and indexes. * Remove unused dict_table_LRU_trim(). * Remove unused 'trx' parameter from dict_table_get_on_id_low(), dict_table_get(), dict_table_get_and_increment_handle_count(). * Add a normal linked list implementation. * Add a work queue implementation. * Add 'level' parameter to mutex_create() and rw_lock_create(). Remove mutex_set_level() and rw_lock_set_level(). * Rename SYNC_LEVEL_NONE to SYNC_LEVEL_VARYING. * Add support for bound ids in InnoDB's parser. * Define UNIV_BTR_DEBUG for enabling consistency checks of FIL_PAGE_NEXT and FIL_PAGE_PREV when accessing sibling pages of B-tree indexes. btr_validate_level(): Check the validity of the doubly linked list formed by FIL_PAGE_NEXT and FIL_PAGE_PREV. * Adapt InnoDB to the new tablename to filename encoding in MySQL 5.1. ut_print_name(), ut_print_name1(): Add parameter 'table_id' for distinguishing names of tables from other identifiers. New: innobase_convert_from_table_id(), innobase_convert_from_id(), innobase_convert_from_filename(), innobase_get_charset. dict_accept(), dict_scan_id(), dict_scan_col(), dict_scan_table_name(), dict_skip_word(), dict_create_foreign_constraints_low(): Add parameter 'cs' so that isspace() can be replaced with my_isspace(), whose operation depends on the connection character set. dict_scan_id(): Convert identifier to UTF-8. dict_str_starts_with_keyword(): New extern function, to replace dict_accept() in row_search_for_mysql(). mysql_get_identifier_quote_char(): Replaced with innobase_print_identifier(). ha_innobase::create(): Remove the thd->convert_strin() call. Pass the statement to InnoDB in the connection character set and let InnoDB convert the identifier to UTF-8. * Add max_row_size to dict_table_t. * btr0cur.c btr_copy_externally_stored_field(): Only set the 'offset' variable when needed. * buf0buf.c buf_page_io_complete(): Write to the error log if the page number or the space id o the disk do not match those in memory. Also write to the error log if a page was read from the doublewrite buffer. The doublewrite buffer should be only read by the lower-level function fil_io() at database startup. * dict0dict.c dict_scan_table_name(): Remove fallback to differently encoded name when the table is not found. The encoding is handled at a higher level. * ha_innodb.cc Increment statistic counter in ha_innobase::index_prev() (bug 19542). Add innobase_convert_string wrapper function and a new file ha_prototypes.h. innobase_print_identifier(): Remove TODO comment before calling get_quote_char_for_identifier(). That function apparently assumes the identifier to be encoded in UTF-8. * ibuf0ibuf.c|h ibuf_count_get(), ibuf_counts[], ibuf_count_inited(): Define these only #ifdef UNIV_IBUF_DEBUG. Previously, when compiled without UNIV_IBUF_DEBUG, invoking ibuf_count_get() would crash InnoDB. The function is only being called #ifdef UNIV_IBUF_DEBUG. * innodb.result Adjust the results for changes in the foreign key error messages. * mem0mem.c|h New: mem_heap_dup(), mem_heap_printf(), mem_heap_cat(). * os0file.c Check the page trailers also after writing to disk. This improves chances of diagnosing bug 18886. os_file_check_page_trailers(): New function for checking that the two copies of the LSN stamped on the page match. os_aio_simulated_handle(): Call os_file_check_page_trailers() before and after os_file_write(). * row0mysql.c Move trx_commit_for_mysql(trx) calls before calls to row_mysql_unlock_data_dictionary(trx) (bug 19727). * row0sel.c row_fetch_print(): Handle SQL NULL values without crashing. row_sel_store_mysql_rec(): Remove useless call to rec_get_nth_field when handling an externally stored column. Fetch externally stored fields when using InnoDB's internal SQL parser. Optimize BLOB selects by using prebuilt->blob_heap directly instead of first reading BLOB data to a temporary heap and then copying it to prebuilt->blob_heap. * srv0srv.c srv_master_thread(): Remove unreachable code. * srv0start.c srv_parse_data_file_paths_and_sizes(): Accept lower-case 'm' and 'g' as abbreviations of megabyte and gigabyte (bug 19609). srv_parse_megabytes(): New fuction. * ut0dbg.c|h Implement InnoDB assertions (ut_a and ut_error) with abort() when the code is compiled with GCC 3 or later on other platforms than Windows or Netware. Also disable the variable ut_dbg_stop_threads and the function ut_dbg_stop_thread() i this case, unless UNIV_SYC_DEBUG is defined. This should allow the compiler to generate more compact code for assertions. * ut0list.c|h Add ib_list_create_heap(). mysql-test/r/innodb.result: Applied innodb-5.1-ss594 snapshot. mysql-test/t/innodb.test: Copy the comment from the beginning of the file to the end because MySQL developers continue adding test cases to this file. sql/ha_innodb.cc: Applied innodb-5.1-ss594 snapshot. storage/innobase/CMakeLists.txt: Applied innodb-5.1-ss594 snapshot. storage/innobase/Makefile.am: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0btr.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0cur.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0pcur.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/btr/btr0sea.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/buf/buf0buf.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/buf/buf0flu.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/data/data0type.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0crea.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0dict.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0load.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/dict/dict0mem.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/fil/fil0fil.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ha/hash0hash.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ibuf/ibuf0ibuf.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/data0type.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0dict.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0dict.ic: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/dict0mem.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/fil0fil.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/fsp0fsp.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ibuf0ibuf.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/mem0mem.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0pars.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0sym.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/pars0types.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/rem0rec.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/row0purge.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/row0undo.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/srv0srv.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/sync0rw.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/sync0sync.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/univ.i: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0dbg.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0ut.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/lock/lock0lock.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/log/log0log.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/log/log0recv.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0dbg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0mem.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/mem/mem0pool.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/os/os0file.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/os/os0thread.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/lexyy.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0lex.l: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0pars.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/pars/pars0sym.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0ins.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0mysql.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0purge.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0row.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0sel.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/row/row0upd.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/srv/srv0srv.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/srv/srv0start.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0arr.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0rw.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/sync/sync0sync.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/thr/thr0loc.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0purge.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0rec.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0roll.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0rseg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0sys.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/trx/trx0trx.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/Makefile.am: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0dbg.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0ut.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ha_prototypes.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0list.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0list.ic: Applied innodb-5.1-ss594 snapshot. storage/innobase/include/ut0wqueue.h: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0list.c: Applied innodb-5.1-ss594 snapshot. storage/innobase/ut/ut0wqueue.c: Applied innodb-5.1-ss594 snapshot.
-rw-r--r--mysql-test/r/innodb.result42
-rw-r--r--mysql-test/t/innodb.test13
-rw-r--r--sql/ha_innodb.cc199
-rw-r--r--storage/innobase/CMakeLists.txt2
-rw-r--r--storage/innobase/Makefile.am2
-rw-r--r--storage/innobase/btr/btr0btr.c91
-rw-r--r--storage/innobase/btr/btr0cur.c30
-rw-r--r--storage/innobase/btr/btr0pcur.c3
-rw-r--r--storage/innobase/btr/btr0sea.c3
-rw-r--r--storage/innobase/buf/buf0buf.c48
-rw-r--r--storage/innobase/buf/buf0flu.c2
-rw-r--r--storage/innobase/data/data0type.c33
-rw-r--r--storage/innobase/dict/dict0crea.c6
-rw-r--r--storage/innobase/dict/dict0dict.c432
-rw-r--r--storage/innobase/dict/dict0load.c2
-rw-r--r--storage/innobase/dict/dict0mem.c6
-rw-r--r--storage/innobase/fil/fil0fil.c7
-rw-r--r--storage/innobase/ha/hash0hash.c4
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c29
-rw-r--r--storage/innobase/include/data0type.h10
-rw-r--r--storage/innobase/include/dict0dict.h49
-rw-r--r--storage/innobase/include/dict0dict.ic27
-rw-r--r--storage/innobase/include/dict0mem.h13
-rw-r--r--storage/innobase/include/fil0fil.h16
-rw-r--r--storage/innobase/include/fsp0fsp.h26
-rw-r--r--storage/innobase/include/ha_prototypes.h22
-rw-r--r--storage/innobase/include/ibuf0ibuf.h2
-rw-r--r--storage/innobase/include/mem0mem.h42
-rw-r--r--storage/innobase/include/pars0pars.h29
-rw-r--r--storage/innobase/include/pars0sym.h10
-rw-r--r--storage/innobase/include/pars0types.h1
-rw-r--r--storage/innobase/include/rem0rec.h6
-rw-r--r--storage/innobase/include/row0purge.h4
-rw-r--r--storage/innobase/include/row0undo.h4
-rw-r--r--storage/innobase/include/srv0srv.h3
-rw-r--r--storage/innobase/include/sync0rw.h19
-rw-r--r--storage/innobase/include/sync0sync.h26
-rw-r--r--storage/innobase/include/univ.i8
-rw-r--r--storage/innobase/include/ut0dbg.h27
-rw-r--r--storage/innobase/include/ut0list.h148
-rw-r--r--storage/innobase/include/ut0list.ic23
-rw-r--r--storage/innobase/include/ut0ut.h2
-rw-r--r--storage/innobase/include/ut0wqueue.h60
-rw-r--r--storage/innobase/lock/lock0lock.c9
-rw-r--r--storage/innobase/log/log0log.c9
-rw-r--r--storage/innobase/log/log0recv.c4
-rw-r--r--storage/innobase/mem/mem0dbg.c3
-rw-r--r--storage/innobase/mem/mem0mem.c187
-rw-r--r--storage/innobase/mem/mem0pool.c3
-rw-r--r--storage/innobase/os/os0file.c59
-rw-r--r--storage/innobase/os/os0thread.c2
-rw-r--r--storage/innobase/pars/lexyy.c986
-rw-r--r--storage/innobase/pars/pars0lex.l8
-rw-r--r--storage/innobase/pars/pars0pars.c58
-rw-r--r--storage/innobase/pars/pars0sym.c46
-rw-r--r--storage/innobase/row/row0ins.c30
-rw-r--r--storage/innobase/row/row0mysql.c112
-rw-r--r--storage/innobase/row/row0purge.c2
-rw-r--r--storage/innobase/row/row0row.c6
-rw-r--r--storage/innobase/row/row0sel.c118
-rw-r--r--storage/innobase/row/row0upd.c3
-rw-r--r--storage/innobase/srv/srv0srv.c22
-rw-r--r--storage/innobase/srv/srv0start.c108
-rw-r--r--storage/innobase/sync/sync0arr.c3
-rw-r--r--storage/innobase/sync/sync0rw.c31
-rw-r--r--storage/innobase/sync/sync0sync.c37
-rw-r--r--storage/innobase/thr/thr0loc.c3
-rw-r--r--storage/innobase/trx/trx0purge.c6
-rw-r--r--storage/innobase/trx/trx0rec.c2
-rw-r--r--storage/innobase/trx/trx0roll.c6
-rw-r--r--storage/innobase/trx/trx0rseg.c3
-rw-r--r--storage/innobase/trx/trx0sys.c3
-rw-r--r--storage/innobase/trx/trx0trx.c3
-rw-r--r--storage/innobase/ut/Makefile.am2
-rw-r--r--storage/innobase/ut/ut0dbg.c10
-rw-r--r--storage/innobase/ut/ut0list.c169
-rw-r--r--storage/innobase/ut/ut0ut.c49
-rw-r--r--storage/innobase/ut/ut0wqueue.c92
78 files changed, 2459 insertions, 1266 deletions
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 7ae87e42b8c..b0bc8fb52f2 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1378,9 +1378,9 @@ insert into `t2`values ( 1 ) ;
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
insert into `t3`values ( 1 ) ;
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 42S22: Unknown column 't1.id' in 'where clause'
drop table t3,t2,t1;
@@ -1392,7 +1392,7 @@ foreign key(pid) references t1(id) on delete cascade) engine=innodb;
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
delete from t1 where id=0;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
delete from t1 where id=15;
delete from t1 where id=0;
drop table t1;
@@ -2633,18 +2633,18 @@ v INT,
CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES(2);
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(1);
DELETE FROM t1 WHERE id = 1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
DROP TABLE t1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE t1;
SET FOREIGN_KEY_CHECKS=1;
INSERT INTO t2 VALUES(3);
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
DROP TABLE t2;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2);
@@ -2922,23 +2922,23 @@ create table t4(a int primary key,constraint foreign key(a)references t3(a)) row
insert into t1 values(1);
insert into t3 values(1);
insert into t2 values(2);
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
insert into t4 values(2);
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
insert into t2 values(1);
insert into t4 values(1);
update t1 set a=2;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t2 set a=2;
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
update t3 set a=2;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
update t4 set a=2;
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
truncate t3;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
truncate t2;
truncate t4;
truncate t1;
@@ -2993,7 +2993,7 @@ create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innod
create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
insert into t2 values(0x42);
-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
insert into t2 values(0x41);
select hex(s1) from t2;
hex(s1)
@@ -3003,11 +3003,11 @@ select hex(s1) from t2;
hex(s1)
4100
update t1 set s1=0x12 where a=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x12345678 where a=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x123457 where a=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
update t1 set s1=0x1220 where a=1;
select hex(s1) from t2;
hex(s1)
@@ -3021,11 +3021,11 @@ select hex(s1) from t2;
hex(s1)
4200
delete from t1 where a=1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a=2;
update t2 set s1=0x4120;
delete from t1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
delete from t1 where a!=3;
select a,hex(s1) from t1;
a hex(s1)
@@ -3051,7 +3051,7 @@ hex(s1)
12
delete from t1 where a=1;
delete from t1 where a=2;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
select a,hex(s1) from t1;
a hex(s1)
2 12
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 92e060eed92..5b1b374e487 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -2510,3 +2510,16 @@ BEGIN;
INSERT INTO t1 VALUES (1);
OPTIMIZE TABLE t1;
DROP TABLE t1;
+
+#######################################################################
+# #
+# 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). #
+# #
+#######################################################################
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 0b2f561e8c9..bcc155db221 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -134,6 +134,7 @@ extern "C" {
#include "../storage/innobase/include/fil0fil.h"
#include "../storage/innobase/include/trx0xa.h"
#include "../storage/innobase/include/thr0loc.h"
+#include "../storage/innobase/include/ha_prototypes.h"
}
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
@@ -706,6 +707,61 @@ innobase_get_cset_width(
}
/**********************************************************************
+Converts an identifier to a table name.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+void
+innobase_convert_from_table_id(
+/*===========================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len) /* in: length of 'to', in bytes */
+{
+ uint errors;
+
+ strconvert(current_thd->charset(), from,
+ &my_charset_filename, to, len, &errors);
+}
+
+/**********************************************************************
+Converts an identifier to UTF-8.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+void
+innobase_convert_from_id(
+/*=====================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len) /* in: length of 'to', in bytes */
+{
+ uint errors;
+
+ strconvert(current_thd->charset(), from,
+ system_charset_info, to, len, &errors);
+}
+
+/**********************************************************************
+Removes the filename encoding of a table or database name.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+void
+innobase_convert_from_filename(
+/*===========================*/
+ char* s) /* in: identifier; out: decoded identifier */
+{
+ uint errors;
+
+ strconvert(&my_charset_filename, s,
+ system_charset_info, s, strlen(s), &errors);
+}
+
+/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE that the exact prototype of this function has to be in
@@ -735,6 +791,21 @@ innobase_casedn_str(
my_casedn_str(system_charset_info, a);
}
+/**************************************************************************
+Determines the connection character set.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+struct charset_info_st*
+innobase_get_charset(
+/*=================*/
+ /* out: connection character set */
+ void* mysql_thd) /* in: MySQL thread handle */
+{
+ return(((THD*) mysql_thd)->charset());
+}
+
/*************************************************************************
Creates a temporary file. */
extern "C"
@@ -781,6 +852,25 @@ innobase_mysql_tmpfile(void)
}
/*************************************************************************
+Wrapper around MySQL's copy_and_convert function, see it for
+documentation. */
+extern "C"
+ulint
+innobase_convert_string(
+/*====================*/
+ void* to,
+ ulint to_length,
+ CHARSET_INFO* to_cs,
+ const void* from,
+ ulint from_length,
+ CHARSET_INFO* from_cs,
+ uint* errors)
+{
+ return(copy_and_convert((char*)to, to_length, to_cs,
+ (const char*)from, from_length, from_cs, errors));
+}
+
+/*************************************************************************
Gets the InnoDB transaction handle for a MySQL handler object, creates
an InnoDB transaction struct if the corresponding MySQL thread struct still
lacks one. */
@@ -1115,23 +1205,69 @@ innobase_invalidate_query_cache(
}
/*********************************************************************
-Get the quote character to be used in SQL identifiers.
+Display an SQL identifier.
This definition must match the one in innobase/ut/ut0ut.c! */
extern "C"
-int
-mysql_get_identifier_quote_char(
-/*============================*/
- /* out: quote character to be
- used in SQL identifiers; EOF if none */
+void
+innobase_print_identifier(
+/*======================*/
+ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen)/* in: length of name */
{
+ const char* s = name;
+ char* qname = NULL;
+ int q;
+
+ if (table_id) {
+ /* Decode the table name. The filename_to_tablename()
+ function expects a NUL-terminated string. The input and
+ output strings buffers must not be shared. The function
+ only produces more output when the name contains other
+ characters than [0-9A-Z_a-z]. */
+ char* temp_name = my_malloc(namelen + 1, MYF(MY_WME));
+ uint qnamelen = namelen
+ + (1 + sizeof srv_mysql50_table_name_prefix);
+
+ if (temp_name) {
+ qname = my_malloc(qnamelen, MYF(MY_WME));
+ if (qname) {
+ memcpy(temp_name, name, namelen);
+ temp_name[namelen] = 0;
+ s = qname;
+ namelen = filename_to_tablename(temp_name,
+ qname, qnamelen);
+ }
+ my_free(temp_name, MYF(0));
+ }
+ }
+
if (!trx || !trx->mysql_thd) {
- return(EOF);
+
+ q = '"';
+ } else {
+ q = get_quote_char_for_identifier((THD*) trx->mysql_thd,
+ s, (int) namelen);
+ }
+
+ if (q == EOF) {
+ fwrite(s, 1, namelen, f);
+ } else {
+ const char* e = s + namelen;
+ putc(q, f);
+ while (s < e) {
+ int c = *s++;
+ if (c == q) {
+ putc(c, f);
+ }
+ putc(c, f);
+ }
+ putc(q, f);
}
- return(get_quote_char_for_identifier((THD*) trx->mysql_thd,
- name, (int) namelen));
+
+ my_free(qname, MYF(MY_ALLOW_ZERO_PTR));
}
/**************************************************************************
@@ -1247,6 +1383,24 @@ innobase_init(void)
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
+#ifdef UNIV_DEBUG
+ static const char test_filename[] = "-@";
+ char test_tablename[sizeof test_filename
+ + sizeof srv_mysql50_table_name_prefix];
+ if ((sizeof test_tablename) - 1
+ != filename_to_tablename(test_filename, test_tablename,
+ sizeof test_tablename)
+ || strncmp(test_tablename,
+ srv_mysql50_table_name_prefix,
+ sizeof srv_mysql50_table_name_prefix)
+ || strcmp(test_tablename
+ + sizeof srv_mysql50_table_name_prefix,
+ test_filename)) {
+ sql_print_error("tablename encoding has been changed");
+ goto error;
+ }
+#endif /* UNIV_DEBUG */
+
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
if (innobase_buffer_pool_size > UINT_MAX32) {
@@ -2215,8 +2369,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);
@@ -4132,6 +4285,9 @@ ha_innobase::index_prev(
mysql_byte* buf) /* in/out: buffer for previous row in MySQL
format */
{
+ statistic_increment(current_thd->status_var.ha_read_prev_count,
+ &LOCK_status);
+
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
@@ -4668,7 +4824,7 @@ ha_innobase::create(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -4764,20 +4920,9 @@ ha_innobase::create(
}
}
- if (current_thd->query != NULL) {
- LEX_STRING q;
-
- if (thd->convert_string(&q, system_charset_info,
- current_thd->query,
- current_thd->query_length,
- current_thd->charset())) {
- error = HA_ERR_OUT_OF_MEM;
-
- goto cleanup;
- }
-
+ if (thd->query != NULL) {
error = row_table_add_foreign_constraints(trx,
- q.str, norm_name,
+ thd->query, norm_name,
create_info->options & HA_LEX_CREATE_TMP_TABLE);
error = convert_error_code_to_mysql(error, NULL);
@@ -4797,7 +4942,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);
@@ -4933,7 +5078,7 @@ ha_innobase::delete_table(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index def51873725..8b8c3af6582 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/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/storage/innobase/Makefile.am b/storage/innobase/Makefile.am
index bf41d3dca88..6fdc1621059 100644
--- a/storage/innobase/Makefile.am
+++ b/storage/innobase/Makefile.am
@@ -76,7 +76,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr
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/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \
CMakeLists.txt
noinst_LIBRARIES = libinnobase.a
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index 5e338f97982..ae3e722b513 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -190,6 +190,10 @@ btr_get_prev_user_rec(
|| (mtr_memo_contains(mtr, buf_block_align(prev_page),
MTR_MEMO_PAGE_X_FIX)));
ut_a(page_is_comp(prev_page) == page_is_comp(page));
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
return(page_rec_get_prev(page_get_supremum_rec(prev_page)));
}
@@ -237,6 +241,10 @@ btr_get_next_user_rec(
MTR_MEMO_PAGE_S_FIX))
|| (mtr_memo_contains(mtr, buf_block_align(next_page),
MTR_MEMO_PAGE_X_FIX)));
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(next_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
ut_a(page_is_comp(next_page) == page_is_comp(page));
return(page_rec_get_next(page_get_infimum_rec(next_page)));
@@ -597,9 +605,9 @@ btr_page_get_father_for_rec(
buf_page_print(buf_frame_align(node_ptr));
fputs("InnoDB: Corruption of an index tree: table ", stderr);
- ut_print_name(stderr, NULL, index->table_name);
+ ut_print_name(stderr, NULL, TRUE, index->table_name);
fputs(", index ", stderr);
- ut_print_name(stderr, NULL, index->name);
+ ut_print_name(stderr, NULL, FALSE, index->name);
fprintf(stderr, ",\n"
"InnoDB: father ptr page no %lu, child page no %lu\n",
(ulong)
@@ -1518,6 +1526,10 @@ btr_attach_half_pages(
prev_page = btr_page_get(space, prev_page_no, RW_X_LATCH, mtr);
ut_a(page_is_comp(prev_page) == page_is_comp(page));
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
btr_page_set_next(prev_page, lower_page_no, mtr);
}
@@ -1805,6 +1817,10 @@ btr_level_list_remove(
prev_page = btr_page_get(space, prev_page_no, RW_X_LATCH, mtr);
ut_a(page_is_comp(prev_page) == page_is_comp(page));
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
btr_page_set_next(prev_page, next_page_no, mtr);
}
@@ -1813,6 +1829,10 @@ btr_level_list_remove(
next_page = btr_page_get(space, next_page_no, RW_X_LATCH, mtr);
ut_a(page_is_comp(next_page) == page_is_comp(page));
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(next_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
btr_page_set_prev(next_page, prev_page_no, mtr);
}
@@ -2032,16 +2052,24 @@ btr_compress(
/* Decide the page to which we try to merge and which will inherit
the locks */
- if (left_page_no != FIL_NULL) {
+ is_left = left_page_no != FIL_NULL;
+
+ if (is_left) {
- is_left = TRUE;
merge_page = btr_page_get(space, left_page_no, RW_X_LATCH,
mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(merge_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
} else if (right_page_no != FIL_NULL) {
- is_left = FALSE;
merge_page = btr_page_get(space, right_page_no, RW_X_LATCH,
mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(merge_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
} else {
/* The page is the only one on the level, lift the records
to the father */
@@ -2203,7 +2231,6 @@ btr_discard_page(
ulint left_page_no;
ulint right_page_no;
page_t* merge_page;
- ibool is_left;
page_t* page;
rec_t* node_ptr;
@@ -2223,13 +2250,19 @@ btr_discard_page(
right_page_no = btr_page_get_next(page, mtr);
if (left_page_no != FIL_NULL) {
- is_left = TRUE;
merge_page = btr_page_get(space, left_page_no, RW_X_LATCH,
mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(merge_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
} else if (right_page_no != FIL_NULL) {
- is_left = FALSE;
merge_page = btr_page_get(space, right_page_no, RW_X_LATCH,
mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(merge_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
} else {
btr_discard_only_page_on_level(tree, page, mtr);
@@ -2256,11 +2289,11 @@ btr_discard_page(
/* Remove the page from the level list */
btr_level_list_remove(tree, page, mtr);
- if (is_left) {
+ if (left_page_no != FIL_NULL) {
lock_update_discard(page_get_supremum_rec(merge_page), page);
} else {
lock_update_discard(page_rec_get_next(
- page_get_infimum_rec(merge_page)), page);
+ page_get_infimum_rec(merge_page)), page);
}
/* Free the file page */
@@ -2745,7 +2778,29 @@ loop:
rec_t* right_rec;
right_page = btr_page_get(space, right_page_no, RW_X_LATCH,
&mtr);
- ut_a(page_is_comp(right_page) == page_is_comp(page));
+ if (UNIV_UNLIKELY(btr_page_get_prev(right_page, &mtr)
+ != buf_frame_get_page_no(page))) {
+ btr_validate_report2(index, level, page, right_page);
+ fputs("InnoDB: broken FIL_PAGE_NEXT"
+ " or FIL_PAGE_PREV links\n", stderr);
+ buf_page_print(page);
+ buf_page_print(right_page);
+
+ ret = FALSE;
+ }
+
+ if (UNIV_UNLIKELY(page_is_comp(right_page)
+ != page_is_comp(page))) {
+ btr_validate_report2(index, level, page, right_page);
+ fputs("InnoDB: 'compact' flag mismatch\n", stderr);
+ buf_page_print(page);
+ buf_page_print(right_page);
+
+ ret = FALSE;
+
+ goto node_ptr_fails;
+ }
+
rec = page_rec_get_prev(page_get_supremum_rec(page));
right_rec = page_rec_get_next(
page_get_infimum_rec(right_page));
@@ -2753,8 +2808,8 @@ loop:
offsets, ULINT_UNDEFINED, &heap);
offsets2 = rec_get_offsets(right_rec, index,
offsets2, ULINT_UNDEFINED, &heap);
- if (cmp_rec_rec(rec, right_rec, offsets, offsets2, index)
- >= 0) {
+ if (UNIV_UNLIKELY(cmp_rec_rec(rec, right_rec,
+ offsets, offsets2, index) >= 0)) {
btr_validate_report2(index, level, page, right_page);
@@ -2869,10 +2924,7 @@ loop:
ut_a(node_ptr == page_rec_get_prev(
page_get_supremum_rec(father_page)));
ut_a(btr_page_get_next(father_page, &mtr) == FIL_NULL);
- }
-
- if (right_page_no != FIL_NULL) {
-
+ } else {
right_node_ptr = btr_page_get_father_node_ptr(tree,
right_page, &mtr);
if (page_rec_get_next(node_ptr) !=
@@ -2934,14 +2986,15 @@ loop:
}
node_ptr_fails:
+ /* Commit the mini-transaction to release the latch on 'page'.
+ Re-acquire the latch on right_page, which will become 'page'
+ on the next loop. The page has already been checked. */
mtr_commit(&mtr);
if (right_page_no != FIL_NULL) {
- ulint comp = page_is_comp(page);
mtr_start(&mtr);
page = btr_page_get(space, right_page_no, RW_X_LATCH, &mtr);
- ut_a(page_is_comp(page) == comp);
goto loop;
}
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index deba3e23487..74def379058 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -157,6 +157,10 @@ btr_cur_latch_leaves(
if (left_page_no != FIL_NULL) {
get_page = btr_page_get(space, left_page_no,
RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(get_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
ut_a(page_is_comp(get_page) == page_is_comp(page));
buf_block_align(get_page)->check_index_page_at_flush =
TRUE;
@@ -171,6 +175,10 @@ btr_cur_latch_leaves(
if (right_page_no != FIL_NULL) {
get_page = btr_page_get(space, right_page_no,
RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(get_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
buf_block_align(get_page)->check_index_page_at_flush =
TRUE;
}
@@ -183,6 +191,10 @@ btr_cur_latch_leaves(
if (left_page_no != FIL_NULL) {
cursor->left_page = btr_page_get(space, left_page_no,
RW_S_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(cursor->left_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
ut_a(page_is_comp(cursor->left_page) ==
page_is_comp(page));
buf_block_align(
@@ -201,6 +213,10 @@ btr_cur_latch_leaves(
if (left_page_no != FIL_NULL) {
cursor->left_page = btr_page_get(space, left_page_no,
RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(cursor->left_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
ut_a(page_is_comp(cursor->left_page) ==
page_is_comp(page));
buf_block_align(
@@ -1731,6 +1747,10 @@ btr_cur_pess_upd_restore_supremum(
ut_ad(prev_page_no != FIL_NULL);
prev_page = buf_page_get_with_no_latch(space, prev_page_no, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
/* We must already have an x-latch to prev_page! */
ut_ad(mtr_memo_contains(mtr, buf_block_align(prev_page),
@@ -3771,11 +3791,6 @@ btr_copy_externally_stored_field(
page_no = btr_blob_get_next_page_no(blob_header);
- /* On other BLOB pages except the first the BLOB header
- always is at the page data start: */
-
- offset = FIL_PAGE_DATA;
-
mtr_commit(&mtr);
if (page_no == FIL_NULL) {
@@ -3786,6 +3801,11 @@ btr_copy_externally_stored_field(
return(buf);
}
+ /* On other BLOB pages except the first the BLOB header
+ always is at the page data start: */
+
+ offset = FIL_PAGE_DATA;
+
ut_a(copied_len < local_len + extern_len);
}
}
diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
index 85a6577bafb..c739930ce04 100644
--- a/storage/innobase/btr/btr0pcur.c
+++ b/storage/innobase/btr/btr0pcur.c
@@ -397,6 +397,9 @@ btr_pcur_move_to_next_page(
ut_ad(next_page_no != FIL_NULL);
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(next_page, mtr) == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
ut_a(page_is_comp(next_page) == page_is_comp(page));
buf_block_align(next_page)->check_index_page_at_flush = TRUE;
diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
index be7bb7c421f..2f2102379ab 100644
--- a/storage/innobase/btr/btr0sea.c
+++ b/storage/innobase/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/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 197b38149fe..5f3e4a9ea50 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -524,12 +524,11 @@ buf_block_init(
block->n_pointers = 0;
- 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 */
}
@@ -572,8 +571,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));
@@ -1856,7 +1854,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);
@@ -1866,18 +1863,36 @@ buf_page_io_complete(
if (io_type == BUF_IO_READ) {
/* 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 != 0
- && !trx_doublewrite_page_inside(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
to the 4 first bytes of the page end lsn field */
@@ -2233,7 +2248,8 @@ buf_get_latched_pages_number(void)
}
mutex_exit(&(buf_pool->mutex));
- return fixed_pages_number;
+
+ return(fixed_pages_number);
}
/*************************************************************************
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index 7b02e353b76..9bfbeb1b456 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -26,7 +26,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/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c
index 2f36e7250fc..feac6739101 100644
--- a/storage/innobase/data/data0type.c
+++ b/storage/innobase/data/data0type.c
@@ -293,3 +293,36 @@ dtype_print(
fprintf(stderr, " len %lu prec %lu", (ulong) len, (ulong) type->prec);
}
+
+/***************************************************************************
+Returns the maximum size of a data type. Note: types in system tables may be
+incomplete and return incorrect information. */
+UNIV_INLINE
+ulint
+dtype_get_max_size(
+/*===============*/
+ /* out: maximum size (ULINT_MAX for
+ unbounded types) */
+ const dtype_t* type) /* in: type */
+{
+ switch (type->mtype) {
+ case DATA_SYS:
+ case DATA_CHAR:
+ case DATA_FIXBINARY:
+ case DATA_INT:
+ case DATA_FLOAT:
+ case DATA_DOUBLE:
+ case DATA_MYSQL:
+ case DATA_VARCHAR:
+ case DATA_BINARY:
+ case DATA_DECIMAL:
+ case DATA_VARMYSQL:
+ return(type->len);
+ case DATA_BLOB:
+ return(ULINT_MAX);
+ default:
+ ut_error;
+ }
+
+ return(ULINT_MAX);
+}
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
index 4233cb05773..a41c90261d8 100644
--- a/storage/innobase/dict/dict0crea.c
+++ b/storage/innobase/dict/dict0crea.c
@@ -1250,9 +1250,9 @@ dict_foreign_eval_sql(
ut_print_timestamp(ef);
fputs(" Error in foreign key constraint creation for table ",
ef);
- ut_print_name(ef, trx, table->name);
+ ut_print_name(ef, trx, TRUE, table->name);
fputs(".\nA foreign key constraint of name ", ef);
- ut_print_name(ef, trx, foreign->id);
+ ut_print_name(ef, trx, FALSE, foreign->id);
fputs("\nalready exists."
" (Note that internally InnoDB adds 'databasename/'\n"
"in front of the user-defined constraint name).\n",
@@ -1280,7 +1280,7 @@ dict_foreign_eval_sql(
ut_print_timestamp(ef);
fputs(" Internal error in foreign key constraint creation"
" for table ", ef);
- ut_print_name(ef, trx, table->name);
+ ut_print_name(ef, trx, TRUE, table->name);
fputs(".\n"
"See the MySQL .err log in the datadir for more information.\n", ef);
mutex_exit(&dict_foreign_err_mutex);
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 74dffd4c906..8fe3dac4c56 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -26,6 +26,9 @@ Created 1/8/1996 Heikki Tuuri
#include "pars0sym.h"
#include "que0que.h"
#include "rem0cmp.h"
+#ifndef UNIV_HOTBACKUP
+# include "m_ctype.h" /* my_isspace() */
+#endif /* !UNIV_HOTBACKUP */
dict_sys_t* dict_sys = NULL; /* the dictionary system */
@@ -55,6 +58,42 @@ static char dict_ibfk[] = "_ibfk_";
#ifndef UNIV_HOTBACKUP
/**********************************************************************
+Converts an identifier to a table name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_table_id(
+/*===========================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len); /* in: length of 'to', in bytes;
+ should be at least 5 * strlen(to) + 1 */
+/**********************************************************************
+Converts an identifier to UTF-8.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_id(
+/*=====================*/
+ char* to, /* out: converted identifier */
+ const char* from, /* in: identifier to convert */
+ ulint len); /* in: length of 'to', in bytes;
+ should be at least 3 * strlen(to) + 1 */
+/**********************************************************************
+Removes the filename encoding of a table or database name.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+extern
+void
+innobase_convert_from_filename(
+/*===========================*/
+ char* s); /* in: identifier; out: decoded identifier */
+/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
@@ -77,6 +116,17 @@ void
innobase_casedn_str(
/*================*/
char* a); /* in/out: string to put in lower case */
+
+/**************************************************************************
+Determines the connection character set.
+
+NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
+this function, you MUST change also the prototype here! */
+struct charset_info_st*
+innobase_get_charset(
+/*=================*/
+ /* out: connection character set */
+ void* mysql_thd); /* in: MySQL thread handle */
#endif /* !UNIV_HOTBACKUP */
/**************************************************************************
@@ -607,7 +657,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(
@@ -629,12 +679,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));
@@ -716,8 +766,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 *
@@ -732,32 +781,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);
@@ -781,13 +826,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);
@@ -819,6 +861,7 @@ dict_table_add_to_cache(
ulint fold;
ulint id_fold;
ulint i;
+ ulint row_len;
ut_ad(table);
#ifdef UNIV_SYNC_DEBUG
@@ -866,6 +909,24 @@ dict_table_add_to_cache(
#error "DATA_N_SYS_COLS != 4"
#endif
+ row_len = 0;
+ for (i = 0; i < table->n_def; i++) {
+ ulint col_len = dtype_get_max_size(
+ dict_col_get_type(dict_table_get_nth_col(table, i)));
+
+ /* If we have a single unbounded field, or several gigantic
+ fields, mark the maximum row size as ULINT_MAX. */
+ if (ut_max(col_len, row_len) >= (ULINT_MAX / 2)) {
+ row_len = ULINT_MAX;
+
+ break;
+ }
+
+ row_len += col_len;
+ }
+
+ table->max_row_size = row_len;
+
/* Look for a table with the same name: error if such exists */
{
dict_table_t* table2;
@@ -897,10 +958,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(); */
}
/**************************************************************************
@@ -1266,38 +1324,6 @@ dict_table_remove_from_cache(
}
/**************************************************************************
-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
void
@@ -1443,6 +1469,7 @@ dict_index_add_to_cache(
ut_ad(mem_heap_validate(index->heap));
+#ifdef UNIV_DEBUG
{
dict_index_t* index2;
index2 = UT_LIST_GET_FIRST(table->indexes);
@@ -1452,10 +1479,11 @@ dict_index_add_to_cache(
index2 = UT_LIST_GET_NEXT(indexes, index2);
}
-
- ut_a(UT_LIST_GET_LEN(table->indexes) == 0
- || (index->type & DICT_CLUSTERED) == 0);
}
+#endif /* UNIV_DEBUG */
+
+ ut_a(!(index->type & DICT_CLUSTERED)
+ || UT_LIST_GET_LEN(table->indexes) == 0);
success = dict_index_find_cols(table, index);
@@ -1526,10 +1554,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);
@@ -2091,6 +2116,7 @@ dict_foreign_find(
return(NULL);
}
+#ifndef UNIV_HOTBACKUP
/*************************************************************************
Tries to find an index whose first fields are the columns in the array,
in the same order. */
@@ -2108,7 +2134,6 @@ dict_foreign_find_index(
only has an effect if types_idx !=
NULL. */
{
-#ifndef UNIV_HOTBACKUP
dict_index_t* index;
const char* col_name;
ulint i;
@@ -2154,13 +2179,6 @@ dict_foreign_find_index(
}
return(NULL);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(NULL);
-#endif /* UNIV_HOTBACKUP */
}
/**************************************************************************
@@ -2196,7 +2214,7 @@ dict_foreign_error_report(
putc('\n', file);
if (fk->foreign_index) {
fputs("The index in the foreign key in table is ", file);
- ut_print_name(file, NULL, fk->foreign_index->name);
+ ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
fputs(
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
"for correct foreign key definition.\n",
@@ -2359,12 +2377,13 @@ dict_scan_to(
/*************************************************************************
Accepts a specified string. Comparisons are case-insensitive. */
-
+static
const char*
dict_accept(
/*========*/
/* out: if string was accepted, the pointer
is moved after that, else ptr is returned */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scan from this */
const char* string, /* in: accept only this string as the next
non-whitespace string */
@@ -2375,7 +2394,7 @@ dict_accept(
*success = FALSE;
- while (isspace(*ptr)) {
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
@@ -2400,12 +2419,15 @@ const char*
dict_scan_id(
/*=========*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
mem_heap_t* heap, /* in: heap where to allocate the id
(NULL=id will not be allocated, but it
will point to string near ptr) */
const char** id, /* out,own: the id; NULL if no id was
scannable */
+ ibool table_id,/* in: TRUE=convert the allocated id
+ as a table name; FALSE=convert to UTF-8 */
ibool accept_also_dot)
/* in: TRUE if also a dot can appear in a
non-quoted id; in a quoted id it can appear
@@ -2414,13 +2436,12 @@ dict_scan_id(
char quote = '\0';
ulint len = 0;
const char* s;
- char* d;
- ulint id_len;
- byte* b;
+ char* str;
+ char* dst;
*id = NULL;
- while (isspace(*ptr)) {
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
@@ -2451,7 +2472,7 @@ dict_scan_id(
len++;
}
} else {
- while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'
+ while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
&& (accept_also_dot || *ptr != '.')
&& *ptr != ',' && *ptr != '\0') {
@@ -2461,43 +2482,50 @@ dict_scan_id(
len = ptr - s;
}
- if (quote && heap) {
- *id = d = mem_heap_alloc(heap, len + 1);
+ if (UNIV_UNLIKELY(!heap)) {
+ /* no heap given: id will point to source string */
+ *id = s;
+ return(ptr);
+ }
+
+ if (quote) {
+ char* d;
+ str = d = mem_heap_alloc(heap, len + 1);
while (len--) {
if ((*d++ = *s++) == quote) {
s++;
}
}
*d++ = 0;
- ut_a(*s == quote);
- ut_a(s + 1 == ptr);
- } else if (heap) {
- *id = mem_heap_strdupl(heap, s, len);
+ len = d - str;
+ ut_ad(*s == quote);
+ ut_ad(s + 1 == ptr);
} else {
- /* no heap given: id will point to source string */
- *id = s;
- }
-
- if (heap && !quote) {
- /* EMS MySQL Manager sometimes adds characters 0xA0 (in
- latin1, a 'non-breakable space') to the end of a table name.
- But isspace(0xA0) is not true, which confuses our foreign key
- parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
- and 0xA0 are at the end of the string.
-
- TODO: we should lex the string using thd->charset_info, and
- my_isspace(). Only after that, convert id names to UTF-8. */
-
- b = (byte*)(*id);
- id_len = strlen((char*) b);
-
- if (id_len >= 3 && b[id_len - 1] == 0xA0
- && b[id_len - 2] == 0xC2) {
-
- /* Strip the 2 last bytes */
+ str = mem_heap_strdupl(heap, s, len);
+ }
+
+ if (!table_id) {
+convert_id:
+ /* Convert the identifier from connection character set
+ to UTF-8. */
+ len = 3 * len + 1;
+ *id = dst = mem_heap_alloc(heap, len);
+
+ innobase_convert_from_id(dst, str, len);
+ } else if (!strncmp(str, srv_mysql50_table_name_prefix,
+ sizeof srv_mysql50_table_name_prefix)) {
+ /* This is a pre-5.1 table name
+ containing chars other than [A-Za-z0-9].
+ Discard the prefix and use raw UTF-8 encoding. */
+ str += sizeof srv_mysql50_table_name_prefix;
+ len -= sizeof srv_mysql50_table_name_prefix;
+ goto convert_id;
+ } else {
+ /* Encode using filename-safe characters. */
+ len = 5 * len + 1;
+ *id = dst = mem_heap_alloc(heap, len);
- b[id_len - 2] = '\0';
- }
+ innobase_convert_from_table_id(dst, str, len);
}
return(ptr);
@@ -2510,6 +2538,7 @@ const char*
dict_scan_col(
/*==========*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
ibool* success,/* out: TRUE if success */
dict_table_t* table, /* in: table in which the column is */
@@ -2518,13 +2547,12 @@ dict_scan_col(
const char** name) /* out,own: the column name; NULL if no name
was scannable */
{
-#ifndef UNIV_HOTBACKUP
dict_col_t* col;
ulint i;
*success = FALSE;
- ptr = dict_scan_id(ptr, heap, name, TRUE);
+ ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
if (*name == NULL) {
@@ -2552,13 +2580,6 @@ dict_scan_col(
}
return(ptr);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(NULL);
-#endif /* UNIV_HOTBACKUP */
}
/*************************************************************************
@@ -2568,6 +2589,7 @@ const char*
dict_scan_table_name(
/*=================*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
dict_table_t** table, /* out: table object or NULL */
const char* name, /* in: foreign key table name */
@@ -2576,7 +2598,6 @@ dict_scan_table_name(
const char** ref_name)/* out,own: the table name;
NULL if no name was scannable */
{
-#ifndef UNIV_HOTBACKUP
const char* database_name = NULL;
ulint database_name_len = 0;
const char* table_name = NULL;
@@ -2587,7 +2608,7 @@ dict_scan_table_name(
*success = FALSE;
*table = NULL;
- ptr = dict_scan_id(ptr, heap, &scan_name, FALSE);
+ ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE);
if (scan_name == NULL) {
@@ -2602,7 +2623,7 @@ dict_scan_table_name(
database_name = scan_name;
database_name_len = strlen(database_name);
- ptr = dict_scan_id(ptr, heap, &table_name, FALSE);
+ ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE);
if (table_name == NULL) {
@@ -2658,13 +2679,6 @@ dict_scan_table_name(
*table = dict_table_get_low(ref);
return(ptr);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(NULL);
-#endif /* UNIV_HOTBACKUP */
}
/*************************************************************************
@@ -2674,6 +2688,7 @@ const char*
dict_skip_word(
/*===========*/
/* out: scanned to */
+ struct charset_info_st* cs,/* in: the character set of ptr */
const char* ptr, /* in: scanned to */
ibool* success)/* out: TRUE if success, FALSE if just spaces
left in string or a syntax error */
@@ -2682,7 +2697,7 @@ dict_skip_word(
*success = FALSE;
- ptr = dict_scan_id(ptr, NULL, &start, TRUE);
+ ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
if (start) {
*success = TRUE;
@@ -2860,6 +2875,7 @@ dict_create_foreign_constraints_low(
/* out: error code or DB_SUCCESS */
trx_t* trx, /* in: transaction */
mem_heap_t* heap, /* in: memory heap */
+ struct charset_info_st* cs,/* in: the character set of sql_string */
const char* sql_string,
/* in: CREATE TABLE or ALTER TABLE statement
where foreign keys are declared like:
@@ -2917,14 +2933,14 @@ dict_create_foreign_constraints_low(
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
- ptr = dict_accept(ptr, "ALTER", &success);
+ ptr = dict_accept(cs, ptr, "ALTER", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "TABLE", &success);
+ ptr = dict_accept(cs, ptr, "TABLE", &success);
if (!success) {
@@ -2933,7 +2949,7 @@ dict_create_foreign_constraints_low(
/* We are doing an ALTER TABLE: scan the table name we are altering */
- ptr = dict_scan_table_name(ptr, &table_to_alter, name,
+ ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
&success, heap, &referenced_table_name);
if (!success) {
fprintf(stderr,
@@ -2973,21 +2989,22 @@ loop:
of the constraint to system tables. */
ptr = ptr1;
- ptr = dict_accept(ptr, "CONSTRAINT", &success);
+ ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
ut_a(success);
- if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') {
+ if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
goto loop;
}
- while (isspace(*ptr)) {
+ while (my_isspace(cs, *ptr)) {
ptr++;
}
/* read constraint name unless got "CONSTRAINT FOREIGN" */
if (ptr != ptr2) {
- ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE);
+ ptr = dict_scan_id(cs, ptr, heap,
+ &constraint_name, FALSE, FALSE);
}
} else {
ptr = ptr2;
@@ -3002,7 +3019,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);
}
/**********************************************************/
@@ -3016,28 +3034,28 @@ loop:
start_of_latest_foreign = ptr;
- ptr = dict_accept(ptr, "FOREIGN", &success);
+ ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) {
goto loop;
}
- if (!isspace(*ptr)) {
+ if (!my_isspace(cs, *ptr)) {
goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
/* MySQL allows also an index id before the '('; we
skip it */
- ptr = dict_skip_word(ptr, &success);
+ ptr = dict_skip_word(cs, ptr, &success);
if (!success) {
dict_foreign_report_syntax_err(name,
@@ -3046,7 +3064,7 @@ loop:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
/* We do not flag a syntax error here because in an
@@ -3061,7 +3079,7 @@ loop:
/* Scan the columns in the first list */
col_loop1:
ut_a(i < (sizeof column_names) / sizeof *column_names);
- ptr = dict_scan_col(ptr, &success, table, columns + i,
+ ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
heap, column_names + i);
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
@@ -3075,13 +3093,13 @@ col_loop1:
i++;
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop1;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(cs, ptr, ")", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
@@ -3098,7 +3116,7 @@ col_loop1:
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fputs("There is no index in table ", ef);
- ut_print_name(ef, NULL, name);
+ ut_print_name(ef, NULL, TRUE, name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
@@ -3108,9 +3126,9 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "REFERENCES", &success);
+ ptr = dict_accept(cs, ptr, "REFERENCES", &success);
- if (!success || !isspace(*ptr)) {
+ if (!success || !my_isspace(cs, *ptr)) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3150,7 +3168,7 @@ col_loop1:
mem_heap_strdup(foreign->heap, columns[i]->name);
}
- ptr = dict_scan_table_name(ptr, &referenced_table, name,
+ ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
&success, heap, &referenced_table_name);
/* Note that referenced_table can be NULL if the user has suppressed
@@ -3169,7 +3187,7 @@ col_loop1:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -3182,7 +3200,7 @@ col_loop1:
i = 0;
col_loop2:
- ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
+ ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
heap, column_names + i);
i++;
@@ -3199,13 +3217,13 @@ col_loop2:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop2;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(cs, ptr, ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_free(foreign);
@@ -3221,17 +3239,17 @@ col_loop2:
scan_on_conditions:
/* Loop here as long as we can find ON ... conditions */
- ptr = dict_accept(ptr, "ON", &success);
+ ptr = dict_accept(cs, ptr, "ON", &success);
if (!success) {
goto try_find_index;
}
- ptr = dict_accept(ptr, "DELETE", &success);
+ ptr = dict_accept(cs, ptr, "DELETE", &success);
if (!success) {
- ptr = dict_accept(ptr, "UPDATE", &success);
+ ptr = dict_accept(cs, ptr, "UPDATE", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -3248,13 +3266,13 @@ scan_on_conditions:
n_on_deletes++;
}
- ptr = dict_accept(ptr, "RESTRICT", &success);
+ ptr = dict_accept(cs, ptr, "RESTRICT", &success);
if (success) {
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "CASCADE", &success);
+ ptr = dict_accept(cs, ptr, "CASCADE", &success);
if (success) {
if (is_on_delete) {
@@ -3266,10 +3284,10 @@ scan_on_conditions:
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "NO", &success);
+ ptr = dict_accept(cs, ptr, "NO", &success);
if (success) {
- ptr = dict_accept(ptr, "ACTION", &success);
+ ptr = dict_accept(cs, ptr, "ACTION", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -3288,7 +3306,7 @@ scan_on_conditions:
goto scan_on_conditions;
}
- ptr = dict_accept(ptr, "SET", &success);
+ ptr = dict_accept(cs, ptr, "SET", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -3297,7 +3315,7 @@ scan_on_conditions:
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "NULL", &success);
+ ptr = dict_accept(cs, ptr, "NULL", &success);
if (!success) {
dict_foreign_free(foreign);
@@ -3407,6 +3425,25 @@ try_find_index:
goto loop;
}
+/**************************************************************************
+Determines whether a string starts with the specified keyword. */
+
+ibool
+dict_str_starts_with_keyword(
+/*=========================*/
+ /* out: TRUE if str starts
+ with keyword */
+ void* mysql_thd, /* in: MySQL thread handle */
+ const char* str, /* in: string to scan for keyword */
+ const char* keyword) /* in: keyword to look for */
+{
+ struct charset_info_st* cs = innobase_get_charset(mysql_thd);
+ ibool success;
+
+ dict_accept(cs, str, keyword, &success);
+ return(success);
+}
+
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
@@ -3434,15 +3471,18 @@ dict_create_foreign_constraints(
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
- char* str;
- ulint err;
- mem_heap_t* heap;
+ char* str;
+ ulint err;
+ mem_heap_t* heap;
+
+ ut_a(trx && trx->mysql_thd);
str = dict_strip_comments(sql_string);
heap = mem_heap_create(10000);
- err = dict_create_foreign_constraints_low(trx, heap, str, name,
- reject_fks);
+ err = dict_create_foreign_constraints_low(trx, heap,
+ innobase_get_charset(trx->mysql_thd),
+ str, name, reject_fks);
mem_heap_free(heap);
mem_free(str);
@@ -3469,12 +3509,17 @@ dict_foreign_parse_drop_constraints(
const char*** constraints_to_drop) /* out: id's of the
constraints to drop */
{
- dict_foreign_t* foreign;
- ibool success;
- char* str;
- const char* ptr;
- const char* id;
- FILE* ef = dict_foreign_err_file;
+ dict_foreign_t* foreign;
+ ibool success;
+ char* str;
+ const char* ptr;
+ const char* id;
+ FILE* ef = dict_foreign_err_file;
+ struct charset_info_st* cs;
+
+ ut_a(trx && trx->mysql_thd);
+
+ cs = innobase_get_charset(trx->mysql_thd);
*n = 0;
@@ -3495,28 +3540,28 @@ loop:
return(DB_SUCCESS);
}
- ptr = dict_accept(ptr, "DROP", &success);
+ ptr = dict_accept(cs, ptr, "DROP", &success);
- if (!isspace(*ptr)) {
+ if (!my_isspace(cs, *ptr)) {
goto loop;
}
- ptr = dict_accept(ptr, "FOREIGN", &success);
+ ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
goto syntax_error;
}
- ptr = dict_scan_id(ptr, heap, &id, TRUE);
+ ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
if (id == NULL) {
@@ -3549,12 +3594,12 @@ loop:
ut_print_timestamp(ef);
fputs(
" Error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, NULL, table->name);
+ ut_print_name(ef, NULL, TRUE, table->name);
fputs(",\n"
"in SQL command\n", ef);
fputs(str, ef);
fputs("\nCannot find a constraint with the given id ", ef);
- ut_print_name(ef, NULL, id);
+ ut_print_name(ef, NULL, FALSE, id);
fputs(".\n", ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -3571,7 +3616,7 @@ syntax_error:
ut_print_timestamp(ef);
fputs(
" Syntax error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, NULL, table->name);
+ ut_print_name(ef, NULL, TRUE, table->name);
fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex);
@@ -3580,6 +3625,7 @@ syntax_error:
return(DB_CANNOT_DROP_CONSTRAINT);
}
+#endif /* UNIV_HOTBACKUP */
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
@@ -3653,9 +3699,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);
}
@@ -4232,11 +4276,11 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(" CONSTRAINT ", file);
- ut_print_name(file, trx, stripped_id);
+ ut_print_name(file, trx, FALSE, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
- ut_print_name(file, trx, foreign->foreign_col_names[i]);
+ ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4249,7 +4293,7 @@ dict_print_info_on_foreign_key_in_create_format(
if (dict_tables_have_same_db(foreign->foreign_table_name,
foreign->referenced_table_name)) {
/* Do not print the database name of the referenced table */
- ut_print_name(file, trx, dict_remove_db_name(
+ ut_print_name(file, trx, TRUE, dict_remove_db_name(
foreign->referenced_table_name));
} else {
/* Look for the '/' in the table name */
@@ -4259,9 +4303,10 @@ dict_print_info_on_foreign_key_in_create_format(
i++;
}
- ut_print_namel(file, trx, foreign->referenced_table_name, i);
+ ut_print_namel(file, trx, TRUE,
+ foreign->referenced_table_name, i);
putc('.', file);
- ut_print_name(file, trx,
+ ut_print_name(file, trx, TRUE,
foreign->referenced_table_name + i + 1);
}
@@ -4269,7 +4314,8 @@ dict_print_info_on_foreign_key_in_create_format(
putc('(', file);
for (i = 0;;) {
- ut_print_name(file, trx, foreign->referenced_col_names[i]);
+ ut_print_name(file, trx, FALSE,
+ foreign->referenced_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4343,12 +4389,12 @@ dict_print_info_on_foreign_keys(
putc(' ', file);
}
- ut_print_name(file, trx,
+ ut_print_name(file, trx, FALSE,
foreign->foreign_col_names[i]);
}
fputs(") REFER ", file);
- ut_print_name(file, trx,
+ ut_print_name(file, trx, TRUE,
foreign->referenced_table_name);
putc('(', file);
@@ -4356,7 +4402,7 @@ dict_print_info_on_foreign_keys(
if (i) {
putc(' ', file);
}
- ut_print_name(file, trx,
+ ut_print_name(file, trx, FALSE,
foreign->referenced_col_names[i]);
}
@@ -4403,7 +4449,7 @@ dict_index_name_print(
const dict_index_t* index) /* in: index to print */
{
fputs("index ", file);
- ut_print_name(file, trx, index->name);
+ ut_print_name(file, trx, FALSE, index->name);
fputs(" of table ", file);
- ut_print_name(file, trx, index->table_name);
+ ut_print_name(file, trx, TRUE, index->table_name);
}
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index ccf4b47c284..58900d85f67 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -184,7 +184,7 @@ loop:
if (table == NULL) {
fputs("InnoDB: Failed to load table ", stderr);
- ut_print_namel(stderr, NULL, (char*) field, len);
+ ut_print_namel(stderr, NULL, TRUE, (char*) field, len);
putc('\n', stderr);
} else {
/* The table definition was corrupt if there
diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
index fe21890adc8..42bf39078d1 100644
--- a/storage/innobase/dict/dict0mem.c
+++ b/storage/innobase/dict/dict0mem.c
@@ -58,7 +58,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;
@@ -83,8 +82,9 @@ dict_mem_table_create(
table->stat_modified_counter = 0;
- mutex_create(&(table->autoinc_mutex));
- mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX);
+ table->max_row_size = 0;
+
+ mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE;
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 7418420628e..b2935a119a5 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -1050,8 +1050,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);
@@ -1295,9 +1294,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/storage/innobase/ha/hash0hash.c b/storage/innobase/ha/hash0hash.c
index 659aeb815d8..6084a19fa27 100644
--- a/storage/innobase/ha/hash0hash.c
+++ b/storage/innobase/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/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 3263a0efd5b..369fbd61c04 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/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_set_level(&ibuf_pessimistic_insert_mutex,
- SYNC_IBUF_PESS_INSERT_MUTEX);
- mutex_create(&ibuf_mutex);
+ mutex_create(&ibuf_pessimistic_insert_mutex,
+ SYNC_IBUF_PESS_INSERT_MUTEX);
- mutex_set_level(&ibuf_mutex, SYNC_IBUF_MUTEX);
+ mutex_create(&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;
}
/**********************************************************************
@@ -2348,6 +2345,10 @@ ibuf_get_volume_buffered(
}
prev_page = buf_page_get(0, prev_page_no, RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(prev_page, SYNC_TREE_NODE);
@@ -2411,6 +2412,10 @@ count_later:
}
next_page = buf_page_get(0, next_page_no, RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(next_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(next_page, SYNC_TREE_NODE);
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index d7c9dcb45a2..1c998c8dc56 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -330,6 +330,16 @@ dtype_get_min_size(
/* out: minimum size */
const dtype_t* type); /* in: type */
/***************************************************************************
+Returns the maximum size of a data type. Note: types in system tables may be
+incomplete and return incorrect information. */
+UNIV_INLINE
+ulint
+dtype_get_max_size(
+/*===============*/
+ /* out: maximum size (ULINT_MAX for
+ unbounded types) */
+ const dtype_t* type); /* in: type */
+/***************************************************************************
Returns a stored SQL NULL size for a type. For fixed length types it is
the fixed length of the type, otherwise 0. */
UNIV_INLINE
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 39cde5bfb55..c27ff715986 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -44,18 +44,6 @@ dict_get_db_name_len(
/* out: database name length */
const char* name); /* in: table name in the form
dbname '/' tablename */
-/*************************************************************************
-Accepts a specified string. Comparisons are case-insensitive. */
-
-const char*
-dict_accept(
-/*========*/
- /* out: if string was accepted, the pointer
- is moved after that, else ptr is returned */
- const char* ptr, /* in: scan from this */
- const char* string, /* in: accept only this string as the next
- non-whitespace string */
- ibool* success);/* out: TRUE if accepted */
/************************************************************************
Decrements the count of open MySQL handles to a table. */
@@ -219,6 +207,17 @@ dict_table_referenced_by_foreign_key(
/* out: TRUE if table is referenced by a
foreign key */
dict_table_t* table); /* in: InnoDB table */
+/**************************************************************************
+Determines whether a string starts with the specified keyword. */
+
+ibool
+dict_str_starts_with_keyword(
+/*=========================*/
+ /* out: TRUE if str starts
+ with keyword */
+ void* mysql_thd, /* in: MySQL thread handle */
+ const char* str, /* in: string to scan for keyword */
+ const char* keyword); /* in: keyword to look for */
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
@@ -265,17 +264,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 +283,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 +294,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/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 0b5a23e9380..c65fdde81e9 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -545,14 +545,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;
@@ -560,7 +559,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);
@@ -571,33 +569,12 @@ 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
dict_index_t*
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 0135ba3874d..427991180f6 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -169,10 +169,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 */
@@ -315,9 +311,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
@@ -348,6 +341,12 @@ struct dict_table_struct{
had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
locks; /* list of locks on the table */
+ ulint max_row_size;
+ /* maximum size of a single row in the
+ table, not guaranteed to be especially
+ accurate. it's ULINT_MAX if there are
+ unbounded variable-width fields. initialized
+ in dict_table_add_to_cache. */
/*----------------------*/
ibool does_not_fit_in_memory;
/* this field is used to specify in simulations
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 53bb496c190..6b8fd4b03d5 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -57,9 +57,21 @@ extern fil_addr_t fil_addr_null;
page */
#define FIL_PAGE_OFFSET 4 /* page offset inside space */
#define FIL_PAGE_PREV 8 /* if there is a 'natural' predecessor
- of the page, its offset */
+ of the page, its offset.
+ Otherwise FIL_NULL.
+ This field is not set on BLOB pages,
+ which are stored as a singly-linked
+ list. See also FIL_PAGE_NEXT. */
#define FIL_PAGE_NEXT 12 /* if there is a 'natural' successor
- of the page, its offset */
+ of the page, its offset.
+ Otherwise FIL_NULL.
+ B-tree index pages
+ (FIL_PAGE_TYPE contains FIL_PAGE_INDEX)
+ on the same PAGE_LEVEL are maintained
+ as a doubly linked list via
+ FIL_PAGE_PREV and FIL_PAGE_NEXT
+ in the collation order of the
+ smallest user record on each page. */
#define FIL_PAGE_LSN 16 /* lsn of the end of the newest
modification log record to the page */
#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,...,
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 11b664b6826..d04269fc157 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -360,24 +360,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/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
new file mode 100644
index 00000000000..2d27034fdfe
--- /dev/null
+++ b/storage/innobase/include/ha_prototypes.h
@@ -0,0 +1,22 @@
+#ifndef HA_INNODB_PROTOTYPES_H
+#define HA_INNODB_PROTOTYPES_H
+
+/* Prototypes for global functions in ha_innodb.cc that are called by
+InnoDB's C-code. */
+
+/*************************************************************************
+Wrapper around MySQL's copy_and_convert function, see it for
+documentation. */
+
+ulint
+innobase_convert_string(
+/*====================*/
+ void* to,
+ ulint to_length,
+ CHARSET_INFO* to_cs,
+ const void* from,
+ ulint from_length,
+ CHARSET_INFO* from_cs,
+ uint* errors);
+
+#endif
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index 34f29ae5dec..77fefe2020b 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/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/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index f9342e962f2..f68d45d83df 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/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. */
@@ -322,6 +322,44 @@ mem_heap_strcat(
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 */
+
+/**************************************************************************
+Concatenate two memory blocks and return the result, using a memory heap. */
+
+void*
+mem_heap_cat(
+/*=========*/
+ /* out, own: the result */
+ mem_heap_t* heap, /* in: memory heap where result is allocated */
+ const void* b1, /* in: block 1 */
+ ulint len1, /* in: length of b1, in bytes */
+ const void* b2, /* in: block 2 */
+ ulint len2); /* in: length of b2, in bytes */
+
+/********************************************************************
+A simple (s)printf replacement that dynamically allocates the space for the
+formatted string from the given heap. This supports a very limited set of
+the printf syntax: types 's' and 'u' and length modifier 'l' (which is
+required for the 'u' type). */
+
+char*
+mem_heap_printf(
+/*============*/
+ /* out: heap-allocated formatted string */
+ mem_heap_t* heap, /* in: memory heap */
+ const char* format, /* in: format string */
+ ...) __attribute__ ((format (printf, 2, 3)));
+
#ifdef MEM_PERIODIC_CHECK
/**********************************************************************
Goes through the list of all allocated mem blocks, checks their magic
diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h
index 68b8ae41cc0..b3140008a3c 100644
--- a/storage/innobase/include/pars0pars.h
+++ b/storage/innobase/include/pars0pars.h
@@ -532,6 +532,16 @@ pars_info_add_function(
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.*/
pars_user_func_t*
@@ -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/storage/innobase/include/pars0sym.h b/storage/innobase/include/pars0sym.h
index 14f762d5b7a..fc7df92ff60 100644
--- a/storage/innobase/include/pars0sym.h
+++ b/storage/innobase/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/storage/innobase/include/pars0types.h b/storage/innobase/include/pars0types.h
index 6fcfaf23024..bf7df89a883 100644
--- a/storage/innobase/include/pars0types.h
+++ b/storage/innobase/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/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index b2f3b9d141b..af11198d001 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -19,8 +19,10 @@ Created 5/30/1994 Heikki Tuuri
#define REC_MAX_HEAP_NO (2 * 8192 - 1)
#define REC_MAX_N_OWNED (16 - 1)
-/* Flag denoting the predefined minimum record: this bit is ORed in the 4
-info bits of a record */
+/* Info bit denoting the predefined minimum record: this bit is set
+if and only if the record is the first user record on a non-leaf
+B-tree page that is the leftmost page on its level
+(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
#define REC_INFO_MIN_REC_FLAG 0x10UL
/* Number of extra bytes in an old-style record,
diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h
index 52dd2fce551..2653f8a354d 100644
--- a/storage/innobase/include/row0purge.h
+++ b/storage/innobase/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/storage/innobase/include/row0undo.h b/storage/innobase/include/row0undo.h
index 5e3f514ad8d..29cfbc9ac20 100644
--- a/storage/innobase/include/row0undo.h
+++ b/storage/innobase/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/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index ff82cb2999a..dc1f2d96d9d 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -18,6 +18,9 @@ Created 10/10/1995 Heikki Tuuri
extern const char* srv_main_thread_op_info;
+/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+extern const char srv_mysql50_table_name_prefix[9];
+
/* When this event is set the lock timeout and InnoDB monitor
thread starts running */
extern os_event_t srv_lock_timeout_thread_event;
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index e6ca3258099..616d3eeb978 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/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/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 0a233843b50..64b245246f8 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/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/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index c5e87e468c6..f2dafbc3a70 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -82,7 +82,7 @@ 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
@@ -90,8 +90,10 @@ memory is read outside the allocated blocks. */
#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
+#endif
+
+#define UNIV_BTR_DEBUG
#define UNIV_LIGHT_MEM_DEBUG
#define YYDEBUG 1
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h
index 55e8c8ef88c..a317f35f4be 100644
--- a/storage/innobase/include/ut0dbg.h
+++ b/storage/innobase/include/ut0dbg.h
@@ -41,12 +41,21 @@ void ut_dbg_panic(void);
/* Stop threads in ut_a(). */
# define UT_DBG_STOP while (0) /* We do not do this on NetWare */
#else /* __NETWARE__ */
-/* Flag for indicating that all threads should stop. This will be set
-by ut_dbg_assertion_failed(). */
-extern ibool ut_dbg_stop_threads;
+# if defined(__WIN__) || defined(__INTEL_COMPILER)
+# undef UT_DBG_USE_ABORT
+# elif defined(__GNUC__) && (__GNUC__ > 2)
+# define UT_DBG_USE_ABORT
+# endif
+# ifndef UT_DBG_USE_ABORT
/* A null pointer that will be dereferenced to trigger a memory trap */
extern ulint* ut_dbg_null_ptr;
+# endif
+
+# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
+/* Flag for indicating that all threads should stop. This will be set
+by ut_dbg_assertion_failed(). */
+extern ibool ut_dbg_stop_threads;
/*****************************************************************
Stop a thread after assertion failure. */
@@ -56,15 +65,23 @@ ut_dbg_stop_thread(
/*===============*/
const char* file,
ulint line);
+# endif
+# ifdef UT_DBG_USE_ABORT
+/* Abort the execution. */
+# define UT_DBG_PANIC abort()
+/* Stop threads (null operation) */
+# define UT_DBG_STOP while (0)
+# else /* UT_DBG_USE_ABORT */
/* Abort the execution. */
-# define UT_DBG_PANIC \
+# define UT_DBG_PANIC \
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
/* Stop threads in ut_a(). */
-# define UT_DBG_STOP do \
+# define UT_DBG_STOP do \
if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
} while (0)
+# endif /* UT_DBG_USE_ABORT */
#endif /* __NETWARE__ */
/* Abort execution if EXPR does not evaluate to nonzero. */
diff --git a/storage/innobase/include/ut0list.h b/storage/innobase/include/ut0list.h
new file mode 100644
index 00000000000..c35cf202600
--- /dev/null
+++ b/storage/innobase/include/ut0list.h
@@ -0,0 +1,148 @@
+/***********************************************************************
+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 using mem_alloc. Lists created with this function must be
+freed with ib_list_free. */
+
+ib_list_t*
+ib_list_create(void);
+/*=================*/
+ /* out: list */
+
+
+/********************************************************************
+Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
+lists created with this function. */
+
+ib_list_t*
+ib_list_create_heap(
+/*================*/
+ /* out: list */
+ mem_heap_t* heap); /* in: memory heap to use */
+
+/********************************************************************
+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 */
+ ibool is_heap_list; /* TRUE if this list was
+ allocated through a heap */
+};
+
+/* 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/storage/innobase/include/ut0list.ic b/storage/innobase/include/ut0list.ic
new file mode 100644
index 00000000000..c2d3e4557f0
--- /dev/null
+++ b/storage/innobase/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/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 8f1be212fbf..1bb90ae041b 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -224,6 +224,7 @@ ut_print_name(
/*==========*/
FILE* f, /* in: output stream */
struct trx_struct*trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name); /* in: name to print */
/**************************************************************************
@@ -234,6 +235,7 @@ ut_print_namel(
/*===========*/
FILE* f, /* in: output stream */
struct trx_struct*trx, /* in: transaction (NULL=no quotes) */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen);/* in: length of name */
diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h
new file mode 100644
index 00000000000..57f2297beee
--- /dev/null
+++ b/storage/innobase/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/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 34e3296c9bc..a73a78620f1 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -1860,7 +1860,7 @@ lock_rec_enqueue_waiting(
fputs(
" InnoDB: Error: a record lock wait happens in a dictionary operation!\n"
"InnoDB: Table name ", stderr);
- ut_print_name(stderr, trx, index->table_name);
+ ut_print_name(stderr, trx, TRUE, index->table_name);
fputs(".\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
stderr);
@@ -1899,7 +1899,7 @@ lock_rec_enqueue_waiting(
if (lock_print_waits) {
fprintf(stderr, "Lock wait for trx %lu in index ",
(ulong) ut_dulint_get_low(trx->id));
- ut_print_name(stderr, trx, index->name);
+ ut_print_name(stderr, trx, FALSE, index->name);
}
#endif /* UNIV_DEBUG */
@@ -3555,7 +3555,7 @@ lock_table_enqueue_waiting(
fputs(
" InnoDB: Error: a table lock wait happens in a dictionary operation!\n"
"InnoDB: Table name ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs(".\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
stderr);
@@ -4074,7 +4074,8 @@ lock_table_print(
ut_a(lock_get_type(lock) == LOCK_TABLE);
fputs("TABLE LOCK table ", file);
- ut_print_name(file, lock->trx, lock->un_member.tab_lock.table->name);
+ ut_print_name(file, lock->trx, TRUE,
+ lock->un_member.tab_lock.table->name);
fprintf(file, " trx id %lu %lu",
(ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low);
diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
index ea3b74c00f9..db6b8fabf6f 100644
--- a/storage/innobase/log/log0log.c
+++ b/storage/innobase/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/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 4a91192782e..63a90f05212 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -112,8 +112,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;
@@ -894,7 +893,6 @@ recv_parse_or_apply_log_rec_body(
recv_sys->found_corrupt_log = TRUE;
}
- ut_ad(!page || ptr);
if (index) {
dict_table_t* table = index->table;
diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c
index 86c33a22531..1220c2c8e82 100644
--- a/storage/innobase/mem/mem0dbg.c
+++ b/storage/innobase/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/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index 5e7c48d3d3d..3c42c1d0fff 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -17,6 +17,7 @@ Created 6/9/1994 Heikki Tuuri
#include "btr0sea.h"
#include "srv0srv.h"
#include "mem0dbg.c"
+#include <stdarg.h>
/*
THE MEMORY MANAGEMENT
@@ -107,11 +108,45 @@ 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 memory blocks and return the result, using a memory heap. */
+
+void*
+mem_heap_cat(
+/*=========*/
+ /* out, own: the result */
+ mem_heap_t* heap, /* in: memory heap where result is allocated */
+ const void* b1, /* in: block 1 */
+ ulint len1, /* in: length of b1, in bytes */
+ const void* b2, /* in: block 2 */
+ ulint len2) /* in: length of b2, in bytes */
+{
+ void* res = mem_heap_alloc(heap, len1 + len2);
+
+ memcpy(res, b1, len1);
+ memcpy(res + len1, b2, len2);
+
+ return(res);
}
/**************************************************************************
@@ -139,6 +174,150 @@ mem_heap_strcat(
return(s);
}
+
+/********************************************************************
+Helper function for mem_heap_printf. */
+static
+ulint
+mem_heap_printf_low(
+/*================*/
+ /* out: length of formatted string,
+ including terminating NUL */
+ char* buf, /* in/out: buffer to store formatted string
+ in, or NULL to just calculate length */
+ const char* format, /* in: format string */
+ va_list ap) /* in: arguments */
+{
+ ulint len = 0;
+
+ while (*format) {
+
+ /* Does this format specifier have the 'l' length modifier. */
+ ibool is_long = FALSE;
+
+ /* Length of one parameter. */
+ size_t plen;
+
+ if (*format++ != '%') {
+ /* Non-format character. */
+
+ len++;
+
+ if (buf) {
+ *buf++ = *(format - 1);
+ }
+
+ continue;
+ }
+
+ if (*format == 'l') {
+ is_long = TRUE;
+ format++;
+ }
+
+ switch (*format++) {
+ case 's':
+ /* string */
+ {
+ char* s = va_arg(ap, char*);
+
+ /* "%ls" is a non-sensical format specifier. */
+ ut_a(!is_long);
+
+ plen = strlen(s);
+ len += plen;
+
+ if (buf) {
+ memcpy(buf, s, plen);
+ buf += plen;
+ }
+ }
+
+ break;
+
+ case 'u':
+ /* unsigned int */
+ {
+ char tmp[32];
+ unsigned long val;
+
+ /* We only support 'long' values for now. */
+ ut_a(is_long);
+
+ val = va_arg(ap, unsigned long);
+
+ plen = sprintf(tmp, "%lu", val);
+ len += plen;
+
+ if (buf) {
+ memcpy(buf, tmp, plen);
+ buf += plen;
+ }
+ }
+
+ break;
+
+ case '%':
+
+ /* "%l%" is a non-sensical format specifier. */
+ ut_a(!is_long);
+
+ len++;
+
+ if (buf) {
+ *buf++ = '%';
+ }
+
+ break;
+
+ default:
+ ut_error;
+ }
+ }
+
+ /* For the NUL character. */
+ len++;
+
+ if (buf) {
+ *buf = '\0';
+ }
+
+ return(len);
+}
+
+/********************************************************************
+A simple (s)printf replacement that dynamically allocates the space for the
+formatted string from the given heap. This supports a very limited set of
+the printf syntax: types 's' and 'u' and length modifier 'l' (which is
+required for the 'u' type). */
+
+char*
+mem_heap_printf(
+/*============*/
+ /* out: heap-allocated formatted string */
+ mem_heap_t* heap, /* in: memory heap */
+ const char* format, /* in: format string */
+ ...)
+{
+ va_list ap;
+ char* str;
+ ulint len;
+
+ /* Calculate length of string */
+ len = 0;
+ va_start(ap, format);
+ len = mem_heap_printf_low(NULL, format, ap);
+ va_end(ap);
+
+ /* Now create it for real. */
+ str = mem_heap_alloc(heap, len);
+ va_start(ap, format);
+ mem_heap_printf_low(str, format, ap);
+ va_end(ap);
+
+ return(str);
+}
+
/*******************************************************************
Creates a memory heap block where data can be allocated. */
diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c
index a61ab1ce170..5606921758c 100644
--- a/storage/innobase/mem/mem0pool.c
+++ b/storage/innobase/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/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index d10bdccbd2b..74905ce06dd 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -3680,6 +3680,37 @@ os_aio_posix_handle(
#endif
/**************************************************************************
+Do a 'last millisecond' check that the page end 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);
+ 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,32 +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 */
-
- 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);
- 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/storage/innobase/os/os0thread.c b/storage/innobase/os/os0thread.c
index 0b739c07557..138db6426ea 100644
--- a/storage/innobase/os/os0thread.c
+++ b/storage/innobase/os/os0thread.c
@@ -220,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/storage/innobase/pars/lexyy.c b/storage/innobase/pars/lexyy.c
index bbe78db1613..6d4e692e86b 100644
--- a/storage/innobase/pars/lexyy.c
+++ b/storage/innobase/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,
-
- 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,
-
- 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,
-
- 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
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
-
- 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,
+ 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,
+
+ 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,
-
- 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,
-
- 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,
-
- 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,
-
- 197, 203
+ 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,
+
+ 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,
+
+ 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, 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,
+
+ 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,
-
- 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,
-
- 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,
-
- 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,
-
- 393, 393
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
-
- 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,
-
- 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,
-
- 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,
-
- 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
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
-
- 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,
-
- 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,
-
- 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,
-
- 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
+ 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,
+
+ 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,
+
+ 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,
+
+ 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,
+
+ 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:
+case 21:
YY_RULE_SETUP
-#line 236 "pars0lex.l"
+#line 244 "pars0lex.l"
{
return(PARS_INT_TOKEN);
}
YY_BREAK
-case 21:
+case 22:
YY_RULE_SETUP
-#line 240 "pars0lex.l"
+#line 248 "pars0lex.l"
{
return(PARS_INT_TOKEN);
}
YY_BREAK
-case 22:
+case 23:
YY_RULE_SETUP
-#line 244 "pars0lex.l"
+#line 252 "pars0lex.l"
{
return(PARS_FLOAT_TOKEN);
}
YY_BREAK
-case 23:
+case 24:
YY_RULE_SETUP
-#line 248 "pars0lex.l"
+#line 256 "pars0lex.l"
{
return(PARS_CHAR_TOKEN);
}
YY_BREAK
-case 24:
+case 25:
YY_RULE_SETUP
-#line 252 "pars0lex.l"
+#line 260 "pars0lex.l"
{
return(PARS_IS_TOKEN);
}
YY_BREAK
-case 25:
+case 26:
YY_RULE_SETUP
-#line 256 "pars0lex.l"
+#line 264 "pars0lex.l"
{
return(PARS_BEGIN_TOKEN);
}
YY_BREAK
-case 26:
+case 27:
YY_RULE_SETUP
-#line 260 "pars0lex.l"
+#line 268 "pars0lex.l"
{
return(PARS_END_TOKEN);
}
YY_BREAK
-case 27:
+case 28:
YY_RULE_SETUP
-#line 264 "pars0lex.l"
+#line 272 "pars0lex.l"
{
return(PARS_IF_TOKEN);
}
YY_BREAK
-case 28:
+case 29:
YY_RULE_SETUP
-#line 268 "pars0lex.l"
+#line 276 "pars0lex.l"
{
return(PARS_THEN_TOKEN);
}
YY_BREAK
-case 29:
+case 30:
YY_RULE_SETUP
-#line 272 "pars0lex.l"
+#line 280 "pars0lex.l"
{
return(PARS_ELSE_TOKEN);
}
YY_BREAK
-case 30:
+case 31:
YY_RULE_SETUP
-#line 276 "pars0lex.l"
+#line 284 "pars0lex.l"
{
return(PARS_ELSIF_TOKEN);
}
YY_BREAK
-case 31:
+case 32:
YY_RULE_SETUP
-#line 280 "pars0lex.l"
+#line 288 "pars0lex.l"
{
return(PARS_LOOP_TOKEN);
}
YY_BREAK
-case 32:
+case 33:
YY_RULE_SETUP
-#line 284 "pars0lex.l"
+#line 292 "pars0lex.l"
{
return(PARS_WHILE_TOKEN);
}
YY_BREAK
-case 33:
+case 34:
YY_RULE_SETUP
-#line 288 "pars0lex.l"
+#line 296 "pars0lex.l"
{
return(PARS_RETURN_TOKEN);
}
YY_BREAK
-case 34:
+case 35:
YY_RULE_SETUP
-#line 292 "pars0lex.l"
+#line 300 "pars0lex.l"
{
return(PARS_SELECT_TOKEN);
}
YY_BREAK
-case 35:
+case 36:
YY_RULE_SETUP
-#line 296 "pars0lex.l"
+#line 304 "pars0lex.l"
{
return(PARS_SUM_TOKEN);
}
YY_BREAK
-case 36:
+case 37:
YY_RULE_SETUP
-#line 300 "pars0lex.l"
+#line 308 "pars0lex.l"
{
return(PARS_COUNT_TOKEN);
}
YY_BREAK
-case 37:
+case 38:
YY_RULE_SETUP
-#line 304 "pars0lex.l"
+#line 312 "pars0lex.l"
{
return(PARS_DISTINCT_TOKEN);
}
YY_BREAK
-case 38:
+case 39:
YY_RULE_SETUP
-#line 308 "pars0lex.l"
+#line 316 "pars0lex.l"
{
return(PARS_FROM_TOKEN);
}
YY_BREAK
-case 39:
+case 40:
YY_RULE_SETUP
-#line 312 "pars0lex.l"
+#line 320 "pars0lex.l"
{
return(PARS_WHERE_TOKEN);
}
YY_BREAK
-case 40:
+case 41:
YY_RULE_SETUP
-#line 316 "pars0lex.l"
+#line 324 "pars0lex.l"
{
return(PARS_FOR_TOKEN);
}
YY_BREAK
-case 41:
+case 42:
YY_RULE_SETUP
-#line 320 "pars0lex.l"
+#line 328 "pars0lex.l"
{
return(PARS_CONSISTENT_TOKEN);
}
YY_BREAK
-case 42:
+case 43:
YY_RULE_SETUP
-#line 324 "pars0lex.l"
+#line 332 "pars0lex.l"
{
return(PARS_READ_TOKEN);
}
YY_BREAK
-case 43:
+case 44:
YY_RULE_SETUP
-#line 328 "pars0lex.l"
+#line 336 "pars0lex.l"
{
return(PARS_ORDER_TOKEN);
}
YY_BREAK
-case 44:
+case 45:
YY_RULE_SETUP
-#line 332 "pars0lex.l"
+#line 340 "pars0lex.l"
{
return(PARS_BY_TOKEN);
}
YY_BREAK
-case 45:
+case 46:
YY_RULE_SETUP
-#line 336 "pars0lex.l"
+#line 344 "pars0lex.l"
{
return(PARS_ASC_TOKEN);
}
YY_BREAK
-case 46:
+case 47:
YY_RULE_SETUP
-#line 340 "pars0lex.l"
+#line 348 "pars0lex.l"
{
return(PARS_DESC_TOKEN);
}
YY_BREAK
-case 47:
+case 48:
YY_RULE_SETUP
-#line 344 "pars0lex.l"
+#line 352 "pars0lex.l"
{
return(PARS_INSERT_TOKEN);
}
YY_BREAK
-case 48:
+case 49:
YY_RULE_SETUP
-#line 348 "pars0lex.l"
+#line 356 "pars0lex.l"
{
return(PARS_INTO_TOKEN);
}
YY_BREAK
-case 49:
+case 50:
YY_RULE_SETUP
-#line 352 "pars0lex.l"
+#line 360 "pars0lex.l"
{
return(PARS_VALUES_TOKEN);
}
YY_BREAK
-case 50:
+case 51:
YY_RULE_SETUP
-#line 356 "pars0lex.l"
+#line 364 "pars0lex.l"
{
return(PARS_UPDATE_TOKEN);
}
YY_BREAK
-case 51:
+case 52:
YY_RULE_SETUP
-#line 360 "pars0lex.l"
+#line 368 "pars0lex.l"
{
return(PARS_SET_TOKEN);
}
YY_BREAK
-case 52:
+case 53:
YY_RULE_SETUP
-#line 364 "pars0lex.l"
+#line 372 "pars0lex.l"
{
return(PARS_DELETE_TOKEN);
}
YY_BREAK
-case 53:
+case 54:
YY_RULE_SETUP
-#line 368 "pars0lex.l"
+#line 376 "pars0lex.l"
{
return(PARS_CURRENT_TOKEN);
}
YY_BREAK
-case 54:
+case 55:
YY_RULE_SETUP
-#line 372 "pars0lex.l"
+#line 380 "pars0lex.l"
{
return(PARS_OF_TOKEN);
}
YY_BREAK
-case 55:
+case 56:
YY_RULE_SETUP
-#line 376 "pars0lex.l"
+#line 384 "pars0lex.l"
{
return(PARS_CREATE_TOKEN);
}
YY_BREAK
-case 56:
+case 57:
YY_RULE_SETUP
-#line 380 "pars0lex.l"
+#line 388 "pars0lex.l"
{
return(PARS_TABLE_TOKEN);
}
YY_BREAK
-case 57:
+case 58:
YY_RULE_SETUP
-#line 384 "pars0lex.l"
+#line 392 "pars0lex.l"
{
return(PARS_INDEX_TOKEN);
}
YY_BREAK
-case 58:
+case 59:
YY_RULE_SETUP
-#line 388 "pars0lex.l"
+#line 396 "pars0lex.l"
{
return(PARS_UNIQUE_TOKEN);
}
YY_BREAK
-case 59:
+case 60:
YY_RULE_SETUP
-#line 392 "pars0lex.l"
+#line 400 "pars0lex.l"
{
return(PARS_CLUSTERED_TOKEN);
}
YY_BREAK
-case 60:
+case 61:
YY_RULE_SETUP
-#line 396 "pars0lex.l"
+#line 404 "pars0lex.l"
{
return(PARS_DOES_NOT_FIT_IN_MEM_TOKEN);
}
YY_BREAK
-case 61:
+case 62:
YY_RULE_SETUP
-#line 400 "pars0lex.l"
+#line 408 "pars0lex.l"
{
return(PARS_ON_TOKEN);
}
YY_BREAK
-case 62:
+case 63:
YY_RULE_SETUP
-#line 404 "pars0lex.l"
+#line 412 "pars0lex.l"
{
return(PARS_DECLARE_TOKEN);
}
YY_BREAK
-case 63:
+case 64:
YY_RULE_SETUP
-#line 408 "pars0lex.l"
+#line 416 "pars0lex.l"
{
return(PARS_CURSOR_TOKEN);
}
YY_BREAK
-case 64:
+case 65:
YY_RULE_SETUP
-#line 412 "pars0lex.l"
+#line 420 "pars0lex.l"
{
return(PARS_OPEN_TOKEN);
}
YY_BREAK
-case 65:
+case 66:
YY_RULE_SETUP
-#line 416 "pars0lex.l"
+#line 424 "pars0lex.l"
{
return(PARS_FETCH_TOKEN);
}
YY_BREAK
-case 66:
+case 67:
YY_RULE_SETUP
-#line 420 "pars0lex.l"
+#line 428 "pars0lex.l"
{
return(PARS_CLOSE_TOKEN);
}
YY_BREAK
-case 67:
+case 68:
YY_RULE_SETUP
-#line 424 "pars0lex.l"
+#line 432 "pars0lex.l"
{
return(PARS_NOTFOUND_TOKEN);
}
YY_BREAK
-case 68:
+case 69:
YY_RULE_SETUP
-#line 428 "pars0lex.l"
+#line 436 "pars0lex.l"
{
return(PARS_TO_CHAR_TOKEN);
}
YY_BREAK
-case 69:
+case 70:
YY_RULE_SETUP
-#line 432 "pars0lex.l"
+#line 440 "pars0lex.l"
{
return(PARS_TO_NUMBER_TOKEN);
}
YY_BREAK
-case 70:
+case 71:
YY_RULE_SETUP
-#line 436 "pars0lex.l"
+#line 444 "pars0lex.l"
{
return(PARS_TO_BINARY_TOKEN);
}
YY_BREAK
-case 71:
+case 72:
YY_RULE_SETUP
-#line 440 "pars0lex.l"
+#line 448 "pars0lex.l"
{
return(PARS_BINARY_TO_NUMBER_TOKEN);
}
YY_BREAK
-case 72:
+case 73:
YY_RULE_SETUP
-#line 444 "pars0lex.l"
+#line 452 "pars0lex.l"
{
return(PARS_SUBSTR_TOKEN);
}
YY_BREAK
-case 73:
+case 74:
YY_RULE_SETUP
-#line 448 "pars0lex.l"
+#line 456 "pars0lex.l"
{
return(PARS_REPLSTR_TOKEN);
}
YY_BREAK
-case 74:
+case 75:
YY_RULE_SETUP
-#line 452 "pars0lex.l"
+#line 460 "pars0lex.l"
{
return(PARS_CONCAT_TOKEN);
}
YY_BREAK
-case 75:
+case 76:
YY_RULE_SETUP
-#line 456 "pars0lex.l"
+#line 464 "pars0lex.l"
{
return(PARS_INSTR_TOKEN);
}
YY_BREAK
-case 76:
+case 77:
YY_RULE_SETUP
-#line 460 "pars0lex.l"
+#line 468 "pars0lex.l"
{
return(PARS_LENGTH_TOKEN);
}
YY_BREAK
-case 77:
+case 78:
YY_RULE_SETUP
-#line 464 "pars0lex.l"
+#line 472 "pars0lex.l"
{
return(PARS_SYSDATE_TOKEN);
}
YY_BREAK
-case 78:
+case 79:
YY_RULE_SETUP
-#line 468 "pars0lex.l"
+#line 476 "pars0lex.l"
{
return(PARS_PRINTF_TOKEN);
}
YY_BREAK
-case 79:
+case 80:
YY_RULE_SETUP
-#line 472 "pars0lex.l"
+#line 480 "pars0lex.l"
{
return(PARS_ASSERT_TOKEN);
}
YY_BREAK
-case 80:
+case 81:
YY_RULE_SETUP
-#line 476 "pars0lex.l"
+#line 484 "pars0lex.l"
{
return(PARS_RND_TOKEN);
}
YY_BREAK
-case 81:
+case 82:
YY_RULE_SETUP
-#line 480 "pars0lex.l"
+#line 488 "pars0lex.l"
{
return(PARS_RND_STR_TOKEN);
}
YY_BREAK
-case 82:
+case 83:
YY_RULE_SETUP
-#line 484 "pars0lex.l"
+#line 492 "pars0lex.l"
{
return(PARS_ROW_PRINTF_TOKEN);
}
YY_BREAK
-case 83:
+case 84:
YY_RULE_SETUP
-#line 488 "pars0lex.l"
+#line 496 "pars0lex.l"
{
return(PARS_COMMIT_TOKEN);
}
YY_BREAK
-case 84:
+case 85:
YY_RULE_SETUP
-#line 492 "pars0lex.l"
+#line 500 "pars0lex.l"
{
return(PARS_ROLLBACK_TOKEN);
}
YY_BREAK
-case 85:
+case 86:
YY_RULE_SETUP
-#line 496 "pars0lex.l"
+#line 504 "pars0lex.l"
{
return(PARS_WORK_TOKEN);
}
YY_BREAK
-case 86:
+case 87:
YY_RULE_SETUP
-#line 500 "pars0lex.l"
+#line 508 "pars0lex.l"
{
return(PARS_UNSIGNED_TOKEN);
}
YY_BREAK
-case 87:
+case 88:
YY_RULE_SETUP
-#line 504 "pars0lex.l"
+#line 512 "pars0lex.l"
{
return(PARS_EXIT_TOKEN);
}
YY_BREAK
-case 88:
+case 89:
YY_RULE_SETUP
-#line 508 "pars0lex.l"
+#line 516 "pars0lex.l"
{
return(PARS_FUNCTION_TOKEN);
}
YY_BREAK
-case 89:
+case 90:
YY_RULE_SETUP
-#line 512 "pars0lex.l"
+#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:
-YY_RULE_SETUP
-#line 519 "pars0lex.l"
-{
- return(PARS_DDOT_TOKEN);
-}
- YY_BREAK
case 91:
YY_RULE_SETUP
-#line 523 "pars0lex.l"
+#line 527 "pars0lex.l"
{
- return(PARS_ASSIGN_TOKEN);
+ return(PARS_DDOT_TOKEN);
}
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 527 "pars0lex.l"
+#line 531 "pars0lex.l"
{
- return(PARS_LE_TOKEN);
+ return(PARS_ASSIGN_TOKEN);
}
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 531 "pars0lex.l"
+#line 535 "pars0lex.l"
{
- return(PARS_GE_TOKEN);
+ return(PARS_LE_TOKEN);
}
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 535 "pars0lex.l"
+#line 539 "pars0lex.l"
{
- return(PARS_NE_TOKEN);
+ return(PARS_GE_TOKEN);
}
YY_BREAK
case 95:
YY_RULE_SETUP
-#line 539 "pars0lex.l"
+#line 543 "pars0lex.l"
{
-
- return((int)(*yytext));
+ return(PARS_NE_TOKEN);
}
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/storage/innobase/pars/pars0lex.l b/storage/innobase/pars/pars0lex.l
index ab1fe446924..8f6a8d39a36 100644
--- a/storage/innobase/pars/pars0lex.l
+++ b/storage/innobase/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/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c
index 7ef2f65c724..def26e62d29 100644
--- a/storage/innobase/pars/pars0pars.c
+++ b/storage/innobase/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);
@@ -2071,6 +2072,32 @@ pars_info_add_function(
}
/********************************************************************
+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.*/
pars_user_func_t*
@@ -2131,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/storage/innobase/pars/pars0sym.c b/storage/innobase/pars/pars0sym.c
index 79a1e555b06..8d691febb14 100644
--- a/storage/innobase/pars/pars0sym.c
+++ b/storage/innobase/pars/pars0sym.c
@@ -207,6 +207,13 @@ sym_tab_add_bound_lit(
*lit_type = PARS_STR_LIT;
break;
+ case DATA_CHAR:
+ ut_a(blit->length > 0);
+
+ len = blit->length;
+ *lit_type = PARS_STR_LIT;
+ break;
+
case DATA_INT:
ut_a(blit->length > 0);
ut_a(blit->length <= 8);
@@ -304,3 +311,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/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index e47d6a621a7..414f4091403 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -601,7 +601,7 @@ row_ins_set_detailed(
rewind(srv_misc_tmpfile);
if (os_file_set_eof(srv_misc_tmpfile)) {
- ut_print_name(srv_misc_tmpfile, trx,
+ ut_print_name(srv_misc_tmpfile, trx, TRUE,
foreign->foreign_table_name);
dict_print_info_on_foreign_key_in_create_format(
srv_misc_tmpfile,
@@ -643,22 +643,22 @@ row_ins_foreign_report_err(
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
TRUE);
putc('\n', ef);
fputs(errstr, ef);
fputs(" in parent table, in index ", ef);
- ut_print_name(ef, trx, foreign->referenced_index->name);
+ ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
if (entry) {
fputs(" tuple:\n", ef);
dtuple_print(ef, entry);
}
fputs("\nBut in child table ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(", in index ", ef);
- ut_print_name(ef, trx, foreign->foreign_index->name);
+ ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
if (rec) {
fputs(", there is a record:\n", ef);
rec_print(ef, rec, foreign->foreign_index);
@@ -696,20 +696,20 @@ row_ins_foreign_report_add_err(
fputs(" Transaction:\n", ef);
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
TRUE);
fputs("\nTrying to add in child table, in index ", ef);
- ut_print_name(ef, trx, foreign->foreign_index->name);
+ ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
if (entry) {
fputs(" tuple:\n", ef);
dtuple_print(ef, entry);
}
fputs("\nBut in parent table ", ef);
- ut_print_name(ef, trx, foreign->referenced_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->referenced_table_name);
fputs(", in index ", ef);
- ut_print_name(ef, trx, foreign->referenced_index->name);
+ ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
fputs(",\nthe closest match we can find is record:\n", ef);
if (rec && page_rec_is_supremum(rec)) {
/* If the cursor ended on a supremum record, it is better
@@ -1277,16 +1277,19 @@ run_again:
fputs(" Transaction:\n", ef);
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE,
+ foreign->foreign_table_name);
fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef,
trx, foreign, TRUE);
fputs("\nTrying to add to index ", ef);
- ut_print_name(ef, trx, foreign->foreign_index->name);
+ ut_print_name(ef, trx, FALSE,
+ foreign->foreign_index->name);
fputs(" tuple:\n", ef);
dtuple_print(ef, entry);
fputs("\nBut the parent table ", ef);
- ut_print_name(ef, trx, foreign->referenced_table_name);
+ ut_print_name(ef, trx, TRUE,
+ foreign->referenced_table_name);
fputs("\nor its .ibd file does not currently exist!\n", ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -1513,8 +1516,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/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 56574618f9a..58d86790c0a 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -680,7 +680,7 @@ row_prebuilt_free(
"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name",
(ulong) prebuilt->magic_n,
(ulong) prebuilt->magic_n2);
- ut_print_name(stderr, NULL, prebuilt->table->name);
+ ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
putc('\n', stderr);
mem_analyze_corruption(prebuilt);
@@ -773,7 +773,7 @@ row_update_prebuilt_trx(
"InnoDB: Error: trying to use a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n);
- ut_print_name(stderr, NULL, prebuilt->table->name);
+ ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
putc('\n', stderr);
mem_analyze_corruption(prebuilt);
@@ -1094,7 +1094,8 @@ row_insert_for_mysql(
"InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n);
- ut_print_name(stderr, prebuilt->trx, prebuilt->table->name);
+ ut_print_name(stderr, prebuilt->trx, TRUE,
+ prebuilt->table->name);
putc('\n', stderr);
mem_analyze_corruption(prebuilt);
@@ -1329,7 +1330,8 @@ row_update_for_mysql(
"InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name",
(ulong) prebuilt->magic_n);
- ut_print_name(stderr, prebuilt->trx, prebuilt->table->name);
+ ut_print_name(stderr, prebuilt->trx, TRUE,
+ prebuilt->table->name);
putc('\n', stderr);
mem_analyze_corruption(prebuilt);
@@ -1941,7 +1943,7 @@ row_create_table_for_mysql(
fputs(" InnoDB: Warning: cannot create table ",
stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs(" because tablespace full\n", stderr);
if (dict_table_get_low(table->name)) {
@@ -1954,7 +1956,7 @@ row_create_table_for_mysql(
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs(" already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n"
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
@@ -2031,7 +2033,7 @@ row_create_index_for_mysql(
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: column ", stderr);
- ut_print_name(stderr, trx,
+ ut_print_name(stderr, trx, FALSE,
dict_index_get_nth_field(index, i)->name);
fputs(" appears twice in ", stderr);
dict_index_name_print(stderr, trx, index);
@@ -2196,7 +2198,7 @@ row_drop_table_for_mysql_in_background(
trx->check_foreigns = FALSE;
/* fputs("InnoDB: Error: Dropping table ", stderr);
- ut_print_name(stderr, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs(" in background drop list\n", stderr); */
/* Try to drop the table in InnoDB */
@@ -2360,7 +2362,7 @@ row_add_table_to_background_drop_list(
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
/* fputs("InnoDB: Adding table ", stderr);
- ut_print_name(stderr, drop->table_name);
+ ut_print_name(stderr, trx, TRUE, drop->table_name);
fputs(" to background drop list\n", stderr); */
mutex_exit(&kernel_mutex);
@@ -2429,7 +2431,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
if (table->space == 0) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr);
err = DB_ERROR;
@@ -2441,7 +2443,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to DISCARD table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: though there is a foreign key check running on it.\n"
"InnoDB: Cannot discard the table.\n",
@@ -2475,10 +2477,10 @@ do not allow the discard. We also reserve the data dictionary latch. */
ut_print_timestamp(ef);
fputs(" Cannot DISCARD table ", ef);
- ut_print_name(ef, trx, name);
+ ut_print_name(ef, trx, TRUE, name);
fputs("\n"
"because it is referenced by ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -2540,10 +2542,10 @@ do not allow the discard. We also reserve the data dictionary latch. */
}
funct_exit:
- row_mysql_unlock_data_dictionary(trx);
-
trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+
trx->op_info = "";
return((int) err);
@@ -2590,7 +2592,7 @@ row_import_tablespace_for_mysql(
if (!success) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: cannot reset lsn's in table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", stderr);
@@ -2611,7 +2613,7 @@ row_import_tablespace_for_mysql(
if (!table) {
ut_print_timestamp(stderr);
fputs(" InnoDB: table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: does not exist in the InnoDB data dictionary\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
@@ -2625,7 +2627,7 @@ row_import_tablespace_for_mysql(
if (table->space == 0) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr);
err = DB_ERROR;
@@ -2638,7 +2640,7 @@ row_import_tablespace_for_mysql(
fputs(
" InnoDB: Error: you are trying to IMPORT a tablespace\n"
"InnoDB: ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs(", though you have not called DISCARD on it yet\n"
"InnoDB: during the lifetime of the mysqld process!\n", stderr);
@@ -2663,7 +2665,7 @@ row_import_tablespace_for_mysql(
fputs(
" InnoDB: cannot find or open in the database directory the .ibd file of\n"
"InnoDB: table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
stderr);
@@ -2673,10 +2675,10 @@ row_import_tablespace_for_mysql(
}
funct_exit:
- row_mysql_unlock_data_dictionary(trx);
-
trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+
trx->op_info = "";
return((int) err);
@@ -2783,10 +2785,10 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
ut_print_timestamp(ef);
fputs(" Cannot truncate table ", ef);
- ut_print_name(ef, trx, table->name);
+ ut_print_name(ef, trx, TRUE, table->name);
fputs(" by DROP+CREATE\n"
"InnoDB: because it is referenced by ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -2803,7 +2805,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
if (table->n_foreign_key_checks_running > 0) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Cannot truncate table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs(" by DROP+CREATE\n"
"InnoDB: because there is a foreign key check running on it.\n",
stderr);
@@ -2918,7 +2920,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
trx->error_state = DB_SUCCESS;
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to assign a new identifier to table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: after truncating it. Background processes may corrupt the table!\n",
stderr);
@@ -3045,7 +3047,7 @@ row_drop_table_for_mysql(
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs(" does not exist in the InnoDB internal\n"
"InnoDB: data dictionary though MySQL is trying to drop it.\n"
"InnoDB: Have you copied the .frm file of the table to the\n"
@@ -3081,10 +3083,10 @@ row_drop_table_for_mysql(
ut_print_timestamp(ef);
fputs(" Cannot drop table ", ef);
- ut_print_name(ef, trx, name);
+ ut_print_name(ef, trx, TRUE, name);
fputs("\n"
"because it is referenced by ", ef);
- ut_print_name(ef, trx, foreign->foreign_table_name);
+ ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
putc('\n', ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -3103,7 +3105,7 @@ row_drop_table_for_mysql(
if (added) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: though there are still open handles to it.\n"
"InnoDB: Adding the table to the background drop queue.\n",
@@ -3136,7 +3138,7 @@ fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
if (added) {
ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to drop table ", stderr);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: though there is a foreign key check running on it.\n"
"InnoDB: Adding the table to the background drop queue.\n",
@@ -3259,7 +3261,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: not able to remove table ",
stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs(" from the dictionary cache!\n", stderr);
err = DB_ERROR;
}
@@ -3277,7 +3279,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
fprintf(stderr,
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
"InnoDB: of table ");
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n");
goto funct_exit;
@@ -3289,14 +3291,14 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
fprintf(stderr,
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
"InnoDB: of table ");
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n");
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: not able to delete tablespace %lu of table ",
(ulong) space_id);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("!\n", stderr);
err = DB_ERROR;
}
@@ -3304,6 +3306,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
}
funct_exit:
+ trx_commit_for_mysql(trx);
+
if (locked_dictionary) {
row_mysql_unlock_data_dictionary(trx);
}
@@ -3312,8 +3316,6 @@ funct_exit:
mem_free(dir_path_of_temp_table);
}
- trx_commit_for_mysql(trx);
-
trx->op_info = "";
#ifndef UNIV_HOTBACKUP
@@ -3364,10 +3366,10 @@ loop:
ut_print_timestamp(stderr);
fputs(
" InnoDB: Warning: MySQL is trying to drop database ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fputs("\n"
"InnoDB: though there are still open handles to table ", stderr);
- ut_print_name(stderr, trx, table_name);
+ ut_print_name(stderr, trx, TRUE, table_name);
fputs(".\n", stderr);
os_thread_sleep(1000000);
@@ -3383,19 +3385,19 @@ loop:
if (err != DB_SUCCESS) {
fputs("InnoDB: DROP DATABASE ", stderr);
- ut_print_name(stderr, trx, name);
+ ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, " failed with error %lu for table ",
(ulint) err);
- ut_print_name(stderr, trx, table_name);
+ ut_print_name(stderr, trx, TRUE, table_name);
putc('\n', stderr);
break;
}
}
- row_mysql_unlock_data_dictionary(trx);
-
trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary(trx);
+
trx->op_info = "";
return(err);
@@ -3543,7 +3545,7 @@ row_rename_table_for_mysql(
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, old_name);
+ ut_print_name(stderr, trx, TRUE, old_name);
fputs(" does not exist in the InnoDB internal\n"
"InnoDB: data dictionary though MySQL is trying to rename the table.\n"
"InnoDB: Have you copied the .frm file of the table to the\n"
@@ -3559,7 +3561,7 @@ row_rename_table_for_mysql(
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
- ut_print_name(stderr, trx, old_name);
+ ut_print_name(stderr, trx, TRUE, old_name);
fputs(
" does not have an .ibd file in the database directory.\n"
"InnoDB: You can look for further help from\n"
@@ -3704,17 +3706,17 @@ end:
"InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
"InnoDB: to have the same internal name in case-insensitive comparison.\n"
"InnoDB: 2) table ", stderr);
- ut_print_name(stderr, trx, new_name);
+ ut_print_name(stderr, trx, TRUE, new_name);
fputs(" exists in the InnoDB internal data\n"
"InnoDB: dictionary though MySQL is trying rename table ", stderr);
- ut_print_name(stderr, trx, old_name);
+ ut_print_name(stderr, trx, TRUE, old_name);
fputs(" to it.\n"
"InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n"
"InnoDB: You can look for further help from\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/"
"InnoDB_troubleshooting_datadict.html\n"
"InnoDB: If table ", stderr);
- ut_print_name(stderr, trx, new_name);
+ ut_print_name(stderr, trx, TRUE, new_name);
fputs(
" is a temporary table #sql..., then it can be that\n"
"InnoDB: there are still queries running on the table, and it will be\n"
@@ -3742,9 +3744,9 @@ end:
ut_print_timestamp(stderr);
fputs(" InnoDB: Error in table rename, cannot rename ",
stderr);
- ut_print_name(stderr, trx, old_name);
+ ut_print_name(stderr, trx, TRUE, old_name);
fputs(" to ", stderr);
- ut_print_name(stderr, trx, new_name);
+ ut_print_name(stderr, trx, TRUE, new_name);
putc('\n', stderr);
err = DB_ERROR;
@@ -3763,7 +3765,7 @@ end:
if (old_is_tmp) {
fputs(" InnoDB: Error: in ALTER TABLE ",
stderr);
- ut_print_name(stderr, trx, new_name);
+ ut_print_name(stderr, trx, TRUE, new_name);
fputs("\n"
"InnoDB: has or is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n",
@@ -3772,7 +3774,7 @@ end:
fputs(
" InnoDB: Error: in RENAME TABLE table ",
stderr);
- ut_print_name(stderr, trx, new_name);
+ ut_print_name(stderr, trx, TRUE, new_name);
fputs("\n"
"InnoDB: is referenced in foreign key constraints\n"
"InnoDB: which are not compatible with the new table definition.\n",
@@ -3788,6 +3790,8 @@ end:
}
funct_exit:
+ trx_commit_for_mysql(trx);
+
if (!recovering_temp_table) {
row_mysql_unlock_data_dictionary(trx);
}
@@ -3796,8 +3800,6 @@ funct_exit:
mem_heap_free(heap);
}
- trx_commit_for_mysql(trx);
-
trx->op_info = "";
return((int) err);
@@ -3986,7 +3988,7 @@ row_check_table_for_mysql(
while (index != NULL) {
/* fputs("Validating index ", stderr);
- ut_print_name(stderr, index->name);
+ ut_print_name(stderr, trx, FALSE, index->name);
putc('\n', stderr); */
if (!btr_validate_tree(index->tree, prebuilt->trx)) {
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index b7581fa3644..1ef24f8e957 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -520,7 +520,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/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c
index 24464ab5b99..50ad462f4aa 100644
--- a/storage/innobase/row/row0row.c
+++ b/storage/innobase/row/row0row.c
@@ -480,12 +480,12 @@ row_build_row_ref_in_tuple(
ut_a(ref && index && rec);
- if (!index->table) {
+ if (UNIV_UNLIKELY(!index->table)) {
fputs("InnoDB: table ", stderr);
notfound:
- ut_print_name(stderr, trx, index->table_name);
+ ut_print_name(stderr, trx, TRUE, index->table_name);
fputs(" for index ", stderr);
- ut_print_name(stderr, trx, index->name);
+ ut_print_name(stderr, trx, FALSE, index->name);
fputs(" not found\n", stderr);
ut_error;
}
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index c0f906f4ed7..a3360bff952 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -302,19 +302,45 @@ row_sel_fetch_columns(
}
while (column) {
+ mem_heap_t* heap = NULL;
+ ibool needs_copy;
+
field_no = column->field_nos[index_type];
if (field_no != ULINT_UNDEFINED) {
- data = rec_get_nth_field(rec, offsets, field_no, &len);
+ if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
+ field_no))) {
+
+ /* Copy an externally stored field to the
+ temporary heap */
+
+ heap = mem_heap_create(1);
+
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets, field_no, &len, heap);
+
+ ut_a(len != UNIV_SQL_NULL);
- if (column->copy_val) {
+ needs_copy = TRUE;
+ } else {
+ data = rec_get_nth_field(rec, offsets,
+ field_no, &len);
+
+ needs_copy = column->copy_val;
+ }
+
+ if (needs_copy) {
eval_node_copy_and_alloc_val(column, data,
len);
} else {
val = que_node_get_val(column);
dfield_set_data(val, data, len);
}
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
}
column = UT_LIST_GET_NEXT(col_var_list, column);
@@ -2036,8 +2062,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, " <NULL>;");
+ }
+
fprintf(stderr, "\n");
exp = que_node_get_next(exp);
@@ -2542,6 +2573,7 @@ row_sel_store_mysql_rec(
{
mysql_row_templ_t* templ;
mem_heap_t* extern_field_heap = NULL;
+ mem_heap_t* heap;
byte* data;
ulint len;
ulint i;
@@ -2558,9 +2590,6 @@ row_sel_store_mysql_rec(
templ = prebuilt->mysql_template + i;
- data = rec_get_nth_field(rec, offsets,
- templ->rec_field_no, &len);
-
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
templ->rec_field_no))) {
@@ -2569,7 +2598,19 @@ row_sel_store_mysql_rec(
ut_a(!prebuilt->trx->has_search_latch);
- extern_field_heap = mem_heap_create(UNIV_PAGE_SIZE);
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap =
+ mem_heap_create(UNIV_PAGE_SIZE);
+ }
+
+ heap = prebuilt->blob_heap;
+ } else {
+ extern_field_heap =
+ mem_heap_create(UNIV_PAGE_SIZE);
+
+ heap = extern_field_heap;
+ }
/* NOTE: if we are retrieving a big BLOB, we may
already run out of memory in the next call, which
@@ -2577,54 +2618,17 @@ row_sel_store_mysql_rec(
data = btr_rec_copy_externally_stored_field(rec,
offsets, templ->rec_field_no, &len,
- extern_field_heap);
+ heap);
ut_a(len != UNIV_SQL_NULL);
+ } else {
+ /* Field is stored in the row. */
+
+ data = rec_get_nth_field(rec, offsets,
+ templ->rec_field_no, &len);
}
if (len != UNIV_SQL_NULL) {
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
-
- ut_a(prebuilt->templ_contains_blob);
-
- /* A heuristic test that we can allocate the
- memory for a big BLOB. We have a safety margin
- of 1000000 bytes. Since the test takes some
- CPU time, we do not use it for small BLOBs. */
-
- if (UNIV_UNLIKELY(len > 2000000)
- && UNIV_UNLIKELY(!ut_test_malloc(
- len + 1000000))) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
-" InnoDB: Warning: could not allocate %lu + 1000000 bytes to retrieve\n"
-"InnoDB: a big column. Table name ", (ulong) len);
- ut_print_name(stderr,
- prebuilt->trx,
- prebuilt->table->name);
- putc('\n', stderr);
-
- if (extern_field_heap) {
- mem_heap_free(
- extern_field_heap);
- }
- return(FALSE);
- }
-
- /* Copy the BLOB data to the BLOB heap of
- prebuilt */
-
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap =
- mem_heap_create(len);
- }
-
- data = memcpy(mem_heap_alloc(
- prebuilt->blob_heap, len),
- data, len);
- }
-
row_sel_field_store_in_mysql_format(
mysql_rec + templ->mysql_col_offset,
templ, data, len);
@@ -3244,7 +3248,7 @@ row_search_for_mysql(
"InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name ",
(ulong) prebuilt->magic_n);
- ut_print_name(stderr, trx, prebuilt->table->name);
+ ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
putc('\n', stderr);
mem_analyze_corruption(prebuilt);
@@ -3530,15 +3534,13 @@ shortcut_fails_too_big_rec:
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
&& prebuilt->select_lock_type != LOCK_NONE
- && trx->mysql_query_str) {
+ && trx->mysql_query_str && trx->mysql_thd) {
/* Scan the MySQL query string; check if SELECT is the first
word there */
- ibool success;
- dict_accept(*trx->mysql_query_str, "SELECT", &success);
-
- if (success) {
+ if (dict_str_starts_with_keyword(trx->mysql_thd,
+ *trx->mysql_query_str, "SELECT")) {
/* It is a plain locking SELECT and the isolation
level is low: do not lock gaps */
@@ -4402,7 +4404,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/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 4023283a60c..7be2fb17a07 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/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/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 83cdcaa271b..c7bff806674 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -68,6 +68,9 @@ ibool srv_error_monitor_active = FALSE;
const char* srv_main_thread_op_info = "";
+/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
+
/* Server parameters which are read from the initfile */
/* The following three are dir paths which are catenated before file
@@ -849,11 +852,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));
@@ -2559,18 +2560,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);
-
- OS_THREAD_DUMMY_RETURN;
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index da2deac123d..205b54004ce 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -108,12 +108,45 @@ 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
+static
+char*
+srv_parse_megabytes(
+/*================*/
+ /* out: next character in string */
+ char* str, /* in: string containing a quantity in bytes */
+ ulint* megs) /* out: the number in megabytes */
+{
+ char* endp;
+ ulint size;
+
+ size = strtoul(str, &endp, 10);
+
+ str = endp;
+
+ switch (*str) {
+ case 'G': case 'g':
+ size *= 1024;
+ /* fall through */
+ case 'M': case 'm':
+ str++;
+ break;
+ default:
+ size /= 1024 * 1024;
+ break;
+ }
+
+ *megs = size;
+ return(str);
+}
+
/*************************************************************************
Reads the data files and their sizes from a character string given in
the .cnf file. */
@@ -138,7 +171,6 @@ srv_parse_data_file_paths_and_sizes(
last file if specified, 0 if not */
{
char* input_str;
- char* endp;
char* path;
ulint size;
ulint i = 0;
@@ -168,18 +200,7 @@ srv_parse_data_file_paths_and_sizes(
str++;
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if (*str != 'M' && *str != 'G') {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
+ str = srv_parse_megabytes(str, &size);
if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
@@ -189,18 +210,7 @@ srv_parse_data_file_paths_and_sizes(
str += (sizeof ":max:") - 1;
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if (*str != 'M' && *str != 'G') {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
+ str = srv_parse_megabytes(str, &size);
}
if (*str != '\0') {
@@ -273,18 +283,7 @@ srv_parse_data_file_paths_and_sizes(
str++;
}
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if ((*str != 'M') && (*str != 'G')) {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
+ str = srv_parse_megabytes(str, &size);
(*data_file_names)[i] = path;
(*data_file_sizes)[i] = size;
@@ -299,20 +298,8 @@ srv_parse_data_file_paths_and_sizes(
str += (sizeof ":max:") - 1;
- size = strtoul(str, &endp, 10);
-
- str = endp;
-
- if (*str != 'M' && *str != 'G') {
- size = size / (1024 * 1024);
- } else if (*str == 'G') {
- size = size * 1024;
- str++;
- } else {
- str++;
- }
-
- *max_auto_extend_size = size;
+ str = srv_parse_megabytes(str,
+ max_auto_extend_size);
}
if (*str != '\0') {
@@ -934,8 +921,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);
}
@@ -1167,8 +1153,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) +
@@ -1189,15 +1175,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);
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index fb7ec4cc78b..81986cdfd33 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/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/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 673e1080d89..ffc2633b467 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/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/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index 6354830df70..04f03e89ec5 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/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/storage/innobase/thr/thr0loc.c b/storage/innobase/thr/thr0loc.c
index 2a7a6c1c21f..c63520e8a07 100644
--- a/storage/innobase/thr/thr0loc.c
+++ b/storage/innobase/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/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
index be949079f80..79f38b1ee52 100644
--- a/storage/innobase/trx/trx0purge.c
+++ b/storage/innobase/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/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c
index d8a5cce22e9..55723df48c5 100644
--- a/storage/innobase/trx/trx0rec.c
+++ b/storage/innobase/trx/trx0rec.c
@@ -843,7 +843,7 @@ trx_undo_update_rec_get_update(
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n"
"InnoDB: Run also CHECK TABLE ",
(ulong) dict_index_get_n_fields(index));
- ut_print_name(stderr, trx, index->table_name);
+ ut_print_name(stderr, trx, TRUE, index->table_name);
fprintf(stderr, "\n"
"InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
(ulong) n_fields, (ulong) i, ptr);
diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c
index af74cfe9032..2e7a5aa7b68 100644
--- a/storage/innobase/trx/trx0roll.c
+++ b/storage/innobase/trx/trx0roll.c
@@ -241,7 +241,7 @@ trx_rollback_to_savepoint_for_mysql(
if (trx->conc_state == TRX_NOT_STARTED) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: transaction has a savepoint ", stderr);
- ut_print_name(stderr, trx, savep->name);
+ ut_print_name(stderr, trx, FALSE, savep->name);
fputs(" though it is not started\n", stderr);
return(DB_ERROR);
}
@@ -540,11 +540,11 @@ 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);
- ut_print_name(stderr, trx, table->name);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs(" in recovery\n", stderr);
err = row_drop_table_for_mysql(table->name, trx, TRUE);
diff --git a/storage/innobase/trx/trx0rseg.c b/storage/innobase/trx/trx0rseg.c
index f396666e7c9..5136174d110 100644
--- a/storage/innobase/trx/trx0rseg.c
+++ b/storage/innobase/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/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index bd1bceef7da..8f24a54208a 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -101,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/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index a3115e332cd..5f191f4599b 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/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/storage/innobase/ut/Makefile.am b/storage/innobase/ut/Makefile.am
index c833a6d5a4c..fa4eeb2e9c9 100644
--- a/storage/innobase/ut/Makefile.am
+++ b/storage/innobase/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/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c
index 2157a71116a..a9391cd3adc 100644
--- a/storage/innobase/ut/ut0dbg.c
+++ b/storage/innobase/ut/ut0dbg.c
@@ -14,19 +14,21 @@ Created 1/30/1994 Heikki Tuuri
ulint ut_dbg_zero = 0;
#endif
+#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
/* If this is set to TRUE all threads will stop into the next assertion
and assert */
ibool ut_dbg_stop_threads = FALSE;
+#endif
#ifdef __NETWARE__
ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there
happens an InnoDB assertion failure or other
fatal error condition that requires an
immediate shutdown. */
-#else /* __NETWARE__ */
+#elif !defined(UT_DBG_USE_ABORT)
/* Null pointer used to generate memory trap */
ulint* ut_dbg_null_ptr = NULL;
-#endif /* __NETWARE__ */
+#endif
/*****************************************************************
Report a failed assertion. */
@@ -56,7 +58,9 @@ ut_dbg_assertion_failed(
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
+#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
ut_dbg_stop_threads = TRUE;
+#endif
}
#ifdef __NETWARE__
@@ -74,6 +78,7 @@ ut_dbg_panic(void)
exit(1);
}
#else /* __NETWARE__ */
+# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
/*****************************************************************
Stop a thread after assertion failure. */
@@ -87,4 +92,5 @@ ut_dbg_stop_thread(
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
}
+# endif
#endif /* __NETWARE__ */
diff --git a/storage/innobase/ut/ut0list.c b/storage/innobase/ut/ut0list.c
new file mode 100644
index 00000000000..a0db7ff7b55
--- /dev/null
+++ b/storage/innobase/ut/ut0list.c
@@ -0,0 +1,169 @@
+#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;
+ list->is_heap_list = FALSE;
+
+ return(list);
+}
+
+/********************************************************************
+Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
+lists created with this function. */
+
+ib_list_t*
+ib_list_create_heap(
+/*================*/
+ /* out: list */
+ mem_heap_t* heap) /* in: memory heap to use */
+{
+ ib_list_t* list = mem_heap_alloc(heap, sizeof(ib_list_t));
+
+ list->first = NULL;
+ list->last = NULL;
+ list->is_heap_list = TRUE;
+
+ return(list);
+}
+
+/********************************************************************
+Free a list. */
+
+void
+ib_list_free(
+/*=========*/
+ ib_list_t* list) /* in: list */
+{
+ ut_a(!list->is_heap_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/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
index 48435fe6155..6d81c113e42 100644
--- a/storage/innobase/ut/ut0ut.c
+++ b/storage/innobase/ut/ut0ut.c
@@ -20,18 +20,20 @@ Created 5/11/1994 Heikki Tuuri
ibool ut_always_false = FALSE;
+#ifndef UNIV_HOTBACKUP
/*********************************************************************
-Get the quote character to be used in SQL identifiers.
+Display an SQL identifier.
This definition must match the one in sql/ha_innodb.cc! */
extern
-int
-mysql_get_identifier_quote_char(
-/*============================*/
- /* out: quote character to be
- used in SQL identifiers; EOF if none */
+void
+innobase_print_identifier(
+/*======================*/
+ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen);/* in: length of name */
+#endif /* !UNIV_HOTBACKUP */
/************************************************************
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
@@ -398,9 +400,10 @@ ut_print_name(
/*==========*/
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name) /* in: name to print */
{
- ut_print_namel(f, trx, name, strlen(name));
+ ut_print_namel(f, trx, table_id, name, strlen(name));
}
/**************************************************************************
@@ -411,29 +414,27 @@ ut_print_namel(
/*===========*/
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction (NULL=no quotes) */
+ ibool table_id,/* in: TRUE=decode table name */
const char* name, /* in: name to print */
ulint namelen)/* in: length of name */
{
- const char* s = name;
- const char* e = s + namelen;
#ifdef UNIV_HOTBACKUP
- int q = '"';
+ fwrite(name, 1, namelen, f);
#else
- int q = mysql_get_identifier_quote_char(trx, name, namelen);
-#endif
- if (q == EOF) {
- fwrite(name, 1, namelen, f);
- return;
+ char* slash = strchr(name, '/');
+
+ if (UNIV_LIKELY_NULL(slash)) {
+ /* Print the database name and table name separately. */
+ ut_ad(table_id);
+
+ innobase_print_identifier(f, trx, TRUE, name, slash - name);
+ putc('.', f);
+ innobase_print_identifier(f, trx, TRUE, slash + 1,
+ namelen - (slash - name) - 1);
+ } else {
+ innobase_print_identifier(f, trx, table_id, name, namelen);
}
- putc(q, f);
- while (s < e) {
- int c = *s++;
- if (c == q) {
- putc(c, f);
- }
- putc(c, f);
- }
- putc(q, f);
+#endif
}
/**************************************************************************
diff --git a/storage/innobase/ut/ut0wqueue.c b/storage/innobase/ut/ut0wqueue.c
new file mode 100644
index 00000000000..2a6d8c19ef0
--- /dev/null
+++ b/storage/innobase/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);
+}