From 50de7d13036c7bacbaf460bfcaa77cfbe1ad4123 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 18 Jan 2018 01:41:52 +0200 Subject: [PATCH 1/6] Fixed MDEV-14326 engine ARIA with row_format=FIXED is broken The problem was that max_size was acciently set to 1 in some cases. Other things: - Adjust max_rows if min_rows > max_rows. - Removed not used variable varchar_length - Adjusted max_pack_length (safety fix) --- mysql-test/suite/maria/max_length.result | 105 +++++++++++++++++++++++ mysql-test/suite/maria/max_length.test | 72 ++++++++++++++++ storage/maria/ma_create.c | 15 ++-- 3 files changed, 184 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/maria/max_length.result b/mysql-test/suite/maria/max_length.result index 049b92eafe5..177810f32a3 100644 --- a/mysql-test/suite/maria/max_length.result +++ b/mysql-test/suite/maria/max_length.result @@ -54,3 +54,108 @@ Table Op Msg_type Msg_text test.t1 check warning Datafile is almost full, 268230656 of 268320768 used test.t1 check status OK drop table t1,t2; +create table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED min_rows=1000000; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 MIN_ROWS=1000000 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED +insert into t1 select seq,seq from seq_1_to_100000; +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED +insert into t1 select seq,seq from seq_1_to_100000; +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE TRANSACTIONAL=0; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE TRANSACTIONAL=0 +insert into t1 select seq,seq from seq_1_to_100000; +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED MAX_ROWS=10; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=FIXED +insert into t1 select seq,seq from seq_1_to_100000; +ERROR HY000: The table 't1' is full +select count(*) from t1; +count(*) +65535 +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=DYNAMIC MAX_ROWS=10; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=DYNAMIC +insert into t1 select seq,seq from seq_1_to_100000; +ERROR HY000: The table 't1' is full +select count(*) from t1; +count(*) +3276 +check table t1; +Table Op Msg_type Msg_text +test.t1 check warning Datafile is almost full, 65520 of 65535 used +test.t1 check status OK +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE +insert into t1 select seq,seq from seq_1_to_100000; +select count(*) from t1; +count(*) +100000 +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned DEFAULT NULL, + `c2` char(80) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 MAX_ROWS=10 PAGE_CHECKSUM=1 ROW_FORMAT=PAGE +insert into t1 select seq,seq from seq_1_to_10000000; +ERROR HY000: The table 't1' is full +select count(*) from t1; +count(*) +6189940 +check table t1; +Table Op Msg_type Msg_text +test.t1 check warning Datafile is almost full, 268320768 of 268320768 used +test.t1 check status OK +drop table t1; diff --git a/mysql-test/suite/maria/max_length.test b/mysql-test/suite/maria/max_length.test index 68ad1e22aa9..2be3da8e1b0 100644 --- a/mysql-test/suite/maria/max_length.test +++ b/mysql-test/suite/maria/max_length.test @@ -2,6 +2,7 @@ # This test will use around 1.3G of disk space! --source include/have_maria.inc +--source include/have_sequence.inc --source include/big_test.inc drop table if exists t1,t2; @@ -50,3 +51,74 @@ insert into t1 (v,b) select v,b from t2; check table t1; drop table t1,t2; + +# +# Check that we don't get table-is-full +# + +create table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED min_rows=1000000; +show create table t1; +insert into t1 select seq,seq from seq_1_to_100000; + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED; +show create table t1; +insert into t1 select seq,seq from seq_1_to_100000; + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE TRANSACTIONAL=0; +show create table t1; +insert into t1 select seq,seq from seq_1_to_100000; + +# +# For these we should get table is full error +# + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=FIXED MAX_ROWS=10; +show create table t1; +--error ER_RECORD_FILE_FULL +insert into t1 select seq,seq from seq_1_to_100000; +select count(*) from t1; + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=DYNAMIC MAX_ROWS=10; +show create table t1; +--error ER_RECORD_FILE_FULL +insert into t1 select seq,seq from seq_1_to_100000; +select count(*) from t1; +check table t1; + +# PAGE uses 3 byte pointers as minimum, which can handle up to 200M files + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10; +show create table t1; +insert into t1 select seq,seq from seq_1_to_100000; +select count(*) from t1; +check table t1; +drop table t1; + +create or replace table t1 ( +c1 int unsigned, +c2 char(80) +) Engine=ARIA ROW_FORMAT=PAGE MAX_ROWS=10; +show create table t1; +--error ER_RECORD_FILE_FULL +insert into t1 select seq,seq from seq_1_to_10000000; +select count(*) from t1; +check table t1; +drop table t1; diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 2c67195b3f8..94c4c250bef 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -70,7 +70,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, myf create_flag; uint length,max_key_length,packed,pack_bytes,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length, - base_pos,long_varchar_count,varchar_length, + base_pos,long_varchar_count, unique_key_parts,fulltext_keys,offset, not_block_record_extra_length; uint max_field_lengths, extra_header_size, column_nr; uint internal_table= flags & HA_CREATE_INTERNAL_TABLE; @@ -144,9 +144,6 @@ int maria_create(const char *name, enum data_file_type datafile_type, datafile_type= BLOCK_RECORD; } - if (ci->reloc_rows > ci->max_rows) - ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */ - if (!(rec_per_key_part= (double*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(double) + (keys + uniques)*HA_MAX_KEY_SEG*sizeof(ulong) + @@ -160,7 +157,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, /* Start by checking fields and field-types used */ - varchar_length=long_varchar_count=packed= not_block_record_extra_length= + long_varchar_count=packed= not_block_record_extra_length= pack_reclength= max_field_lengths= 0; reclength= min_pack_length= ci->null_bytes; forced_packed= 0; @@ -232,7 +229,6 @@ int maria_create(const char *name, enum data_file_type datafile_type, } else if (type == FIELD_VARCHAR) { - varchar_length+= column->length-1; /* Used for min_pack_length */ pack_reclength++; not_block_record_extra_length++; max_field_lengths++; @@ -368,6 +364,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, pack_bytes); if (!ci->data_file_length && ci->max_rows) { + set_if_bigger(ci->max_rows, ci->reloc_rows); if (pack_reclength == INT_MAX32 || (~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength) ci->data_file_length= ~(ulonglong) 0; @@ -401,13 +398,14 @@ int maria_create(const char *name, enum data_file_type datafile_type, else ci->max_rows= data_file_length / (min_pack_length + extra_header_size + - DIR_ENTRY_SIZE)+1; + DIR_ENTRY_SIZE); } else ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length + ((options & HA_OPTION_PACK_RECORD) ? - 3 : 0)))+1; + 3 : 0))); + set_if_smaller(ci->reloc_rows, ci->max_rows); } max_rows= (ulonglong) ci->max_rows; if (datafile_type == BLOCK_RECORD) @@ -800,6 +798,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, share.state.state.data_file_length= maria_block_size; /* Add length of packed fields + length */ share.base.pack_reclength+= share.base.max_field_lengths+3; + share.base.max_pack_length= share.base.pack_reclength; /* Adjust max_pack_length, to be used if we have short rows */ if (share.base.max_pack_length < maria_block_size) From cc915cd59973a9eaccdeb2ca4c30ab4d8878ea43 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 18 Jan 2018 01:42:51 +0200 Subject: [PATCH 2/6] Fixed some build scripts to work with gprof and gcov --- BUILD/SETUP.sh | 1 + BUILD/compile-pentium-gprof | 2 +- BUILD/compile-pentium64-gcov | 2 +- BUILD/compile-pentium64-gprof | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 2d6548dda0e..3a1a861f2f8 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -307,3 +307,4 @@ gprof_compile_flags="-O2 -pg -g" gprof_link_flags="--disable-shared $static_link" +disable_gprof_plugins="--with-zlib-dir=bundled --without-plugin-oqgraph --without-plugin-mroonga" diff --git a/BUILD/compile-pentium-gprof b/BUILD/compile-pentium-gprof index de014e3ae8b..498c964df74 100755 --- a/BUILD/compile-pentium-gprof +++ b/BUILD/compile-pentium-gprof @@ -19,6 +19,6 @@ path=`dirname $0` . "$path/SETUP.sh" extra_flags="$pentium_cflags $gprof_compile_flags" -extra_configs="$pentium_configs $debug_configs $gprof_link_flags $disable_64_bit_plugins" +extra_configs="$pentium_configs $debug_configs $gprof_link_flags $disable_64_bit_plugins $disable_gprof_plugins" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium64-gcov b/BUILD/compile-pentium64-gcov index 9587c51b4e0..6e3366c79bd 100755 --- a/BUILD/compile-pentium64-gcov +++ b/BUILD/compile-pentium64-gcov @@ -28,6 +28,6 @@ export LDFLAGS="$gcov_link_flags" extra_flags="$pentium64_cflags $max_cflags $gcov_compile_flags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs" +extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs --without-oqgraph" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium64-gprof b/BUILD/compile-pentium64-gprof index b7821e06b6e..346777a4611 100755 --- a/BUILD/compile-pentium64-gprof +++ b/BUILD/compile-pentium64-gprof @@ -20,6 +20,6 @@ path=`dirname $0` . "$path/SETUP.sh" extra_flags="$pentium64_cflags $gprof_compile_flags" -extra_configs="$pentium_configs $max_configs $gprof_link_flags --with-zlib-dir=bundled" +extra_configs="$pentium_configs $max_configs $gprof_link_flags $disable_gprof_plugins" . "$path/FINISH.sh" From 6c09a6542e94d2bcaaa7d03abe6b6cab40083f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 18 Jan 2018 16:13:50 +0200 Subject: [PATCH 3/6] MDEV-14985 innodb_undo_log_truncate may be blocked if transactions were recovered at startup The field trx_rseg_t::trx_ref_count that was added in WL#6965 in MySQL 5.7.5 is being incremented twice if a recovered transaction includes both undo log partitions insert_undo and update_undo. This reference count is being used in trx_purge(), which invokes trx_purge_initiate_truncate() to try to truncate an undo tablespace file. Because of the double-increment, the trx_ref_count would never reach 0. It is possible that after the failed truncation attempt, the undo tablespace would be disabled for logging any new transactions until the server is restarted (hopefully after committing or rolling back all transactions, so that no transactions would be recovered on the next startup). trx_resurrect_insert(), trx_resurrect_update(): Do not increment trx_ref_count. Instead, let the caller do that. trx_lists_init_at_db_start(): Increment rseg->trx_ref_count only once for each recovered transaction. Adjust comments. Finally, if innodb_force_recovery prevents the undo log scan, do not bother iterating the empty lists. --- storage/innobase/trx/trx0trx.cc | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index ed334207b4c..0e488d6379a 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -824,10 +824,6 @@ trx_resurrect_insert( ut_d(trx->start_line = __LINE__); trx->rsegs.m_redo.rseg = rseg; - /* For transactions with active data will not have rseg size = 1 - or will not qualify for purge limit criteria. So it is safe to increment - this trx_ref_count w/o mutex protection. */ - ++trx->rsegs.m_redo.rseg->trx_ref_count; *trx->xid = undo->xid; trx->id = undo->trx_id; trx->rsegs.m_redo.insert_undo = undo; @@ -934,10 +930,6 @@ trx_resurrect_update( trx_rseg_t* rseg) /*!< in/out: rollback segment */ { trx->rsegs.m_redo.rseg = rseg; - /* For transactions with active data will not have rseg size = 1 - or will not qualify for purge limit criteria. So it is safe to increment - this trx_ref_count w/o mutex protection. */ - ++trx->rsegs.m_redo.rseg->trx_ref_count; *trx->xid = undo->xid; trx->id = undo->trx_id; trx->rsegs.m_redo.update_undo = undo; @@ -991,10 +983,12 @@ trx_lists_init_at_db_start() purge_sys = UT_NEW_NOKEY(purge_sys_t()); - if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) { - trx_rseg_array_init(); + if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { + return; } + trx_rseg_array_init(); + /* Look from the rollback segments if there exist undo logs for transactions. */ @@ -1002,8 +996,9 @@ trx_lists_init_at_db_start() trx_undo_t* undo; trx_rseg_t* rseg = trx_sys->rseg_array[i]; - /* At this stage non-redo rseg slots are all NULL as they are - re-created on server start and existing slots are not read. */ + /* Some rollback segment may be unavailable, + especially if the server was previously run with a + non-default value of innodb_undo_logs. */ if (rseg == NULL) { continue; } @@ -1013,6 +1008,11 @@ trx_lists_init_at_db_start() undo != NULL; undo = UT_LIST_GET_NEXT(undo_list, undo)) { + /* trx_purge() will not run before we return, + so we can safely increment this without + holding rseg->mutex. */ + ++rseg->trx_ref_count; + trx_t* trx; trx = trx_resurrect_insert(undo, rseg); @@ -1037,6 +1037,7 @@ trx_lists_init_at_db_start() if (trx == NULL) { trx = trx_allocate_for_background(); + ++rseg->trx_ref_count; ut_d(trx->start_file = __FILE__); ut_d(trx->start_line = __LINE__); From 30289a2713807dbca9b2560634379a5bd9ea86e8 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 18 Jan 2018 15:56:28 -0800 Subject: [PATCH 4/6] Fixed mdev-14969 Non-recursive Common Table Expressions used in view caused an error The function subselect_single_select_engine::print() did not print the WITH clause attached to a subselect with single select engine. As a result views using suqueries with attached WITH clauses lost these clauses when saved in frm files. --- mysql-test/r/cte_nonrecursive.result | 74 ++++++++++++++++++++++++++++ mysql-test/t/cte_nonrecursive.test | 47 ++++++++++++++++++ sql/item_subselect.cc | 3 ++ 3 files changed, 124 insertions(+) diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index c1f4c9fd486..4f193384d0f 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -1295,3 +1295,77 @@ TERM03 TERM03 TERM01 NULL NULL TERM04 drop table t1,t2; +# +# MDEV-14969: view using subquery with attached CTE +# +create table region ( +r_regionkey int, +r_name char(25), +primary key (r_regionkey) +); +insert into region values +(0,'AFRICA'), (1,'AMERICA'), (2,'ASIA'), (3,'EUROPE'), (4,'MIDDLE EAST'); +create table nation ( +n_nationkey int, +n_name char(25), +n_regionkey int, +primary key (n_nationkey), +key i_n_regionkey (n_regionkey) +); +insert into nation values +(0,'ALGERIA',0), (1,'ARGENTINA',1), (2,'BRAZIL',1), (3,'CANADA',1), +(4,'EGYPT',4), (5,'ETHIOPIA',0), (6,'FRANCE',3), (7,'GERMANY',3), +(8,'INDIA',2), (9,'INDONESIA',2), (10,'IRAN',4), (11,'IRAQ',4), +(12,'JAPAN',2), (13,'JORDAN',4), (14,'KENYA',0), (15,'MOROCCO',0), +(16,'MOZAMBIQUE',0), (17,'PERU',1), (18,'CHINA',2), (19,'ROMANIA',3), +(20,'SAUDI ARABIA',4), (21,'VIETNAM',2), (22,'RUSSIA',3), +(23,'UNITED KINGDOM',3), (24,'UNITED STATES',1); +select * from nation n ,region r +where n.n_regionkey = r.r_regionkey and +r.r_regionkey in +(with t as (select * from region where r_regionkey <= 3 ) +select r_regionkey from t where r_name <> "ASIA"); +n_nationkey n_name n_regionkey r_regionkey r_name +0 ALGERIA 0 0 AFRICA +5 ETHIOPIA 0 0 AFRICA +14 KENYA 0 0 AFRICA +15 MOROCCO 0 0 AFRICA +16 MOZAMBIQUE 0 0 AFRICA +1 ARGENTINA 1 1 AMERICA +2 BRAZIL 1 1 AMERICA +3 CANADA 1 1 AMERICA +17 PERU 1 1 AMERICA +24 UNITED STATES 1 1 AMERICA +6 FRANCE 3 3 EUROPE +7 GERMANY 3 3 EUROPE +19 ROMANIA 3 3 EUROPE +22 RUSSIA 3 3 EUROPE +23 UNITED KINGDOM 3 3 EUROPE +create view v as +select * from nation n ,region r +where n.n_regionkey = r.r_regionkey and +r.r_regionkey in +(with t as (select * from region where r_regionkey <= 3) +select r_regionkey from t where r_name <> "ASIA"); +show create view v; +View Create View character_set_client collation_connection +v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `n`.`n_nationkey` AS `n_nationkey`,`n`.`n_name` AS `n_name`,`n`.`n_regionkey` AS `n_regionkey`,`r`.`r_regionkey` AS `r_regionkey`,`r`.`r_name` AS `r_name` from (`nation` `n` join `region` `r`) where `n`.`n_regionkey` = `r`.`r_regionkey` and `r`.`r_regionkey` in (with t as (select `region`.`r_regionkey` AS `r_regionkey`,`region`.`r_name` AS `r_name` from `region` where `region`.`r_regionkey` <= 3)select `t`.`r_regionkey` from `t` where `t`.`r_name` <> 'ASIA') latin1 latin1_swedish_ci +select * from v; +n_nationkey n_name n_regionkey r_regionkey r_name +0 ALGERIA 0 0 AFRICA +5 ETHIOPIA 0 0 AFRICA +14 KENYA 0 0 AFRICA +15 MOROCCO 0 0 AFRICA +16 MOZAMBIQUE 0 0 AFRICA +1 ARGENTINA 1 1 AMERICA +2 BRAZIL 1 1 AMERICA +3 CANADA 1 1 AMERICA +17 PERU 1 1 AMERICA +24 UNITED STATES 1 1 AMERICA +6 FRANCE 3 3 EUROPE +7 GERMANY 3 3 EUROPE +19 ROMANIA 3 3 EUROPE +22 RUSSIA 3 3 EUROPE +23 UNITED KINGDOM 3 3 EUROPE +drop view v; +drop table region, nation; diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test index 9436665bfee..a092a161277 100644 --- a/mysql-test/t/cte_nonrecursive.test +++ b/mysql-test/t/cte_nonrecursive.test @@ -882,3 +882,50 @@ union all where c1.term is null); drop table t1,t2; + +--echo # +--echo # MDEV-14969: view using subquery with attached CTE +--echo # + +create table region ( + r_regionkey int, + r_name char(25), + primary key (r_regionkey) +); +insert into region values +(0,'AFRICA'), (1,'AMERICA'), (2,'ASIA'), (3,'EUROPE'), (4,'MIDDLE EAST'); + +create table nation ( + n_nationkey int, + n_name char(25), + n_regionkey int, + primary key (n_nationkey), + key i_n_regionkey (n_regionkey) +); +insert into nation values +(0,'ALGERIA',0), (1,'ARGENTINA',1), (2,'BRAZIL',1), (3,'CANADA',1), +(4,'EGYPT',4), (5,'ETHIOPIA',0), (6,'FRANCE',3), (7,'GERMANY',3), +(8,'INDIA',2), (9,'INDONESIA',2), (10,'IRAN',4), (11,'IRAQ',4), +(12,'JAPAN',2), (13,'JORDAN',4), (14,'KENYA',0), (15,'MOROCCO',0), +(16,'MOZAMBIQUE',0), (17,'PERU',1), (18,'CHINA',2), (19,'ROMANIA',3), +(20,'SAUDI ARABIA',4), (21,'VIETNAM',2), (22,'RUSSIA',3), +(23,'UNITED KINGDOM',3), (24,'UNITED STATES',1); + +select * from nation n ,region r + where n.n_regionkey = r.r_regionkey and + r.r_regionkey in + (with t as (select * from region where r_regionkey <= 3 ) + select r_regionkey from t where r_name <> "ASIA"); + +create view v as +select * from nation n ,region r + where n.n_regionkey = r.r_regionkey and + r.r_regionkey in + (with t as (select * from region where r_regionkey <= 3) + select r_regionkey from t where r_name <> "ASIA"); + +show create view v; +select * from v; + +drop view v; +drop table region, nation; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 96d3bea6685..74f11ca6e41 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4373,6 +4373,9 @@ table_map subselect_union_engine::upper_select_const_tables() void subselect_single_select_engine::print(String *str, enum_query_type query_type) { + With_clause* with_clause= select_lex->get_with_clause(); + if (with_clause) + with_clause->print(str, query_type); select_lex->print(get_thd(), str, query_type); } From f67b8273c03b4802cb97e68b0c1baf5de330a2bf Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 21 Jan 2018 17:17:16 +0200 Subject: [PATCH 5/6] Fixed wrong arguments to printf in InnoDB --- storage/innobase/handler/ha_innodb.cc | 16 ++++++------ storage/innobase/handler/handler0alter.cc | 7 +++--- storage/innobase/row/row0import.cc | 30 +++++++++++------------ storage/innobase/row/row0merge.cc | 4 +-- storage/innobase/row/row0quiesce.cc | 28 ++++++++++----------- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b42da1c025e..198cfadc195 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2166,7 +2166,7 @@ convert_error_code_to_mysql( case DB_TOO_BIG_INDEX_COL: my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0), - DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)); + (ulong) DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)); return(HA_ERR_INDEX_COL_TOO_LONG); case DB_NO_SAVEPOINT: @@ -5287,7 +5287,6 @@ innobase_close_connection( "MariaDB is closing a connection that has an active " "InnoDB transaction. " TRX_ID_FMT " row modifications " "will roll back.", - " row modifications will roll back.", trx->undo_no); ut_d(ib::warn() << "trx: " << trx << " started on: " @@ -12132,7 +12131,7 @@ create_table_info_t::create_options_are_invalid() ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: invalid KEY_BLOCK_SIZE = %u." " Valid values are [1, 2, 4, 8, 16]", - m_create_info->key_block_size); + (uint) m_create_info->key_block_size); ret = "KEY_BLOCK_SIZE"; break; } @@ -12623,7 +12622,7 @@ index_bad: m_thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ignoring KEY_BLOCK_SIZE=%u.", - m_create_info->key_block_size); + (uint) m_create_info->key_block_size); } } @@ -12646,7 +12645,7 @@ index_bad: ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ignoring KEY_BLOCK_SIZE=%u" " unless ROW_FORMAT=COMPRESSED.", - m_create_info->key_block_size); + (uint) m_create_info->key_block_size); zip_allowed = false; } } else { @@ -14199,7 +14198,8 @@ ha_innobase::records_in_range( push_warning_printf( ha_thd(), Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT, - "btr_estimate_n_rows_in_range(): %f", n_rows); + "btr_estimate_n_rows_in_range(): %lld", + (longlong) n_rows); ); func_exit: @@ -22963,7 +22963,7 @@ ib_push_frm_error( "installations? See " REFMAN "innodb-troubleshooting.html\n", - ib_table->name); + ib_table->name.m_name); if (push_warning) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -23007,7 +23007,7 @@ ib_push_frm_error( "installations? See " REFMAN "innodb-troubleshooting.html\n", - ib_table->name, n_keys, + ib_table->name.m_name, n_keys, table->s->keys); if (push_warning) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 44c40d05b4c..9e6d81e21e4 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -300,7 +300,7 @@ my_error_innodb( break; case DB_TOO_BIG_INDEX_COL: my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0), - DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)); + (ulong) DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)); break; case DB_TOO_MANY_CONCURRENT_TRXS: my_error(ER_TOO_MANY_CONCURRENT_TRXS, MYF(0)); @@ -1636,7 +1636,7 @@ innobase_get_foreign_key_info( /* Not possible to add a foreign key without a referenced column */ mutex_exit(&dict_sys->mutex); - my_error(ER_CANNOT_ADD_FOREIGN, MYF(0), tbl_namep); + my_error(ER_CANNOT_ADD_FOREIGN, MYF(0)); goto err_exit; } @@ -2050,7 +2050,8 @@ innobase_check_index_keys( } #endif /* MYSQL_RENAME_INDEX */ - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key.name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), + key.name); return(ER_WRONG_NAME_FOR_INDEX); } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index a02f60c6800..473e0c25f86 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2463,7 +2463,7 @@ row_import_cfg_read_index_fields( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading index fields."); return(DB_IO_ERROR); @@ -2499,7 +2499,7 @@ row_import_cfg_read_index_fields( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while parsing table name."); return(err); @@ -2569,7 +2569,7 @@ row_import_read_index_data( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), msg); + (ulong) errno, strerror(errno), msg); ib::error() << "IO Error: " << msg; @@ -2644,7 +2644,7 @@ row_import_read_index_data( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while parsing index name."); return(err); @@ -2683,7 +2683,7 @@ row_import_read_indexes( if (fread(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading number of indexes."); return(DB_IO_ERROR); @@ -2769,7 +2769,7 @@ row_import_read_columns( if (fread(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading table column meta-data."); return(DB_IO_ERROR); @@ -2833,7 +2833,7 @@ row_import_read_columns( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while parsing table column name."); return(err); @@ -2864,7 +2864,7 @@ row_import_read_v1( if (fread(value, 1, sizeof(value), file) != sizeof(value)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading meta-data export hostname length."); return(DB_IO_ERROR); @@ -2892,7 +2892,7 @@ row_import_read_v1( ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while parsing export hostname."); return(err); @@ -2906,7 +2906,7 @@ row_import_read_v1( if (fread(value, 1, sizeof(value), file) != sizeof(value)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading meta-data table name length."); return(DB_IO_ERROR); @@ -2933,7 +2933,7 @@ row_import_read_v1( if (err != DB_SUCCESS) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while parsing table name."); return(err); @@ -2952,7 +2952,7 @@ row_import_read_v1( if (fread(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading autoinc value."); return(DB_IO_ERROR); @@ -2968,7 +2968,7 @@ row_import_read_v1( if (fread(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading meta-data header."); return(DB_IO_ERROR); @@ -3039,7 +3039,7 @@ row_import_read_meta_data( if (fread(&row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while reading meta-data version."); return(DB_IO_ERROR); @@ -3090,7 +3090,7 @@ row_import_read_cfg( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_READ_ERROR, - errno, strerror(errno), msg); + (ulong) errno, strerror(errno), msg); cfg.m_missing = true; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 017821fdf38..4776bcc3c25 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4702,8 +4702,8 @@ row_merge_build_indexes( "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - !old_table->is_readable() ? old_table->name : - new_table->name); + !old_table->is_readable() ? old_table->name.m_name : + new_table->name.m_name); goto func_exit; } diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 21cc67620f6..77cb35b8f21 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -67,7 +67,7 @@ row_quiesce_write_index_fields( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing index fields."); return(DB_IO_ERROR); @@ -87,7 +87,7 @@ row_quiesce_write_index_fields( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing index column."); return(DB_IO_ERROR); @@ -121,7 +121,7 @@ row_quiesce_write_indexes( if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing index count."); return(DB_IO_ERROR); @@ -175,7 +175,7 @@ row_quiesce_write_indexes( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing index meta-data."); return(DB_IO_ERROR); @@ -196,7 +196,7 @@ row_quiesce_write_indexes( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing index name."); return(DB_IO_ERROR); @@ -256,7 +256,7 @@ row_quiesce_write_table( if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing table column data."); return(DB_IO_ERROR); @@ -283,7 +283,7 @@ row_quiesce_write_table( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing column name."); return(DB_IO_ERROR); @@ -315,7 +315,7 @@ row_quiesce_write_header( if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing meta-data version number."); return(DB_IO_ERROR); @@ -345,7 +345,7 @@ row_quiesce_write_header( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing hostname."); return(DB_IO_ERROR); @@ -365,7 +365,7 @@ row_quiesce_write_header( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing table name."); return(DB_IO_ERROR); @@ -381,7 +381,7 @@ row_quiesce_write_header( if (fwrite(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing table autoinc value."); return(DB_IO_ERROR); @@ -405,7 +405,7 @@ row_quiesce_write_header( if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), + (ulong) errno, strerror(errno), "while writing table meta-data."); return(DB_IO_ERROR); @@ -458,7 +458,7 @@ row_quiesce_write_cfg( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), msg); + (ulong) errno, strerror(errno), msg); } if (fclose(file) != 0) { @@ -468,7 +468,7 @@ row_quiesce_write_cfg( ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, - errno, strerror(errno), msg); + (ulong) errno, strerror(errno), msg); } } From 6b7dcefdc83c4444ac8a4623b46810ff940528db Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 21 Jan 2018 20:16:22 +0200 Subject: [PATCH 6/6] Reset thd->lex->current_select for SP current_select may point to data from old parser states when calling a stored procedure with CALL The failure happens in Item::Item when testing if we are in having. Fixed by explicitely reseting current_select in do_execute_sp() and in sp_rcontext::create(). The later is also needed for stored functions(). --- sql/sp_rcontext.cc | 8 +++++++- sql/sql_parse.cc | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 08f942b7d6d..396f5b448fc 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -61,6 +61,7 @@ sp_rcontext *sp_rcontext::create(THD *thd, const sp_pcontext *root_parsing_ctx, Field *return_value_fld) { + SELECT_LEX *save_current_select; sp_rcontext *ctx= new (thd->mem_root) sp_rcontext(root_parsing_ctx, return_value_fld, thd->in_sub_stmt); @@ -68,14 +69,19 @@ sp_rcontext *sp_rcontext::create(THD *thd, if (!ctx) return NULL; + /* Reset current_select as it's checked in Item_ident::Item_ident */ + save_current_select= thd->lex->current_select; + thd->lex->current_select= 0; + if (ctx->alloc_arrays(thd) || ctx->init_var_table(thd) || ctx->init_var_items(thd)) { delete ctx; - return NULL; + ctx= 0; } + thd->lex->current_select= save_current_select; return ctx; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 21abc1a248c..99c57fc7cfa 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2876,6 +2876,12 @@ static bool do_execute_sp(THD *thd, sp_head *sp) ha_rows select_limit= thd->variables.select_limit; thd->variables.select_limit= HA_POS_ERROR; + /* + Reset current_select as it may point to random data as a + result of previous parsing. + */ + thd->lex->current_select= NULL; + /* We never write CALL statements into binlog: - If the mode is non-prelocked, each statement will be logged