From 0cafc1316410d118c0b6298daf4d923b3258c502 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Fri, 24 Aug 2018 01:59:02 +0530 Subject: [PATCH 1/6] MDEV-17073: Crash during read_histogram_for_table with optimizer_use_condition_selectivity set to 4 No need to read statistics for tables that are not USER tables. We allocate memory for structures to collect statistics only for USER TABLES. --- mysql-test/r/stat_tables.result | 13 +++++++++++++ mysql-test/r/stat_tables_innodb.result | 13 +++++++++++++ mysql-test/t/stat_tables.test | 12 ++++++++++++ sql/sql_statistics.cc | 3 +++ 4 files changed, 41 insertions(+) diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index c1457d5e91a..cd78d44462e 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -577,3 +577,16 @@ SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; +# +# MDEV-17023: Crash during read_histogram_for_table with optimizer_use_condition_selectivity set to 4 +# +set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables= PREFERABLY; +explain +SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL +1 SIMPLE user ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 2ac868e9341..02a07fa8bbb 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -604,5 +604,18 @@ SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; +# +# MDEV-17023: Crash during read_histogram_for_table with optimizer_use_condition_selectivity set to 4 +# +set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables= PREFERABLY; +explain +SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE PROFILING ALL NULL NULL NULL NULL NULL +1 SIMPLE user ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index d69b00618ea..a0b2a22b946 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -356,3 +356,15 @@ SELECT * FROM mysql.column_stats; DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-17023: Crash during read_histogram_for_table with optimizer_use_condition_selectivity set to 4 +--echo # + +set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables= PREFERABLY; +explain +SELECT * FROM INFORMATION_SCHEMA.PROFILING, mysql.user; +set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +set use_stat_tables=@save_use_stat_tables; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 537ede91710..cb75a5c2176 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3129,6 +3129,9 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table) { TABLE_SHARE *table_share= tl->table->s; + if (table_share && !(table_share->table_category == TABLE_CATEGORY_USER)) + continue; + if (table_share && table_share->stats_cb.stats_can_be_read && !table_share->stats_cb.stats_is_read) From f195286a3eae6328a1f90948205e90201c0479c5 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 24 Aug 2018 18:08:56 +0300 Subject: [PATCH 2/6] MDEV-17021 Server crash or assertion `length <= column->length' failure in write_block_record Problem was that the number of NULL bit's was record wrong in the .frm file because there could be more fields marked NOT_NULL after the number of not_null fields where recorded. Fixed by copying test for virtual fields from prepare_create_field() The code change, only the test, doesn't have to be merged to 10.3 as this is fixed there. --- mysql-test/suite/maria/create.result | 26 +++++++++++++++++++++++ mysql-test/suite/maria/create.test | 31 ++++++++++++++++++++++++++++ sql/sql_table.cc | 4 ++++ 3 files changed, 61 insertions(+) create mode 100644 mysql-test/suite/maria/create.result create mode 100644 mysql-test/suite/maria/create.test diff --git a/mysql-test/suite/maria/create.result b/mysql-test/suite/maria/create.result new file mode 100644 index 00000000000..83c5b8d22e4 --- /dev/null +++ b/mysql-test/suite/maria/create.result @@ -0,0 +1,26 @@ +CREATE OR REPLACE TABLE t1 ( +f1 DECIMAL(43,0) NOT NULL, +f2 TIME(4) NULL, +f3 BINARY(101) NULL, +f4 TIMESTAMP(4) NULL, +f5 DATETIME(1) NULL, +f6 SET('a','b','c') NOT NULL DEFAULT 'a', +f7 VARBINARY(2332) NOT NULL DEFAULT '', +f8 DATE NULL, +f9 BLOB NULL, +f10 MEDIUMINT(45) NOT NULL DEFAULT 0, +f11 YEAR NULL, +f12 BIT(58) NULL, +v2 TIME(1) AS (f2) VIRTUAL, +v3 BINARY(115) AS (f3) VIRTUAL, +v4 TIMESTAMP(3) AS (f4) VIRTUAL, +v7 VARBINARY(658) AS (f7) PERSISTENT, +v8 DATE AS (f8) PERSISTENT, +v9 TINYTEXT AS (f9) PERSISTENT, +v11 YEAR AS (f11) VIRTUAL +) ENGINE=Aria; +INSERT IGNORE INTO t1 (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12) VALUES +(0.8,'16:01:46',NULL,'2006-03-01 12:44:34','2029-10-10 21:27:53','a','foo','1989-12-24','bar',9,1975,b'1'); +Warnings: +Note 1265 Data truncated for column 'f1' at row 1 +DROP TABLE t1; diff --git a/mysql-test/suite/maria/create.test b/mysql-test/suite/maria/create.test new file mode 100644 index 00000000000..2e61a95d743 --- /dev/null +++ b/mysql-test/suite/maria/create.test @@ -0,0 +1,31 @@ +--source include/have_maria.inc + +# MDEV-17021 +# Server crash or assertion `length <= column->length' failure in +# write_block_record +# + +CREATE OR REPLACE TABLE t1 ( + f1 DECIMAL(43,0) NOT NULL, + f2 TIME(4) NULL, + f3 BINARY(101) NULL, + f4 TIMESTAMP(4) NULL, + f5 DATETIME(1) NULL, + f6 SET('a','b','c') NOT NULL DEFAULT 'a', + f7 VARBINARY(2332) NOT NULL DEFAULT '', + f8 DATE NULL, + f9 BLOB NULL, + f10 MEDIUMINT(45) NOT NULL DEFAULT 0, + f11 YEAR NULL, + f12 BIT(58) NULL, + v2 TIME(1) AS (f2) VIRTUAL, + v3 BINARY(115) AS (f3) VIRTUAL, + v4 TIMESTAMP(3) AS (f4) VIRTUAL, + v7 VARBINARY(658) AS (f7) PERSISTENT, + v8 DATE AS (f8) PERSISTENT, + v9 TINYTEXT AS (f9) PERSISTENT, + v11 YEAR AS (f11) VIRTUAL +) ENGINE=Aria; +INSERT IGNORE INTO t1 (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12) VALUES + (0.8,'16:01:46',NULL,'2006-03-01 12:44:34','2029-10-10 21:27:53','a','foo','1989-12-24','bar',9,1975,b'1'); +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9a2b4901d4e..f89a6d64fa6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3328,6 +3328,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } + /* Virtual fields are always NULL */ + if (sql_field->vcol_info) + sql_field->flags&= ~NOT_NULL_FLAG; + if (sql_field->sql_type == MYSQL_TYPE_SET || sql_field->sql_type == MYSQL_TYPE_ENUM) { From 490e220ad2cf14321f18841a3e6c60fcb12a322e Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 24 Aug 2018 21:03:22 +0300 Subject: [PATCH 3/6] MDEV-17067 Server crash in write_block_record Problem was that Create_field::create_length_to_internal_length() calculated a different pack_length for NEWDECIMAL compared to Field_new_decimal constructor which lead to some unused bytes in the middle of the record, which Aria didn't like. --- mysql-test/suite/maria/create.result | 9 ++++++++- mysql-test/suite/maria/create.test | 11 +++++++++++ sql/field.cc | 17 +++++++++++------ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/maria/create.result b/mysql-test/suite/maria/create.result index 83c5b8d22e4..82c6b8c9871 100644 --- a/mysql-test/suite/maria/create.result +++ b/mysql-test/suite/maria/create.result @@ -1,4 +1,4 @@ -CREATE OR REPLACE TABLE t1 ( +CREATE OR REPLACE TABLE t1 ( f1 DECIMAL(43,0) NOT NULL, f2 TIME(4) NULL, f3 BINARY(101) NULL, @@ -24,3 +24,10 @@ INSERT IGNORE INTO t1 (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12) VALUES Warnings: Note 1265 Data truncated for column 'f1' at row 1 DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a INT(45)); +INSERT IGNORE INTO t1 VALUES (1),(2); +CREATE OR REPLACE TABLE t2 ENGINE=Aria AS SELECT SUM(a) AS f1, IFNULL( 'qux', ExtractValue( 'foo', 'bar' ) ) AS f2 FROM t1; +select * from t2; +f1 f2 +3 qux +DROP TABLE t1, t2; diff --git a/mysql-test/suite/maria/create.test b/mysql-test/suite/maria/create.test index 2e61a95d743..8f2ffd7492f 100644 --- a/mysql-test/suite/maria/create.test +++ b/mysql-test/suite/maria/create.test @@ -29,3 +29,14 @@ CREATE OR REPLACE TABLE t1 ( INSERT IGNORE INTO t1 (f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12) VALUES (0.8,'16:01:46',NULL,'2006-03-01 12:44:34','2029-10-10 21:27:53','a','foo','1989-12-24','bar',9,1975,b'1'); DROP TABLE t1; + +# +# MDEV-17067 Server crash in write_block_record +# + +CREATE OR REPLACE TABLE t1 (a INT(45)); +INSERT IGNORE INTO t1 VALUES (1),(2); + +CREATE OR REPLACE TABLE t2 ENGINE=Aria AS SELECT SUM(a) AS f1, IFNULL( 'qux', ExtractValue( 'foo', 'bar' ) ) AS f2 FROM t1; +select * from t2; +DROP TABLE t1, t2; diff --git a/sql/field.cc b/sql/field.cc index a9a7d54929b..1427e055324 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9065,13 +9065,18 @@ void Create_field::create_length_to_internal_length(void) } break; case MYSQL_TYPE_NEWDECIMAL: - key_length= pack_length= - my_decimal_get_binary_size(my_decimal_length_to_precision(length, - decimals, - flags & - UNSIGNED_FLAG), - decimals); + { + /* + This code must be identical to code in + Field_new_decimal::Field_new_decimal as otherwise the record layout + gets out of sync. + */ + uint precision= my_decimal_length_to_precision(length, decimals, + flags & UNSIGNED_FLAG); + set_if_smaller(precision, DECIMAL_MAX_PRECISION); + key_length= pack_length= my_decimal_get_binary_size(precision, decimals); break; + } default: key_length= pack_length= calc_pack_length(sql_type, length); break; From 4ba6327f9560a23c128c2434d0fe6511d0d94452 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 16 Apr 2018 21:11:58 +0000 Subject: [PATCH 4/6] Fix typo in `--srcdir` option in echo message status of mysql_install_db --- scripts/mysql_install_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 43ff4191e08..e4f2d419ea5 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -210,7 +210,7 @@ cannot_find_file() echo echo "If you compiled from source, you need to either run 'make install' to" echo "copy the software into the correct location ready for operation." - echo "If you don't want to do a full install, you can use the --srcddir" + echo "If you don't want to do a full install, you can use the --srcdir" echo "option to only install the mysql database and privilege tables" echo echo "If you compiled from source, you need to either run 'make install' to" From 6b22cc4ae074276eb0adca4c7a7a0b99cc6ca56b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Jun 2018 21:23:21 +1000 Subject: [PATCH 5/6] connect engine: GetStringUTFChars takes pointer arg Avoids compile errors of the form: /storage/connect/jdbconn.cpp:1473:41: error: cannot initialize a parameter of type 'jboolean *' (aka 'unsigned char *') with an rvalue of type 'jboolean' (aka 'unsigned char') name = env->GetStringUTFChars(label, (jboolean)false); ^~~~~~~~~~~~~~~ /usr/lib/jvm/java-8-oracle/include/jni.h:1616:58: note: passing argument to parameter 'isCopy' here const char* GetStringUTFChars(jstring str, jboolean *isCopy) { --- storage/connect/javaconn.cpp | 4 ++-- storage/connect/jdbconn.cpp | 10 +++++----- storage/connect/jmgoconn.cpp | 4 ++-- storage/connect/tabjmg.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp index d1be0ca1848..e73149486a8 100644 --- a/storage/connect/javaconn.cpp +++ b/storage/connect/javaconn.cpp @@ -153,7 +153,7 @@ bool JAVAConn::Check(jint rc) if (exc != nullptr && tid != nullptr) { jstring s = (jstring)env->CallObjectMethod(exc, tid); - const char *utf = env->GetStringUTFChars(s, (jboolean)false); + const char *utf = env->GetStringUTFChars(s, NULL); env->DeleteLocalRef(s); Msg = PlugDup(m_G, utf); } else @@ -162,7 +162,7 @@ bool JAVAConn::Check(jint rc) env->ExceptionClear(); } else if (rc < 0) { s = (jstring)env->CallObjectMethod(job, errid); - Msg = (char*)env->GetStringUTFChars(s, (jboolean)false); + Msg = (char*)env->GetStringUTFChars(s, NULL); } else Msg = NULL; diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index ddbc3115f0b..7e42ca126d0 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -828,11 +828,11 @@ bool JDBConn::Connect(PJPARM sop) jstring s = (jstring)env->CallObjectMethod(job, qcid); if (s != nullptr) { - char *qch = (char*)env->GetStringUTFChars(s, (jboolean)false); + char *qch = (char*)env->GetStringUTFChars(s, NULL); m_IDQuoteChar[0] = *qch; } else { s = (jstring)env->CallObjectMethod(job, errid); - Msg = (char*)env->GetStringUTFChars(s, (jboolean)false); + Msg = (char*)env->GetStringUTFChars(s, NULL); } // endif s } // endif qcid @@ -1010,7 +1010,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) cn = nullptr; if (cn) { - field = env->GetStringUTFChars(cn, (jboolean)false); + field = env->GetStringUTFChars(cn, NULL); val->SetValue_psz((PSZ)field); } else val->Reset(); @@ -1084,7 +1084,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) cn = nullptr; if (cn) { - const char *field = env->GetStringUTFChars(cn, (jboolean)false); + const char *field = env->GetStringUTFChars(cn, NULL); val->SetValue_psz((PSZ)field); } else val->Reset(); @@ -1462,7 +1462,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) return NULL; } // endif label - name = env->GetStringUTFChars(label, (jboolean)false); + name = env->GetStringUTFChars(label, NULL); crp = qrp->Colresp; // Column_Name crp->Kdata->SetValue((char*)name, i); n = env->GetIntArrayElements(val, 0); diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp index 1731ccbeb8c..33668e69988 100644 --- a/storage/connect/jmgoconn.cpp +++ b/storage/connect/jmgoconn.cpp @@ -522,7 +522,7 @@ PSZ JMgoConn::GetDocument(void) jdc = (jstring)env->CallObjectMethod(job, getdocid); if (jdc) - doc = (PSZ)env->GetStringUTFChars(jdc, (jboolean)false); + doc = (PSZ)env->GetStringUTFChars(jdc, NULL); } // endif getdocid @@ -807,7 +807,7 @@ PSZ JMgoConn::GetColumnValue(PSZ path) fn = (jstring)env->CallObjectMethod(job, objfldid, jn); if (fn) - fld = (PSZ)env->GetStringUTFChars(fn, (jboolean)false); + fld = (PSZ)env->GetStringUTFChars(fn, NULL); } // endif objfldid diff --git a/storage/connect/tabjmg.cpp b/storage/connect/tabjmg.cpp index ba3e1c3e7c0..4653973a4db 100644 --- a/storage/connect/tabjmg.cpp +++ b/storage/connect/tabjmg.cpp @@ -101,7 +101,7 @@ bool JMGDISC::ColDesc(PGLOBAL g, jobject obj, char *pcn, char *pfmt, continue; jkey = (jstring)Jcp->env->CallObjectMethod(Jcp->job, bvnameid); - key = Jcp->env->GetStringUTFChars(jkey, (jboolean)false); + key = Jcp->env->GetStringUTFChars(jkey, NULL); if (pcn) { strncpy(colname, pcn, 64); From 51fb163b6d390119a7ca9641a4ca9b36e713fc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sat, 25 Aug 2018 18:23:34 +0300 Subject: [PATCH 6/6] Fix clang warning of mismatched new[] and delete[] Warning: 'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'? --- storage/connect/javaconn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp index e73149486a8..ec10b125737 100644 --- a/storage/connect/javaconn.cpp +++ b/storage/connect/javaconn.cpp @@ -456,7 +456,7 @@ bool JAVAConn::Open(PGLOBAL g) //=============== load and initialize Java VM and JNI interface ============= rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! - delete options; // we then no longer need the initialisation options. + delete[] options; // we then no longer need the initialisation options. switch (rc) { case JNI_OK: