summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-02-23 08:43:34 +0100
committerSergei Golubchik <serg@mariadb.org>2018-02-23 08:43:34 +0100
commit2732fcc608eb98345f79ba805842ab02272d49cf (patch)
treee7273c809f44432e5f60a55d5b8f35253d49963d
parent131d9a5d0cb51fa88a0461c939dfd2a7c68d5664 (diff)
parentb8af22af15d159b32256f7d5be8324871ae1a104 (diff)
downloadmariadb-git-2732fcc608eb98345f79ba805842ab02272d49cf.tar.gz
Merge branch 'bb-10.2-ext' into 10.3
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/heap.h1
-rw-r--r--include/my_time.h2
-rw-r--r--mysql-test/lib/My/SafeProcess/Base.pm12
-rw-r--r--mysql-test/lib/My/Tee.pm23
-rwxr-xr-xmysql-test/mysql-test-run.pl9
-rw-r--r--mysql-test/r/cte_nonrecursive.result27
-rw-r--r--mysql-test/r/func_in.result13
-rw-r--r--mysql-test/r/func_time.result51
-rw-r--r--mysql-test/r/view.result108
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption-page-compression.result18
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption-page-compression.test23
-rw-r--r--mysql-test/suite/galera/disabled.def3
-rw-r--r--mysql-test/suite/galera/r/galera_var_node_address.result1
-rw-r--r--mysql-test/suite/galera/t/galera_var_node_address.test1
-rw-r--r--mysql-test/suite/maria/dynamic.result4
-rw-r--r--mysql-test/suite/maria/dynamic.test7
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result9
-rw-r--r--mysql-test/suite/parts/t/partition_alter_maria.test7
-rw-r--r--mysql-test/suite/parts/t/partition_alter_myisam.test1
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test2
-rw-r--r--mysql-test/t/cte_nonrecursive.test25
-rw-r--r--mysql-test/t/func_in.test14
-rw-r--r--mysql-test/t/func_time.test53
-rw-r--r--mysql-test/t/view.test112
-rw-r--r--mysys/my_addr_resolve.c7
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh2
-rw-r--r--sql/field.cc83
-rw-r--r--sql/field.h1
-rw-r--r--sql/item.cc32
-rw-r--r--sql/item.h29
-rw-r--r--sql/item_cmpfunc.cc64
-rw-r--r--sql/item_cmpfunc.h11
-rw-r--r--sql/item_func.cc38
-rw-r--r--sql/item_func.h45
-rw-r--r--sql/item_timefunc.cc69
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/partition_info.cc35
-rw-r--r--sql/sql_cte.cc7
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_type.cc82
-rw-r--r--sql/sql_type.h251
-rw-r--r--storage/connect/ha_connect.cc16
-rw-r--r--storage/heap/_check.c2
-rw-r--r--storage/heap/ha_heap.cc11
-rw-r--r--storage/heap/hp_create.c8
-rw-r--r--storage/heap/hp_delete.c2
-rw-r--r--storage/heap/hp_rrnd.c2
-rw-r--r--storage/heap/hp_rsame.c2
-rw-r--r--storage/heap/hp_scan.c2
-rw-r--r--storage/heap/hp_write.c4
-rw-r--r--storage/innobase/CMakeLists.txt10
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc4
-rw-r--r--storage/maria/ma_bitmap.c241
-rw-r--r--storage/maria/ma_dynrec.c7
-rw-r--r--storage/maria/maria_def.h3
-rw-r--r--storage/rocksdb/ha_rocksdb.cc17
-rw-r--r--storage/rocksdb/ha_rocksdb.h2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result24
-rw-r--r--storage/rocksdb/rdb_datadic.cc2
-rw-r--r--storage/spider/CMakeLists.txt2
-rw-r--r--storage/tokudb/CMakeLists.txt2
-rw-r--r--win/upgrade_wizard/CMakeLists.txt2
63 files changed, 1137 insertions, 517 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d381461c53..0813cf2288f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -162,6 +162,7 @@ INCLUDE(plugin)
INCLUDE(install_macros)
INCLUDE(systemd)
INCLUDE(mysql_add_executable)
+INCLUDE(compile_flags)
INCLUDE(crc32-vpmsum)
# Handle options
diff --git a/include/heap.h b/include/heap.h
index 724cf6c5f98..e92f649b87b 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -144,6 +144,7 @@ typedef struct st_heap_share
uint key_version; /* Updated on key change */
uint file_version; /* Update on clear */
uint reclength; /* Length of one record */
+ uint visible; /* Offset to the visible/deleted mark */
uint changed;
uint keys,max_key_length;
uint currently_disabled_keys; /* saved value from "keys" when disabled */
diff --git a/include/my_time.h b/include/my_time.h
index 2638b18d027..dd95854fb3a 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -117,7 +117,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
ulonglong flags, int *was_cut);
static inline
-longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut)
+longlong double_to_datetime(double nr, MYSQL_TIME *ltime, ulonglong flags, int *cut)
{
if (nr < 0 || nr > LONGLONG_MAX)
nr= (double)LONGLONG_MAX;
diff --git a/mysql-test/lib/My/SafeProcess/Base.pm b/mysql-test/lib/My/SafeProcess/Base.pm
index 1ac0120a735..c5ac2ab51c2 100644
--- a/mysql-test/lib/My/SafeProcess/Base.pm
+++ b/mysql-test/lib/My/SafeProcess/Base.pm
@@ -186,8 +186,10 @@ sub create_process {
# it and any childs(that hasn't changed group themself)
setpgrp(0,0) if $opts{setpgrp};
- if ( $output and !open(STDOUT, $open_mode, $output) ) {
- croak("can't redirect STDOUT to '$output': $!");
+ if ( $output ) {
+ close STDOUT;
+ open(STDOUT, $open_mode, $output)
+ or croak "can't redirect STDOUT to '$output': $!";
}
if ( $error ) {
@@ -196,8 +198,10 @@ sub create_process {
croak("can't dup STDOUT: $!");
}
}
- elsif ( ! open(STDERR, $open_mode, $error) ) {
- croak("can't redirect STDERR to '$error': $!");
+ else {
+ close STDERR;
+ open(STDERR, $open_mode, $error)
+ or croak "can't redirect STDERR to '$error': $!";
}
}
diff --git a/mysql-test/lib/My/Tee.pm b/mysql-test/lib/My/Tee.pm
new file mode 100644
index 00000000000..ee82e6f45ae
--- /dev/null
+++ b/mysql-test/lib/My/Tee.pm
@@ -0,0 +1,23 @@
+package My::Tee;
+
+# see PerlIO::via
+
+our $copyfh;
+
+sub PUSHED
+{
+ open($copyfh, '>', "$::opt_vardir/log/stdout.log")
+ or die "open(>$::opt_vardir/log/stdout.log): $!"
+ unless $copyfh;
+ bless { }, shift;
+}
+
+sub WRITE
+{
+ my ($obj, $buf, $fh) = @_;
+ print $fh $buf;
+ print $copyfh $buf;
+ return length($buf);
+}
+
+1;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index a78cfbe4140..5ee05f3f606 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -91,6 +91,7 @@ use My::Platform;
use My::SafeProcess;
use My::ConfigFactory;
use My::Options;
+use My::Tee;
use My::Find;
use My::SysInfo;
use My::CoreDump;
@@ -389,6 +390,11 @@ sub main {
initialize_servers();
init_timers();
+ unless (IS_WINDOWS) {
+ binmode(STDOUT,":via(My::Tee)") or die "binmode(STDOUT, :via(My::Tee)):$!";
+ binmode(STDERR,":via(My::Tee)") or die "binmode(STDERR, :via(My::Tee)):$!";
+ }
+
mtr_report("Checking supported features...");
executable_setup();
@@ -6270,7 +6276,8 @@ sub xterm_stat {
my $done = $num_tests - $left;
my $spent = time - $^T;
- printf "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
+ syswrite STDOUT, sprintf
+ "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
time_format($spent), $done,
time_format($spent/$done * $left), $left;
}
diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result
index beca9e7ca4f..53334512b20 100644
--- a/mysql-test/r/cte_nonrecursive.result
+++ b/mysql-test/r/cte_nonrecursive.result
@@ -1398,3 +1398,30 @@ i
2
3
DROP TABLE t1;
+#
+# MDEV-14297: Lost name of a explicitly named CTE column used in
+# the non-recursive CTE via prepared statement
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+PREPARE stmt FROM "WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+a
+1
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM "CREATE VIEW v1 AS WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v1;
+a
+1
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM "CREATE VIEW v2 AS WITH cte(a) AS (SELECT * FROM t1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v2;
+a
+1
+2
+3
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+DROP VIEW v1,v2;
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 692806c7cac..65313148bf8 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -896,3 +896,16 @@ EXECUTE stmt;
a b
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+#
+# MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+#
+SELECT
+TIME'00:00:00'='' AS c1_true,
+TIME'00:00:00' IN ('', TIME'10:20:30') AS c2_true,
+TIME'00:00:00' NOT IN ('', TIME'10:20:30') AS c3_false;
+c1_true c2_true c3_false
+1 1 0
+Warnings:
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
+Warning 1292 Truncated incorrect time value: ''
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index e710f3ac438..e03de2ca582 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -3351,3 +3351,54 @@ SELECT CONVERT_TZ(1, ROW(1,1), 1);
ERROR HY000: Illegal parameter data type row for operation 'convert_tz'
SELECT CONVERT_TZ(1, 1, ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'convert_tz'
+#
+# MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+#
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+COALESCE(TIME'800:00:00', NOW()) AS c,
+HOUR(COALESCE(TIME'800:00:00',NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END AS c,
+HOUR(CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+IFNULL(TIME'800:00:00', NOW()) AS c,
+HOUR(IFNULL(TIME'800:00:00', NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+IF(TRUE,TIME'800:00:00', NOW()) AS c,
+HOUR(IF(TRUE,TIME'800:00:00', NOW())) AS hc;
+c hc
+2018-03-22 08:00:00 8
+SELECT
+ADDTIME(TIME'10:20:30', TIMESTAMP'2001-01-01 00:00:00') AS c1,
+ADDTIME(TIME'10:20:30', COALESCE(TIMESTAMP'2001-01-01 00:00:00',TIMESTAMP'2001-01-01 00:00:00')) AS c2,
+ADDTIME(TIME'10:20:30', DATE'2001-01-01') AS c3,
+ADDTIME(TIME'10:20:30', COALESCE(DATE'2001-01-01',TIMESTAMP'2001-01-01 00:00:00')) AS c4;
+c1 c2 c3 c4
+NULL NULL NULL NULL
+SELECT
+HOUR(TIMESTAMP'0000-00-01 10:00:00') AS h0,
+TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00') AS tts0,
+TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00.1') AS tts1,
+CAST(TIMESTAMP'0000-00-01 10:00:00' AS TIME) AS c0,
+CAST(TIMESTAMP'0000-00-01 10:00:00.1' AS TIME(1)) AS c2;
+h0 tts0 tts1 c0 c2
+10 36000 36000.1 10:00:00 10:00:00.1
+SET TIMESTAMP=DEFAULT;
+#
+# MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
+#
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+LAST_DAY(TIME'00:00:00') AS c1,
+CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
+CAST(LAST_DAY(TIME'00:00:00') AS TIME) AS c3;
+c1 c2 c3
+2018-02-28 00:00:00 00:00:00
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 640d317713b..e61e2d2663d 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -5227,114 +5227,6 @@ execute stmt1;
deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
-#
-# MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
-# with MERGE view)
-#
-CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE OR REPLACE view v1 AS
-SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-;
-SELECT 1
-FROM (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
-FROM t1 a_alias_1
-LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
-LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
-LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
-LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
-LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
-;
-1
-SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
-;
-1
-drop view v1;
-drop table t1,t2,t3,t4,t5,t6;
# -----------------------------------------------------------------
# -- End of 5.3 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
index 5c646a4010d..bf5698f97fa 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
@@ -135,6 +135,13 @@ count(*)
select count(*) from innodb_page_compressed9 where c1 < 500000;
count(*)
2000
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+# Wait until dirty pages are compressed and encrypted
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
variable_value > 0
1
@@ -152,9 +159,14 @@ update innodb_page_compressed6 set c1 = c1 + 1;
update innodb_page_compressed7 set c1 = c1 + 1;
update innodb_page_compressed8 set c1 = c1 + 1;
update innodb_page_compressed9 set c1 = c1 + 1;
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
-variable_value > 0
-1
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+# Wait until dirty pages are compressed and encrypted 2
+unlock tables;
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
variable_value > 0
1
diff --git a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
index a9e9a79cb06..df52d3f66eb 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
@@ -74,6 +74,15 @@ select count(*) from innodb_page_compressed7 where c1 < 500000;
select count(*) from innodb_page_compressed8 where c1 < 500000;
select count(*) from innodb_page_compressed9 where c1 < 500000;
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+
+unlock tables;
+
+--echo # Wait until dirty pages are compressed and encrypted
let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED';
--source include/wait_condition.inc
let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
@@ -97,12 +106,20 @@ update innodb_page_compressed7 set c1 = c1 + 1;
update innodb_page_compressed8 set c1 = c1 + 1;
update innodb_page_compressed9 set c1 = c1 + 1;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
---source include/wait_condition.inc
+flush tables innodb_page_compressed1, innodb_page_compressed2,
+innodb_page_compressed3, innodb_page_compressed4,
+innodb_page_compressed5, innodb_page_compressed6,
+innodb_page_compressed7, innodb_page_compressed8,
+innodb_page_compressed9 for export;
+unlock tables;
+
+--echo # Wait until dirty pages are compressed and encrypted 2
let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED';
--source include/wait_condition.inc
+unlock tables;
+let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_DECRYPTED';
+--source include/wait_condition.inc
-SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted';
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted';
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed';
SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed';
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 0b5aa239180..8db0073d268 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -62,3 +62,6 @@ MW-328B: MDEV-13549 Galera test failures 10.1
MW-328: MDEV-13549 Galera test failures 10.1
galera_suspend_slave: MDEV-13549 Galera test failures 10.1
galera_ist_progress: MDEV-15236 galera_ist_progress fails when trying to read transfer status
+galera_gtid : MDEV-13549 Galera test failures 10.1
+galera_gtid_slave : MDEV-13549 Galera test failures 10.1
+galera_unicode_identifiers : MDEV-13549 Galera test failures 10.1
diff --git a/mysql-test/suite/galera/r/galera_var_node_address.result b/mysql-test/suite/galera/r/galera_var_node_address.result
index 8ce6a5e01a1..b8076958532 100644
--- a/mysql-test/suite/galera/r/galera_var_node_address.result
+++ b/mysql-test/suite/galera/r/galera_var_node_address.result
@@ -1,5 +1,6 @@
call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*");
call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .* is not in state transfer (.*). Message ignored.");
+call mtr.add_suppression("WSREP: Sending JOIN failed: -[0-9]+ (Transport endpoint is not connected). Will retry in new primary component.");
SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
VARIABLE_VALUE = 4
1
diff --git a/mysql-test/suite/galera/t/galera_var_node_address.test b/mysql-test/suite/galera/t/galera_var_node_address.test
index 3353652d8b9..22e98e3aa82 100644
--- a/mysql-test/suite/galera/t/galera_var_node_address.test
+++ b/mysql-test/suite/galera/t/galera_var_node_address.test
@@ -8,6 +8,7 @@
call mtr.add_suppression("WSREP: Stray state UUID msg: .* current group state WAIT_STATE_UUID .*");
call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .* is not in state transfer (.*). Message ignored.");
+call mtr.add_suppression("WSREP: Sending JOIN failed: -[0-9]+ (Transport endpoint is not connected). Will retry in new primary component.");
SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
diff --git a/mysql-test/suite/maria/dynamic.result b/mysql-test/suite/maria/dynamic.result
new file mode 100644
index 00000000000..1e87010e9ca
--- /dev/null
+++ b/mysql-test/suite/maria/dynamic.result
@@ -0,0 +1,4 @@
+create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic;
+insert t1 (b) values (repeat('a', 20000));
+update t1 set b='b';
+drop table t1;
diff --git a/mysql-test/suite/maria/dynamic.test b/mysql-test/suite/maria/dynamic.test
new file mode 100644
index 00000000000..f8a1e98cd41
--- /dev/null
+++ b/mysql-test/suite/maria/dynamic.test
@@ -0,0 +1,7 @@
+#
+# MDEV-13748 Assertion `status_var.local_memory_used == 0 || !debug_assert_on_not_freed_memory' failed in virtual THD::~THD after query with INTERSECT
+#
+create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic;
+insert t1 (b) values (repeat('a', 20000));
+update t1 set b='b';
+drop table t1;
diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result
index 7fed69bb5a5..c7e9028a29c 100644
--- a/mysql-test/suite/parts/r/partition_alter_maria.result
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -16,6 +16,15 @@ select * from t1;
pk dt
1 2017-09-28 15:12:00
drop table t1;
+create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 TRANSACTIONAL=1
+ PARTITION BY HASH (`a`)
+PARTITIONS 2
+drop table t1;
#
# MDEV-14641 Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine
#
diff --git a/mysql-test/suite/parts/t/partition_alter_maria.test b/mysql-test/suite/parts/t/partition_alter_maria.test
index e21f0dfab82..e0b9256391d 100644
--- a/mysql-test/suite/parts/t/partition_alter_maria.test
+++ b/mysql-test/suite/parts/t/partition_alter_maria.test
@@ -17,5 +17,12 @@ alter table t1 drop partition p20181231;
select * from t1;
drop table t1;
+#
+# MDEV-13982 Server crashes in in ha_partition::engine_name
+#
+create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2;
+show create table t1;
+drop table t1;
+
--let $engine=Aria
--source inc/part_alter_values.inc
diff --git a/mysql-test/suite/parts/t/partition_alter_myisam.test b/mysql-test/suite/parts/t/partition_alter_myisam.test
index d3abb8842e1..326cf52b018 100644
--- a/mysql-test/suite/parts/t/partition_alter_myisam.test
+++ b/mysql-test/suite/parts/t/partition_alter_myisam.test
@@ -1,4 +1,5 @@
--source include/have_partition.inc
+--source include/have_symlink.inc
--let $engine=MyISAM
--source inc/part_alter_values.inc
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 9be0d5556f0..6c5eaffd9a2 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -42,8 +42,10 @@ select 1,
3;
insert into t2 values (1), (2);
select * from t2;
+--disable_ps_protocol
--error ER_NO_SUCH_TABLE
select * from t_doesnt_exist;
+--enable_ps_protocol
--error 1064
syntax_error_query;
drop table renamed_t1, t2;
diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test
index 05de03fc7af..3d073183877 100644
--- a/mysql-test/t/cte_nonrecursive.test
+++ b/mysql-test/t/cte_nonrecursive.test
@@ -964,3 +964,28 @@ WITH RECURSIVE c1 AS (WITH c3 AS (SELECT * FROM c2) SELECT * FROM c3),
SELECT * FROM c1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14297: Lost name of a explicitly named CTE column used in
+--echo # the non-recursive CTE via prepared statement
+--echo #
+
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2),(3);
+
+PREPARE stmt FROM "WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+PREPARE stmt FROM "CREATE VIEW v1 AS WITH cte(a) AS (SELECT 1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v1;
+DEALLOCATE PREPARE stmt;
+
+PREPARE stmt FROM "CREATE VIEW v2 AS WITH cte(a) AS (SELECT * FROM t1) SELECT * FROM cte";
+EXECUTE stmt;
+SELECT * FROM v2;
+DEALLOCATE PREPARE stmt;
+
+DROP TABLE t1;
+DROP VIEW v1,v2;
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 8f6062fd2c2..b99fad159c2 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -676,3 +676,17 @@ EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+--echo #
+
+# This is to make sure that TIME_FUZZY_DATE is always passed to str_to_time(),
+# so empty strings are compared as TIME'00:00:00' all around the code:
+# when using Arg_comparator (e.g. in binary comparison operators), and
+# when not using it (e.g. in IN predicate).
+
+SELECT
+ TIME'00:00:00'='' AS c1_true,
+ TIME'00:00:00' IN ('', TIME'10:20:30') AS c2_true,
+ TIME'00:00:00' NOT IN ('', TIME'10:20:30') AS c3_false;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 09c13598cfd..a475c33b925 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1945,3 +1945,56 @@ SELECT CONVERT_TZ(ROW(1,1),1,1);
SELECT CONVERT_TZ(1, ROW(1,1), 1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CONVERT_TZ(1, 1, ROW(1,1));
+
+
+--echo #
+--echo # MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
+--echo #
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+ COALESCE(TIME'800:00:00', NOW()) AS c,
+ HOUR(COALESCE(TIME'800:00:00',NOW())) AS hc;
+
+SELECT
+ CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END AS c,
+ HOUR(CASE WHEN TRUE THEN TIME'800:00:00' ELSE NOW() END) AS hc;
+
+SELECT
+ IFNULL(TIME'800:00:00', NOW()) AS c,
+ HOUR(IFNULL(TIME'800:00:00', NOW())) AS hc;
+
+SELECT
+ IF(TRUE,TIME'800:00:00', NOW()) AS c,
+ HOUR(IF(TRUE,TIME'800:00:00', NOW())) AS hc;
+
+SELECT
+ ADDTIME(TIME'10:20:30', TIMESTAMP'2001-01-01 00:00:00') AS c1,
+ ADDTIME(TIME'10:20:30', COALESCE(TIMESTAMP'2001-01-01 00:00:00',TIMESTAMP'2001-01-01 00:00:00')) AS c2,
+ ADDTIME(TIME'10:20:30', DATE'2001-01-01') AS c3,
+ ADDTIME(TIME'10:20:30', COALESCE(DATE'2001-01-01',TIMESTAMP'2001-01-01 00:00:00')) AS c4;
+
+#
+# Make sure that time functions that in 10.2 used get_arg0_time()
+# do not mix days to hours for dates with zero YYYYMM and non-zero days.
+#
+
+SELECT
+ HOUR(TIMESTAMP'0000-00-01 10:00:00') AS h0,
+ TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00') AS tts0,
+ TIME_TO_SEC(TIMESTAMP'0000-00-01 10:00:00.1') AS tts1,
+ CAST(TIMESTAMP'0000-00-01 10:00:00' AS TIME) AS c0,
+ CAST(TIMESTAMP'0000-00-01 10:00:00.1' AS TIME(1)) AS c2;
+
+SET TIMESTAMP=DEFAULT;
+
+--echo #
+--echo # MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
+--echo #
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2018-02-17 01:02:03');
+SELECT
+ LAST_DAY(TIME'00:00:00') AS c1,
+ CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
+ CAST(LAST_DAY(TIME'00:00:00') AS TIME) AS c3;
+SET TIMESTAMP=DEFAULT;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 2d8f98f4d5f..f78ddd6f49e 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -5109,118 +5109,6 @@ deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
---echo #
---echo # MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
---echo # with MERGE view)
---echo #
-
-CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
-
-CREATE OR REPLACE view v1 AS
- SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-;
-
-SELECT 1
-FROM (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
- FROM t1 a_alias_1
- LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
- LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
- LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
- LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
- LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
-;
-
-SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
-;
-
-drop view v1;
-drop table t1,t2,t3,t4,t5,t6;
-
--echo # -----------------------------------------------------------------
--echo # -- End of 5.3 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 10f8552f226..84bff47d1a9 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -49,6 +49,13 @@ static const char *strip_path(const char *s)
static bfd *bfdh= 0;
static asymbol **symtable= 0;
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+#include <link.h>
+static ElfW(Addr) offset= 0;
+#else
+#define offset 0
+#endif
+
/**
finds a file name, a line number, and a function name corresponding to addr.
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 9f3b70863e7..e7313e4e188 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -638,7 +638,7 @@ wait_for_listen()
for i in {1..300}
do
- LSOF_OUT=$(lsof -sTCP:LISTEN -i TCP:${PORT} -a -c nc -c socat -F c)
+ LSOF_OUT=$(lsof -sTCP:LISTEN -i TCP:${PORT} -a -c nc -c socat -F c 2> /dev/null || :)
[ -n "${LSOF_OUT}" ] && break
sleep 0.2
done
diff --git a/sql/field.cc b/sql/field.cc
index 1f97e587eb3..e47b6e9c989 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5081,6 +5081,13 @@ copy_or_convert_to_datetime(THD *thd, const MYSQL_TIME *from, MYSQL_TIME *to)
}
+sql_mode_t Field_timestamp::sql_mode_for_timestamp(THD *thd) const
+{
+ // We don't want to store invalid or fuzzy datetime values in TIMESTAMP
+ return (thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE;
+}
+
+
int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
int unused;
@@ -5089,9 +5096,7 @@ int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
MYSQL_TIME l_time;
bool valid= !copy_or_convert_to_datetime(thd, ltime, &l_time) &&
!check_date(&l_time, pack_time(&l_time) != 0,
- (thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &unused);
-
+ sql_mode_for_timestamp(thd), &unused);
return store_TIME_with_warning(thd, &l_time, &str, false, valid);
}
@@ -5104,11 +5109,8 @@ int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs)
ErrConvString str(from, len, cs);
THD *thd= get_thd();
- /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
have_smth_to_conv= !str_to_datetime(cs, from, len, &l_time,
- (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &status);
+ sql_mode_for_timestamp(thd), &status);
return store_TIME_with_warning(thd, &l_time, &str,
status.warnings, have_smth_to_conv);
}
@@ -5121,9 +5123,8 @@ int Field_timestamp::store(double nr)
ErrConvDouble str(nr);
THD *thd= get_thd();
- longlong tmp= double_to_datetime(nr, &l_time, (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &error);
+ longlong tmp= double_to_datetime(nr, &l_time, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
}
@@ -5135,10 +5136,8 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
ErrConvInteger str(nr, unsigned_val);
THD *thd= get_thd();
- /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
- longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE) |
- MODE_NO_ZERO_IN_DATE, &error);
+ longlong tmp= number_to_datetime(nr, 0, &l_time, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1);
}
@@ -5433,10 +5432,8 @@ int Field_timestamp::store_decimal(const my_decimal *d)
error= 2;
}
else
- tmp= number_to_datetime(nr, sec_part, &ltime, TIME_NO_ZERO_IN_DATE |
- (thd->variables.sql_mode &
- MODE_NO_ZERO_DATE), &error);
-
+ tmp= number_to_datetime(nr, sec_part, &ltime, sql_mode_for_timestamp(thd),
+ &error);
return store_TIME_with_warning(thd, &ltime, &str, error, tmp != -1);
}
@@ -5711,30 +5708,28 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
const_item->field_type() != MYSQL_TYPE_TIMESTAMP) ||
const_item->decimals != decimals())
{
- MYSQL_TIME ltime;
- if (const_item->field_type() == MYSQL_TYPE_TIME ?
- const_item->get_date_with_conversion(&ltime, 0) :
- const_item->get_date(&ltime, 0))
+ Datetime dt(thd, const_item, 0);
+ if (!dt.is_valid_datetime())
return NULL;
/*
See comments about truncation in the same place in
Field_time::get_equal_const_item().
*/
- return new (thd->mem_root) Item_datetime_literal(thd, &ltime,
+ return new (thd->mem_root) Item_datetime_literal(thd,
+ dt.get_mysql_time(),
decimals());
}
break;
case ANY_SUBST:
if (!is_temporal_type_with_date(const_item->field_type()))
{
- MYSQL_TIME ltime;
- if (const_item->get_date_with_conversion(&ltime,
- TIME_FUZZY_DATES |
- TIME_INVALID_DATES))
+ Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES);
+ if (!dt.is_valid_datetime())
return NULL;
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, &ltime,
- ltime.second_part ?
+ Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ dt.get_mysql_time()->
+ second_part ?
TIME_SECOND_PART_DIGITS : 0);
}
break;
@@ -6086,10 +6081,8 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
{
MYSQL_TIME ltime;
// Get the value of const_item with conversion from DATETIME to TIME
- if (const_item->get_time_with_conversion(thd, &ltime,
- TIME_TIME_ONLY |
- TIME_FUZZY_DATES |
- TIME_INVALID_DATES))
+ ulonglong fuzzydate= Time::comparison_flags_for_get_date();
+ if (const_item->get_time_with_conversion(thd, &ltime, fuzzydate))
return NULL;
/*
Replace a DATE/DATETIME constant to a TIME constant:
@@ -6562,10 +6555,9 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
case ANY_SUBST:
if (!is_temporal_type_with_date(const_item->field_type()))
{
- MYSQL_TIME ltime;
// Get the value of const_item with conversion from TIME to DATETIME
- if (const_item->get_date_with_conversion(&ltime,
- TIME_FUZZY_DATES | TIME_INVALID_DATES))
+ Datetime dt(thd, const_item, TIME_FUZZY_DATES | TIME_INVALID_DATES);
+ if (!dt.is_valid_datetime())
return NULL;
/*
Replace the constant to a DATE or DATETIME constant.
@@ -6578,26 +6570,23 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
(assuming CURRENT_DATE is '2015-08-30'
*/
- if (non_zero_hhmmssuu(&ltime))
+ if (!dt.hhmmssff_is_zero())
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, &ltime,
- ltime.second_part ?
+ Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ dt.get_mysql_time()->
+ second_part ?
TIME_SECOND_PART_DIGITS : 0);
- datetime_to_date(&ltime);
return new (thd->mem_root)
- Item_date_literal_for_invalid_dates(thd, &ltime);
+ Item_date_literal_for_invalid_dates(thd, Date(&dt).get_mysql_time());
}
break;
case IDENTITY_SUBST:
if (const_item->field_type() != MYSQL_TYPE_DATE)
{
- MYSQL_TIME ltime;
- if (const_item->field_type() == MYSQL_TYPE_TIME ?
- const_item->get_date_with_conversion(&ltime, 0) :
- const_item->get_date(&ltime, 0))
+ Date d(thd, const_item, 0);
+ if (!d.is_valid_date())
return NULL;
- datetime_to_date(&ltime);
- return new (thd->mem_root) Item_date_literal(thd, &ltime);
+ return new (thd->mem_root) Item_date_literal(thd, d.get_mysql_time());
}
break;
}
diff --git a/sql/field.h b/sql/field.h
index 364e937227c..186d9b0e47a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -2457,6 +2457,7 @@ public:
class Field_timestamp :public Field_temporal {
protected:
+ sql_mode_t sql_mode_for_timestamp(THD *thd) const;
int store_TIME_with_warning(THD *, MYSQL_TIME *, const ErrConv *,
int warnings, bool have_smth_to_conv);
public:
diff --git a/sql/item.cc b/sql/item.cc
index 34d5d810ff9..d1648147608 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -130,38 +130,6 @@ longlong Item::val_datetime_packed_result()
/**
Get date/time/datetime.
- Optionally extend TIME result to DATETIME.
-*/
-bool Item::get_date_with_conversion(MYSQL_TIME *ltime, ulonglong fuzzydate)
-{
- THD *thd= current_thd;
-
- /*
- Some TIME type items return error when trying to do get_date()
- without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
- In the SQL standard time->datetime conversion mode we add TIME_TIME_ONLY.
- In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
- and leave it to get_date() to check date.
- */
- ulonglong time_flag= (field_type() == MYSQL_TYPE_TIME &&
- !(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
- TIME_TIME_ONLY : 0;
- if (get_date(ltime, fuzzydate | time_flag))
- return true;
- if (ltime->time_type == MYSQL_TIMESTAMP_TIME &&
- !(fuzzydate & TIME_TIME_ONLY))
- {
- MYSQL_TIME tmp;
- if (time_to_datetime_with_warn(thd, ltime, &tmp, fuzzydate))
- return null_value= true;
- *ltime= tmp;
- }
- return false;
-}
-
-
-/**
- Get date/time/datetime.
If DATETIME or DATE result is returned, it's converted to TIME.
*/
bool Item::get_time_with_conversion(THD *thd, MYSQL_TIME *ltime,
diff --git a/sql/item.h b/sql/item.h
index 8f2c11eb578..a048d0e6563 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -684,13 +684,6 @@ protected:
value= NULL;
return value;
}
- bool get_date_with_conversion_from_item(Item *item,
- MYSQL_TIME *ltime,
- ulonglong fuzzydate)
- {
- DBUG_ASSERT(fixed == 1);
- return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
- }
/*
This method is used if the item was not null but convertion to
TIME/DATE/DATETIME failed. We return a zero date if allowed,
@@ -1386,17 +1379,16 @@ public:
bool get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_time(MYSQL_TIME *ltime)
- { return get_date(ltime, TIME_TIME_ONLY | TIME_INVALID_DATES); }
- // Get date with automatic TIME->DATETIME conversion
- bool get_date_with_conversion(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ { return get_date(ltime, Time::flags_for_get_date()); }
/*
- Get time with automatic DATE/DATETIME to TIME conversion.
+ Get time with automatic DATE/DATETIME to TIME conversion,
+ by subtracting CURRENT_DATE.
- Performce a reserve operation to get_date_with_conversion().
+ Performce a reverse operation to CAST(time AS DATETIME)
Suppose:
- we have a set of items (typically with the native MYSQL_TYPE_TIME type)
whose item->get_date() return TIME1 value, and
- - item->get_date_with_conversion() for the same Items return DATETIME1,
+ - CAST(AS DATETIME) for the same Items return DATETIME1,
after applying time-to-datetime conversion to TIME1.
then all items (typically of the native MYSQL_TYPE_{DATE|DATETIME} types)
@@ -1425,22 +1417,21 @@ public:
// Get a DATE or DATETIME value in numeric packed format for comparison
virtual longlong val_datetime_packed()
{
- MYSQL_TIME ltime;
ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
- return get_date_with_conversion(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
+ Datetime dt(current_thd, this, fuzzydate);
+ return dt.is_valid_datetime() ? pack_time(dt.get_mysql_time()) : 0;
}
// Get a TIME value in numeric packed format for comparison
virtual longlong val_time_packed()
{
- MYSQL_TIME ltime;
- ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES | TIME_TIME_ONLY;
- return get_date(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
+ Time tm(this, Time::comparison_flags_for_get_date());
+ return tm.is_valid_time() ? pack_time(tm.get_mysql_time()) : 0;
}
longlong val_datetime_packed_result();
longlong val_time_packed_result()
{
MYSQL_TIME ltime;
- ulonglong fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES | TIME_TIME_ONLY;
+ ulonglong fuzzydate= Time::comparison_flags_for_get_date();
return get_date_result(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 4296b2c6468..6e19cfcdf80 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2371,9 +2371,25 @@ Item_func_ifnull::str_op(String *str)
bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
DBUG_ASSERT(fixed == 1);
- if (!args[0]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
- return (null_value= false);
- return (null_value= args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES));
+ for (uint i= 0; i < 2; i++)
+ {
+ Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
+ if (!(dt.copy_to_mysql_time(ltime, mysql_timestamp_type())))
+ return (null_value= false);
+ }
+ return (null_value= true);
+}
+
+
+bool Item_func_ifnull::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ for (uint i= 0; i < 2; i++)
+ {
+ if (!Time(args[i]).copy_to_mysql_time(ltime))
+ return (null_value= false);
+ }
+ return (null_value= true);
}
@@ -2853,7 +2869,19 @@ Item_func_nullif::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
DBUG_ASSERT(fixed == 1);
if (!compare())
return (null_value= true);
- return (null_value= args[2]->get_date(ltime, fuzzydate));
+ Datetime dt(current_thd, args[2], fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+}
+
+
+bool
+Item_func_nullif::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (!compare())
+ return (null_value= true);
+ return (null_value= Time(args[2]).copy_to_mysql_time(ltime));
+
}
@@ -2994,7 +3022,18 @@ bool Item_func_case::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
Item *item= find_item();
if (!item)
return (null_value= true);
- return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
+ Datetime dt(current_thd, item, fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+}
+
+
+bool Item_func_case::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ Item *item= find_item();
+ if (!item)
+ return (null_value= true);
+ return (null_value= Time(item).copy_to_mysql_time(ltime));
}
@@ -3404,7 +3443,20 @@ bool Item_func_coalesce::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
DBUG_ASSERT(fixed == 1);
for (uint i= 0; i < arg_count; i++)
{
- if (!args[i]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
+ if (!dt.copy_to_mysql_time(ltime, mysql_timestamp_type()))
+ return (null_value= false);
+ }
+ return (null_value= true);
+}
+
+
+bool Item_func_coalesce::time_op(MYSQL_TIME *ltime)
+{
+ DBUG_ASSERT(fixed == 1);
+ for (uint i= 0; i < arg_count; i++)
+ {
+ if (!Time(args[i]).copy_to_mysql_time(ltime))
return (null_value= false);
}
return (null_value= true);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 4d0ee5cf993..4caf7e4622d 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1005,6 +1005,7 @@ public:
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
void fix_length_and_dec()
{
if (!aggregate_for_result(func_name(), args, arg_count, true))
@@ -1077,6 +1078,7 @@ public:
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
void fix_length_and_dec()
{
Item_func_case_abbreviation2::fix_length_and_dec2(args);
@@ -1110,7 +1112,12 @@ public:
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- return get_date_with_conversion_from_item(find_item(), ltime, fuzzydate);
+ Datetime dt(current_thd, find_item(), fuzzydate);
+ return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
+ }
+ bool time_op(MYSQL_TIME *ltime)
+ {
+ return (null_value= Time(find_item()).copy_to_mysql_time(ltime));
}
longlong int_op()
{
@@ -1222,6 +1229,7 @@ public:
arg_count= 2; // See the comment to the constructor
}
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
double real_op();
longlong int_op();
String *str_op(String *str);
@@ -2111,6 +2119,7 @@ public:
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool time_op(MYSQL_TIME *ltime);
bool fix_fields(THD *thd, Item **ref);
table_map not_null_tables() const { return 0; }
const char *func_name() const { return "case"; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1b9b0e801bc..4e79b45f5d6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -929,7 +929,6 @@ String *Item_func_hybrid_field_type::val_str_from_date_op(String *str)
if (date_op_with_null_check(&ltime) ||
(null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
return (String *) 0;
- ltime.time_type= mysql_timestamp_type();
str->length(my_TIME_to_str(&ltime, const_cast<char*>(str->ptr()), decimals));
str->set_charset(&my_charset_bin);
DBUG_ASSERT(!null_value);
@@ -941,7 +940,6 @@ double Item_func_hybrid_field_type::val_real_from_date_op()
MYSQL_TIME ltime;
if (date_op_with_null_check(&ltime))
return 0;
- ltime.time_type= mysql_timestamp_type();
return TIME_to_double(&ltime);
}
@@ -950,7 +948,6 @@ longlong Item_func_hybrid_field_type::val_int_from_date_op()
MYSQL_TIME ltime;
if (date_op_with_null_check(&ltime))
return 0;
- ltime.time_type= mysql_timestamp_type();
return TIME_to_ulonglong(&ltime);
}
@@ -963,7 +960,40 @@ Item_func_hybrid_field_type::val_decimal_from_date_op(my_decimal *dec)
my_decimal_set_zero(dec);
return 0;
}
- ltime.time_type= mysql_timestamp_type();
+ return date2my_decimal(&ltime, dec);
+}
+
+
+String *Item_func_hybrid_field_type::val_str_from_time_op(String *str)
+{
+ MYSQL_TIME ltime;
+ if (time_op_with_null_check(&ltime) ||
+ (null_value= my_TIME_to_str(&ltime, str, decimals)))
+ return NULL;
+ return str;
+}
+
+double Item_func_hybrid_field_type::val_real_from_time_op()
+{
+ MYSQL_TIME ltime;
+ return time_op_with_null_check(&ltime) ? 0 : TIME_to_double(&ltime);
+}
+
+longlong Item_func_hybrid_field_type::val_int_from_time_op()
+{
+ MYSQL_TIME ltime;
+ return time_op_with_null_check(&ltime) ? 0 : TIME_to_ulonglong(&ltime);
+}
+
+my_decimal *
+Item_func_hybrid_field_type::val_decimal_from_time_op(my_decimal *dec)
+{
+ MYSQL_TIME ltime;
+ if (time_op_with_null_check(&ltime))
+ {
+ my_decimal_set_zero(dec);
+ return 0;
+ }
return date2my_decimal(&ltime, dec);
}
diff --git a/sql/item_func.h b/sql/item_func.h
index b10223289b9..1b3f28c41be 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -163,14 +163,9 @@ public:
void print_args(String *str, uint from, enum_query_type query_type);
inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- return (null_value=args[0]->get_date_with_conversion(ltime, fuzzy_date));
- }
- inline bool get_arg0_time(MYSQL_TIME *ltime)
- {
- null_value= args[0]->get_time(ltime);
- DBUG_ASSERT(null_value ||
- ltime->time_type != MYSQL_TIMESTAMP_TIME || ltime->day == 0);
- return null_value;
+ DBUG_ASSERT(!(fuzzy_date & TIME_TIME_ONLY));
+ Datetime dt(current_thd, args[0], fuzzy_date);
+ return (null_value= dt.copy_to_mysql_time(ltime));
}
bool is_null() {
update_null_value();
@@ -450,11 +445,17 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
*/
bool date_op_with_null_check(MYSQL_TIME *ltime)
{
- bool rc= date_op(ltime,
- field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0);
+ bool rc= date_op(ltime, 0);
DBUG_ASSERT(!rc ^ null_value);
return rc;
}
+ bool time_op_with_null_check(MYSQL_TIME *ltime)
+ {
+ bool rc= time_op(ltime);
+ DBUG_ASSERT(!rc ^ null_value);
+ DBUG_ASSERT(rc || ltime->time_type == MYSQL_TIMESTAMP_TIME);
+ return rc;
+ }
String *str_op_with_null_check(String *str)
{
String *res= str_op(str);
@@ -491,32 +492,30 @@ public:
{
return real_op();
}
- bool get_date_from_date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
- {
- return date_op(ltime,
- (fuzzydate |
- (field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0)));
- }
// Value methods that involve conversion
String *val_str_from_decimal_op(String *str);
String *val_str_from_real_op(String *str);
String *val_str_from_int_op(String *str);
String *val_str_from_date_op(String *str);
+ String *val_str_from_time_op(String *str);
my_decimal *val_decimal_from_str_op(my_decimal *dec);
my_decimal *val_decimal_from_real_op(my_decimal *dec);
my_decimal *val_decimal_from_int_op(my_decimal *dec);
my_decimal *val_decimal_from_date_op(my_decimal *dec);
+ my_decimal *val_decimal_from_time_op(my_decimal *dec);
longlong val_int_from_str_op();
longlong val_int_from_real_op();
longlong val_int_from_decimal_op();
longlong val_int_from_date_op();
+ longlong val_int_from_time_op();
double val_real_from_str_op();
double val_real_from_decimal_op();
double val_real_from_date_op();
+ double val_real_from_time_op();
double val_real_from_int_op();
bool get_date_from_str_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
@@ -612,11 +611,18 @@ public:
/**
@brief Performs the operation that this functions implements when
- field type is a temporal type.
+ field type is DATETIME or DATE.
@return The result of the operation.
*/
virtual bool date_op(MYSQL_TIME *res, ulonglong fuzzy_date)= 0;
+ /**
+ @brief Performs the operation that this functions implements when
+ field type is TIME.
+ @return The result of the operation.
+ */
+ virtual bool time_op(MYSQL_TIME *res)= 0;
+
};
@@ -679,6 +685,11 @@ public:
DBUG_ASSERT(0);
return true;
}
+ bool time_op(MYSQL_TIME *ltime)
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a048f4d933d..06c3aaecd54 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -992,15 +992,15 @@ longlong Item_func_quarter::val_int()
longlong Item_func_hour::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.hour;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->hour;
}
longlong Item_func_minute::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.minute;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->minute;
}
/**
@@ -1009,8 +1009,8 @@ longlong Item_func_minute::val_int()
longlong Item_func_second::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- return get_arg0_time(&ltime) ? 0 : ltime.second;
+ Time tm(args[0], Time::Options_for_cast());
+ return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->second;
}
@@ -1266,24 +1266,20 @@ longlong Item_func_unix_timestamp::val_int_endpoint(bool left_endp, bool *incl_e
longlong Item_func_time_to_sec::int_op()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (get_arg0_time(&ltime))
- return 0;
-
- longlong seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
- return ltime.neg ? -seconds : seconds;
+ Time tm(args[0], Time::Options_for_cast());
+ return ((null_value= !tm.is_valid_time())) ? 0 : tm.to_seconds();
}
my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (get_arg0_time(&ltime))
+ Time tm(args[0], Time::Options_for_cast());
+ if ((null_value= !tm.is_valid_time()))
return 0;
-
- longlong seconds= ltime.hour*3600L+ltime.minute*60+ltime.second;
- return seconds2my_decimal(ltime.neg, seconds, ltime.second_part, buf);
+ const MYSQL_TIME *ltime= tm.get_mysql_time();
+ longlong seconds= tm.to_seconds_abs();
+ return seconds2my_decimal(ltime->neg, seconds, ltime->second_part, buf);
}
@@ -1990,7 +1986,7 @@ String *Item_func_date_format::val_str(String *str)
const MY_LOCALE *lc= 0;
DBUG_ASSERT(fixed == 1);
- if (get_arg0_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0))
+ if ((null_value= args[0]->get_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0)))
return 0;
if (!(format = args[1]->val_str(str)) || !format->length())
@@ -2606,17 +2602,12 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
bool Item_time_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- if (get_arg0_time(ltime))
- return 1;
+ Time tm(args[0], Time::Options_for_cast());
+ if ((null_value= !tm.is_valid_time()))
+ return true;
+ tm.copy_to_mysql_time(ltime);
if (decimals < TIME_SECOND_PART_DIGITS)
my_time_trunc(ltime, decimals);
- /*
- MYSQL_TIMESTAMP_TIME value can have non-zero day part,
- which we should not lose.
- */
- if (ltime->time_type != MYSQL_TIMESTAMP_TIME)
- ltime->year= ltime->month= ltime->day= 0;
- ltime->time_type= MYSQL_TIMESTAMP_TIME;
return (fuzzy_date & TIME_TIME_ONLY) ? 0 :
(null_value= check_date_with_warn(ltime, fuzzy_date,
MYSQL_TIMESTAMP_ERROR));
@@ -2791,7 +2782,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
// ADDTIME function AND the first argument is TIME
if (args[0]->get_time(&l_time1) ||
args[1]->get_time(&l_time2) ||
- l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
+ l_time2.time_type != MYSQL_TIMESTAMP_TIME)
return (null_value= 1);
is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
}
@@ -2956,10 +2947,9 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
longlong Item_func_microsecond::val_int()
{
DBUG_ASSERT(fixed == 1);
- MYSQL_TIME ltime;
- if (!get_arg0_date(&ltime, TIME_TIME_ONLY))
- return ltime.second_part;
- return 0;
+ Time tm(args[0], Time::Options_for_cast());
+ return ((null_value= !tm.is_valid_time())) ?
+ 0 : tm.get_mysql_time()->second_part;
}
@@ -2970,14 +2960,13 @@ longlong Item_func_timestamp_diff::val_int()
long microseconds;
long months= 0;
int neg= 1;
+ THD *thd= current_thd;
+ ulonglong fuzzydate= TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE;
+
+ null_value= 0;
- null_value= 0;
- if (args[0]->get_date_with_conversion(&ltime1,
- TIME_NO_ZERO_DATE |
- TIME_NO_ZERO_IN_DATE) ||
- args[1]->get_date_with_conversion(&ltime2,
- TIME_NO_ZERO_DATE |
- TIME_NO_ZERO_IN_DATE))
+ if (Datetime(thd, args[0], fuzzydate).copy_to_mysql_time(&ltime1) ||
+ Datetime(thd, args[1], fuzzydate).copy_to_mysql_time(&ltime2))
goto null_date;
if (calc_time_diff(&ltime2,&ltime1, 1,
@@ -3343,7 +3332,7 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
bool Item_func_last_day::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- if (get_arg0_date(ltime, fuzzy_date) ||
+ if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY) ||
(ltime->month == 0))
return (null_value=1);
uint month_idx= ltime->month-1;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b21d50a20fe..4ee9cda70bf 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6112,12 +6112,14 @@ int mysqld_main(int argc, char **argv)
mysqld_port, MYSQL_COMPILATION_COMMENT);
}
+#ifndef _WIN32
// try to keep fd=0 busy
- if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin))
+ if (!freopen("/dev/null", "r", stdin))
{
// fall back on failure
fclose(stdin);
}
+#endif
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
Service.SetRunning();
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index a60ca28044f..618c866a3b9 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -3013,24 +3013,6 @@ end:
}
-bool partition_info::error_if_requires_values() const
-{
- switch (part_type) {
- case NOT_A_PARTITION:
- case HASH_PARTITION:
- case VERSIONING_PARTITION:
- break;
- case RANGE_PARTITION:
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN");
- return true;
- case LIST_PARTITION:
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN");
- return true;
- }
- return false;
-}
-
-
/**
Fix partition data from parser.
@@ -3548,3 +3530,20 @@ bool check_partition_dirs(partition_info *part_info)
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
+
+bool partition_info::error_if_requires_values() const
+{
+ switch (part_type) {
+ case NOT_A_PARTITION:
+ case HASH_PARTITION:
+ case VERSIONING_PARTITION:
+ break;
+ case RANGE_PARTITION:
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN");
+ return true;
+ case LIST_PARTITION:
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN");
+ return true;
+ }
+ return false;
+}
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 61eaa535c00..a58a9254a82 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -926,12 +926,19 @@ With_element::rename_columns_of_derived_unit(THD *thd,
my_error(ER_WITH_COL_WRONG_LIST, MYF(0));
return true;
}
+
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+
/* Rename the columns of the first select in the unit */
while ((item= it++, name= nm++))
{
item->set_name(thd, name->str, (uint) name->length, system_charset_info);
item->is_autogenerated_name= false;
}
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
}
else
make_valid_column_names(thd, select->item_list);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1b066cd2df4..64359a585e3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4290,7 +4290,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Give warnings for not supported table options */
#if defined(WITH_ARIA_STORAGE_ENGINE)
extern handlerton *maria_hton;
- if (file->ht != maria_hton)
+ if (file->partition_ht() != maria_hton)
#endif
if (create_info->transactional)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 9e4c53b8849..a11b5a7978f 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -125,12 +125,38 @@ bool Type_handler_data::init()
Type_handler_data *type_handler_data= NULL;
-void Time::make_from_item(Item *item)
+void Time::make_from_item(Item *item, const Options opt)
{
- if (item->get_time(this))
+ if (item->get_date(this, opt.get_date_flags()))
time_type= MYSQL_TIMESTAMP_NONE;
else
- valid_MYSQL_TIME_to_valid_value();
+ valid_MYSQL_TIME_to_valid_value(opt);
+}
+
+
+void Temporal_with_date::make_from_item(THD *thd, Item *item, sql_mode_t flags)
+{
+ flags&= ~TIME_TIME_ONLY;
+ /*
+ Some TIME type items return error when trying to do get_date()
+ without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
+ In the SQL standard time->datetime conversion mode we add TIME_TIME_ONLY.
+ In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
+ and leave it to get_date() to check date.
+ */
+ ulonglong time_flag= (item->field_type() == MYSQL_TYPE_TIME &&
+ !(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
+ TIME_TIME_ONLY : 0;
+ if (item->get_date(this, flags | time_flag))
+ time_type= MYSQL_TIMESTAMP_NONE;
+ else if (time_type == MYSQL_TIMESTAMP_TIME)
+ {
+ MYSQL_TIME tmp;
+ if (time_to_datetime_with_warn(thd, this, &tmp, flags))
+ time_type= MYSQL_TIMESTAMP_NONE;
+ else
+ *(static_cast<MYSQL_TIME*>(this))= tmp;
+ }
}
@@ -3576,7 +3602,55 @@ Type_handler_temporal_result::Item_func_hybrid_field_type_get_date(
MYSQL_TIME *ltime,
ulonglong fuzzydate) const
{
- return item->get_date_from_date_op(ltime, fuzzydate);
+ return item->date_op(ltime, fuzzydate);
+}
+
+
+/***************************************************************************/
+
+String *
+Type_handler_time_common::Item_func_hybrid_field_type_val_str(
+ Item_func_hybrid_field_type *item,
+ String *str) const
+{
+ return item->val_str_from_time_op(str);
+}
+
+
+double
+Type_handler_time_common::Item_func_hybrid_field_type_val_real(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return item->val_real_from_time_op();
+}
+
+
+longlong
+Type_handler_time_common::Item_func_hybrid_field_type_val_int(
+ Item_func_hybrid_field_type *item)
+ const
+{
+ return item->val_int_from_time_op();
+}
+
+
+my_decimal *
+Type_handler_time_common::Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *item,
+ my_decimal *dec) const
+{
+ return item->val_decimal_from_time_op(dec);
+}
+
+
+bool
+Type_handler_time_common::Item_func_hybrid_field_type_get_date(
+ Item_func_hybrid_field_type *item,
+ MYSQL_TIME *ltime,
+ ulonglong fuzzydate) const
+{
+ return item->time_op(ltime);
}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 0446c93f88f..0738ef40ce8 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -95,6 +95,47 @@ struct SORT_FIELD_ATTR;
*/
class Time: private MYSQL_TIME
{
+public:
+ enum datetime_to_time_mode_t
+ {
+ DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS,
+ DATETIME_TO_TIME_YYYYMMDD_TRUNCATE
+ };
+ class Options
+ {
+ sql_mode_t m_get_date_flags;
+ datetime_to_time_mode_t m_datetime_to_time_mode;
+ public:
+ Options()
+ :m_get_date_flags(flags_for_get_date()),
+ m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
+ { }
+ Options(sql_mode_t flags)
+ :m_get_date_flags(flags),
+ m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
+ { }
+ Options(sql_mode_t flags, datetime_to_time_mode_t dtmode)
+ :m_get_date_flags(flags),
+ m_datetime_to_time_mode(dtmode)
+ { }
+ sql_mode_t get_date_flags() const
+ { return m_get_date_flags; }
+ datetime_to_time_mode_t datetime_to_time_mode() const
+ { return m_datetime_to_time_mode; }
+ };
+ /*
+ CAST(AS TIME) historically does not mix days to hours.
+ This is different comparing to how implicit conversion
+ in Field::store_time_dec() works (e.g. on INSERT).
+ */
+ class Options_for_cast: public Options
+ {
+ public:
+ Options_for_cast()
+ :Options(flags_for_get_date(), DATETIME_TO_TIME_YYYYMMDD_TRUNCATE)
+ { }
+ };
+private:
bool is_valid_value_slow() const
{
return time_type == MYSQL_TIMESTAMP_NONE || is_valid_time_slow();
@@ -114,7 +155,7 @@ class Time: private MYSQL_TIME
e.g. returned from Item::get_date().
After this call, "this" is a valid TIME value.
*/
- void valid_datetime_to_valid_time()
+ void valid_datetime_to_valid_time(const Options opt)
{
DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE ||
time_type == MYSQL_TIMESTAMP_DATETIME);
@@ -124,7 +165,9 @@ class Time: private MYSQL_TIME
*/
DBUG_ASSERT(day < 32);
DBUG_ASSERT(hour < 24);
- if (year == 0 && month == 0)
+ if (year == 0 && month == 0 &&
+ opt.datetime_to_time_mode() ==
+ DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
{
/*
The maximum hour value after mixing days will be 31*24+23=767,
@@ -149,12 +192,12 @@ class Time: private MYSQL_TIME
- either a valid TIME (within the supported TIME range),
- or MYSQL_TIMESTAMP_NONE
*/
- void valid_MYSQL_TIME_to_valid_value()
+ void valid_MYSQL_TIME_to_valid_value(const Options opt)
{
switch (time_type) {
case MYSQL_TIMESTAMP_DATE:
case MYSQL_TIMESTAMP_DATETIME:
- valid_datetime_to_valid_time();
+ valid_datetime_to_valid_time(opt);
break;
case MYSQL_TIMESTAMP_NONE:
break;
@@ -166,19 +209,35 @@ class Time: private MYSQL_TIME
break;
}
}
- void make_from_item(class Item *item);
+ void make_from_item(class Item *item, const Options opt);
public:
Time() { time_type= MYSQL_TIMESTAMP_NONE; }
- Time(Item *item) { make_from_item(item); }
+ Time(Item *item) { make_from_item(item, Options()); }
+ Time(Item *item, const Options opt) { make_from_item(item, opt); }
+ static sql_mode_t flags_for_get_date()
+ { return TIME_TIME_ONLY | TIME_INVALID_DATES; }
+ static sql_mode_t comparison_flags_for_get_date()
+ { return TIME_TIME_ONLY | TIME_INVALID_DATES | TIME_FUZZY_DATES; }
bool is_valid_time() const
{
DBUG_ASSERT(is_valid_value_slow());
return time_type == MYSQL_TIMESTAMP_TIME;
}
- void copy_to_mysql_time(MYSQL_TIME *ltime) const
+ const MYSQL_TIME *get_mysql_time() const
{
DBUG_ASSERT(is_valid_time_slow());
+ return this;
+ }
+ bool copy_to_mysql_time(MYSQL_TIME *ltime) const
+ {
+ if (time_type == MYSQL_TIMESTAMP_NONE)
+ {
+ ltime->time_type= MYSQL_TIMESTAMP_NONE;
+ return true;
+ }
+ DBUG_ASSERT(is_valid_time_slow());
*ltime= *this;
+ return false;
}
int cmp(const Time *other) const
{
@@ -192,9 +251,175 @@ public:
return 1;
return 0;
}
+ longlong to_seconds_abs() const
+ {
+ DBUG_ASSERT(is_valid_time_slow());
+ return hour * 3600L + minute * 60 + second;
+ }
+ longlong to_seconds() const
+ {
+ return neg ? -to_seconds_abs() : to_seconds_abs();
+ }
};
+/**
+ Class Temporal_with_date is designed to store valid DATE or DATETIME values.
+ See also class Time.
+
+ 1. Valid value:
+ a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a valid DATE or DATETIME value
+ b. MYSQL_TIMESTAMP_NONE - an undefined value
+
+ 2. Invalid value (internally only):
+ a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a DATE or DATETIME value, but with
+ MYSQL_TIME members outside of the
+ valid/supported range
+ b. MYSQL_TIMESTAMP_TIME - a TIME value
+ c. MYSQL_TIMESTAMP_ERROR - error
+
+ Temporarily is allowed to have an invalid value, but only internally,
+ during initialization time. All constructors and modification methods must
+ leave the value as described above (see "Valid value").
+
+ Derives from MYSQL_TIME using "protected" inheritance to make sure
+ it is accessed externally only in the valid state.
+*/
+
+class Temporal_with_date: protected MYSQL_TIME
+{
+protected:
+ void make_from_item(THD *thd, Item *item, sql_mode_t flags);
+ Temporal_with_date(THD *thd, Item *item, sql_mode_t flags)
+ {
+ make_from_item(thd, item, flags);
+ }
+};
+
+
+/**
+ Class Date is designed to store valid DATE values.
+ All constructors and modification methods leave instances
+ of this class in one of the following valid states:
+ a. MYSQL_TIMESTAMP_DATE - a DATE with all MYSQL_TIME members properly set
+ b. MYSQL_TIMESTAMP_NONE - an undefined value.
+ Other MYSQL_TIMESTAMP_XXX are not possible.
+ MYSQL_TIMESTAMP_DATE with MYSQL_TIME members improperly set is not possible.
+*/
+class Date: public Temporal_with_date
+{
+ bool is_valid_value_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_NONE || is_valid_date_slow();
+ }
+ bool is_valid_date_slow() const
+ {
+ DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE);
+ return !check_datetime_range(this);
+ }
+public:
+ Date(THD *thd, Item *item, sql_mode_t flags)
+ :Temporal_with_date(thd, item, flags)
+ {
+ if (time_type == MYSQL_TIMESTAMP_DATETIME)
+ datetime_to_date(this);
+ DBUG_ASSERT(is_valid_value_slow());
+ }
+ Date(const Temporal_with_date *d)
+ :Temporal_with_date(*d)
+ {
+ datetime_to_date(this);
+ DBUG_ASSERT(is_valid_date_slow());
+ }
+ bool is_valid_date() const
+ {
+ DBUG_ASSERT(is_valid_value_slow());
+ return time_type == MYSQL_TIMESTAMP_DATE;
+ }
+ const MYSQL_TIME *get_mysql_time() const
+ {
+ DBUG_ASSERT(is_valid_date_slow());
+ return this;
+ }
+};
+
+
+/**
+ Class Datetime is designed to store valid DATETIME values.
+ All constructors and modification methods leave instances
+ of this class in one of the following valid states:
+ a. MYSQL_TIMESTAMP_DATETIME - a DATETIME with all members properly set
+ b. MYSQL_TIMESTAMP_NONE - an undefined value.
+ Other MYSQL_TIMESTAMP_XXX are not possible.
+ MYSQL_TIMESTAMP_DATETIME with MYSQL_TIME members
+ improperly set is not possible.
+*/
+class Datetime: public Temporal_with_date
+{
+ bool is_valid_value_slow() const
+ {
+ return time_type == MYSQL_TIMESTAMP_NONE || is_valid_datetime_slow();
+ }
+ bool is_valid_datetime_slow() const
+ {
+ DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATETIME);
+ return !check_datetime_range(this);
+ }
+public:
+ Datetime(THD *thd, Item *item, sql_mode_t flags)
+ :Temporal_with_date(thd, item, flags)
+ {
+ if (time_type == MYSQL_TIMESTAMP_DATE)
+ date_to_datetime(this);
+ DBUG_ASSERT(is_valid_value_slow());
+ }
+ bool is_valid_datetime() const
+ {
+ /*
+ Here we quickly check for the type only.
+ If the type is valid, the rest of value must also be valid.
+ */
+ DBUG_ASSERT(is_valid_value_slow());
+ return time_type == MYSQL_TIMESTAMP_DATETIME;
+ }
+ bool hhmmssff_is_zero() const
+ {
+ DBUG_ASSERT(is_valid_datetime_slow());
+ return hour == 0 && minute == 0 && second == 0 && second_part == 0;
+ }
+ const MYSQL_TIME *get_mysql_time() const
+ {
+ DBUG_ASSERT(is_valid_datetime_slow());
+ return this;
+ }
+ bool copy_to_mysql_time(MYSQL_TIME *ltime) const
+ {
+ if (time_type == MYSQL_TIMESTAMP_NONE)
+ {
+ ltime->time_type= MYSQL_TIMESTAMP_NONE;
+ return true;
+ }
+ DBUG_ASSERT(is_valid_datetime_slow());
+ *ltime= *this;
+ return false;
+ }
+ /**
+ Copy without data loss, with an optional DATETIME to DATE conversion.
+ If the value of the "type" argument is MYSQL_TIMESTAMP_DATE,
+ then "this" must be a datetime with a zero hhmmssff part.
+ */
+ bool copy_to_mysql_time(MYSQL_TIME *ltime, timestamp_type type)
+ {
+ DBUG_ASSERT(type == MYSQL_TIMESTAMP_DATE ||
+ type == MYSQL_TIMESTAMP_DATETIME);
+ if (copy_to_mysql_time(ltime))
+ return true;
+ DBUG_ASSERT(type != MYSQL_TIMESTAMP_DATE || hhmmssff_is_zero());
+ ltime->time_type= type;
+ return false;
+ }
+};
+
/*
Flags for collation aggregation modes, used in TDCollation::agg():
@@ -2234,6 +2459,18 @@ public:
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
+ String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
+ String *) const;
+ double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
+ const;
+ longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
+ const;
+ my_decimal *Item_func_hybrid_field_type_val_decimal(
+ Item_func_hybrid_field_type *,
+ my_decimal *) const;
+ bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
+ MYSQL_TIME *,
+ ulonglong fuzzydate) const;
bool Item_func_min_max_get_date(Item_func_min_max*,
MYSQL_TIME *, ulonglong fuzzydate) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 990d71d7f27..4d62efd8988 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1755,11 +1755,13 @@ bool ha_connect::CheckVirtualIndex(TABLE_SHARE *s)
bool ha_connect::IsPartitioned(void)
{
+#ifdef WITH_PARTITION_STORAGE_ENGINE
if (tshp)
return tshp->partition_info_str_len > 0;
else if (table && table->part_info)
return true;
else
+#endif
return false;
} // end of IsPartitioned
@@ -6166,8 +6168,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABLE *st= table; // Probably unuseful
THD *thd= ha_thd();
LEX_CSTRING cnc = table_arg->s->connect_string;
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
+#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info= table_arg->part_info;
+#else
+#define part_info 0
#endif // WITH_PARTITION_STORAGE_ENGINE
xp= GetUser(thd, xp);
PGLOBAL g= xp->g;
@@ -6269,9 +6273,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
// fall through
case TAB_MYSQL:
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (!part_info)
-#endif // WITH_PARTITION_STORAGE_ENGINE
{const char *src= options->srcdef;
PCSZ host, db, tab= options->tabname;
int port;
@@ -6535,7 +6537,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} else
lwt[i]= tolower(options->type[i]);
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info) {
char *p;
@@ -6545,7 +6546,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
strcat(strcat(strcpy(buf, p), "."), lwt);
*p= 0;
} else {
-#endif // WITH_PARTITION_STORAGE_ENGINE
strcat(strcat(strcpy(buf, GetTableName()), "."), lwt);
sprintf(g->Message, "No file name. Table will use %s", buf);
@@ -6553,9 +6553,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/");
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
} // endif part_info
-#endif // WITH_PARTITION_STORAGE_ENGINE
PlugSetPath(fn, buf, dbpath);
@@ -6620,11 +6618,9 @@ int ha_connect::create(const char *name, TABLE *table_arg,
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Unexpected command in create, please contact CONNECT team");
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info && !inward)
strncpy(partname, decode(g, strrchr(name, '#') + 1), sizeof(partname) - 1);
// strcpy(partname, part_info->curr_part_elem->partition_name);
-#endif // WITH_PARTITION_STORAGE_ENGINE
if (g->Alchecked == 0 &&
(!IsFileType(type) || FileExists(options->filename, false))) {
@@ -6660,12 +6656,10 @@ int ha_connect::create(const char *name, TABLE *table_arg,
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc = HA_ERR_INTERNAL_ERROR;
} else if (cat) {
-#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info)
strncpy(partname,
decode(g, strrchr(name, (inward ? slash : '#')) + 1),
sizeof(partname) - 1);
-#endif // WITH_PARTITION_STORAGE_ENGINE
if ((rc= optimize(table->in_use, NULL))) {
htrc("Create rc=%d %s\n", rc, g->Message);
diff --git a/storage/heap/_check.c b/storage/heap/_check.c
index 910a0d20256..fd8652d6a2a 100644
--- a/storage/heap/_check.c
+++ b/storage/heap/_check.c
@@ -79,7 +79,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
}
hp_find_record(info,pos);
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
deleted++;
else
records++;
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index b953b1dbb23..dc7b225f592 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -90,15 +90,6 @@ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
- if (table->s->reclength < sizeof (char*))
- {
- MEM_UNDEFINED(table->s->default_values + table->s->reclength,
- sizeof(char*) - table->s->reclength);
- table->s->reclength= sizeof(char*);
- MEM_UNDEFINED(table->record[0], table->s->reclength);
- MEM_UNDEFINED(table->record[1], table->s->reclength);
- }
-
internal_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE);
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
{
@@ -713,7 +704,7 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
}
}
}
- mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
+ mem_per_row+= MY_ALIGN(MY_MAX(share->reclength, sizeof(char*)) + 1, sizeof(char*));
if (table_arg->found_next_number_field)
{
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index 431e992e75b..ed669069b96 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
uint keys= create_info->keys;
ulong min_records= create_info->min_records;
ulong max_records= create_info->max_records;
+ uint visible_offset;
DBUG_ENTER("heap_create");
if (!create_info->internal_table)
@@ -58,9 +59,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
/*
We have to store sometimes uchar* del_link in records,
- so the record length should be at least sizeof(uchar*)
+ so the visible_offset must be least at sizeof(uchar*)
*/
- set_if_bigger(reclength, sizeof (uchar*));
+ visible_offset= MY_MAX(reclength, sizeof (char*));
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
{
@@ -154,7 +155,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys);
- init_block(&share->block, reclength + 1, min_records, max_records);
+ init_block(&share->block, visible_offset + 1, min_records, max_records);
/* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
@@ -196,6 +197,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
share->max_table_size= create_info->max_table_size;
share->data_length= share->index_length= 0;
share->reclength= reclength;
+ share->visible= visible_offset;
share->blength= 1;
share->keys= keys;
share->max_key_length= max_length;
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index 301606af397..62f21497f29 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
info->update=HA_STATE_DELETED;
*((uchar**) pos)=share->del_link;
share->del_link=pos;
- pos[share->reclength]=0; /* Record deleted */
+ pos[share->visible]=0; /* Record deleted */
share->deleted++;
share->key_version++;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
diff --git a/storage/heap/hp_rrnd.c b/storage/heap/hp_rrnd.c
index 6bf1888275e..1f2a26cb3ed 100644
--- a/storage/heap/hp_rrnd.c
+++ b/storage/heap/hp_rrnd.c
@@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos)
info->update= 0;
DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
}
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
{
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c
index 40c5a18f974..19767fd752b 100644
--- a/storage/heap/hp_rsame.c
+++ b/storage/heap/hp_rsame.c
@@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rsame");
test_active(info);
- if (info->current_ptr[share->reclength])
+ if (info->current_ptr[share->visible])
{
if (inx < -1 || inx >= (int) share->keys)
{
diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c
index 39a6f2082a3..65726c37e1f 100644
--- a/storage/heap/hp_scan.c
+++ b/storage/heap/hp_scan.c
@@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record)
}
hp_find_record(info, pos);
}
- if (!info->current_ptr[share->reclength])
+ if (!info->current_ptr[share->visible])
{
DBUG_PRINT("warning",("Found deleted record"));
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c
index 392662f69ae..a1e4de446d0 100644
--- a/storage/heap/hp_write.c
+++ b/storage/heap/hp_write.c
@@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record)
}
memcpy(pos,record,(size_t) share->reclength);
- pos[share->reclength]=1; /* Mark record as not deleted */
+ pos[share->visible]= 1; /* Mark record as not deleted */
if (++share->records == share->blength)
share->blength+= share->blength;
info->s->key_version++;
@@ -92,7 +92,7 @@ err:
share->deleted++;
*((uchar**) pos)=share->del_link;
share->del_link=pos;
- pos[share->reclength]=0; /* Record deleted */
+ pos[share->visible]= 0; /* Record deleted */
DBUG_RETURN(my_errno);
} /* heap_write */
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index c2d614451a3..dc61f773e96 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -174,7 +174,13 @@ IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
btr/btr0btr.cc
btr/btr0cur.cc
buf/buf0buf.cc
+ fts/fts0fts.cc
gis/gis0sea.cc
+ handler/handler0alter.cc
+ mtr/mtr0mtr.cc
+ row/row0merge.cc
+ row/row0mysql.cc
+ srv/srv0srv.cc
COMPILE_FLAGS "-O0"
)
ENDIF()
@@ -192,4 +198,6 @@ ENDIF()
ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup)
-ADD_DEPENDENCIES(innobase GenError)
+IF(TARGET innobase)
+ ADD_DEPENDENCIES(innobase GenError)
+ENDIF()
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 2531a9fb5aa..dd0148a3275 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1108,7 +1108,7 @@ fsp_fill_free_list(
skip_resize = !srv_sys_space.can_auto_extend_last_file();
break;
case SRV_TMP_SPACE_ID:
- skip_resize = srv_tmp_space.can_auto_extend_last_file();
+ skip_resize = !srv_tmp_space.can_auto_extend_last_file();
break;
}
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 4b0f03c66ed..4470b771ad3 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -145,6 +145,11 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page);
static void _ma_bitmap_unpin_all(MARIA_SHARE *share);
+#ifndef DBUG_OFF
+static void _ma_check_bitmap(MARIA_FILE_BITMAP *bitmap);
+#else
+#define _ma_check_bitmap(A) do { } while(0)
+#endif
/* Write bitmap page to key cache */
@@ -267,6 +272,13 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
bitmap->sizes[6]= max_page_size - max_page_size * 80 / 100;
bitmap->sizes[7]= 0;
+ /*
+ If a record size will fit into the smallest empty page, return first
+ found page in find_head()
+ */
+ if (bitmap->sizes[3] >= share->base.max_pack_length)
+ bitmap->return_first_match= 1;
+
mysql_mutex_init(key_SHARE_BITMAP_lock,
&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
mysql_cond_init(key_SHARE_BITMAP_cond,
@@ -677,7 +689,8 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
bzero(bitmap->map, bitmap->block_size);
bitmap->changed= 1;
bitmap->page= 0;
- bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
+ bitmap->used_size= bitmap->full_tail_size= bitmap->full_head_size= 0;
+ bitmap->total_size= bitmap->max_total_size;
}
DBUG_VOID_RETURN;
}
@@ -715,6 +728,7 @@ void _ma_bitmap_reset_cache(MARIA_SHARE *share)
*/
bitmap->page= ((pgcache_page_no_t) 0) - bitmap->pages_covered;
bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
+ bitmap->full_head_size= bitmap->full_tail_size= bitmap->max_total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
@@ -1016,9 +1030,6 @@ static void adjust_total_size(MARIA_HA *info, pgcache_page_no_t page)
bitmap Bitmap handler
page Page to read
- TODO
- Update 'bitmap->used_size' to real size of used bitmap
-
NOTE
We don't always have share->bitmap.bitmap_lock here
(when called from_ma_check_bitmap_data() for example).
@@ -1035,6 +1046,9 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
MARIA_SHARE *share= info->s;
my_bool res;
DBUG_ENTER("_ma_read_bitmap_page");
+ DBUG_PRINT("enter", ("page: %lld data_file_length: %lld",
+ (longlong) page,
+ (longlong) share->state.state.data_file_length));
DBUG_ASSERT(page % bitmap->pages_covered == 0);
DBUG_ASSERT(!bitmap->changed);
@@ -1049,13 +1063,22 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
}
adjust_total_size(info, page);
- bitmap->used_size= bitmap->total_size;
+ bitmap->full_head_size= bitmap->full_tail_size= 0;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
res= pagecache_read(share->pagecache,
&bitmap->file, page, 0,
bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL;
+ if (!res)
+ {
+ /* Calculate used_size */
+ const uchar *data, *end= bitmap->map;
+ for (data= bitmap->map + bitmap->total_size; --data >= end && *data == 0; )
+ {}
+ bitmap->used_size= (uint) ((data + 1) - end);
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
+ }
/*
We can't check maria_bitmap_marker here as if the bitmap page
previously had a true checksum and the user switched mode to not checksum
@@ -1067,7 +1090,10 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
#ifndef DBUG_OFF
if (!res)
+ {
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
+ _ma_check_bitmap(bitmap);
+ }
#endif
DBUG_RETURN(res);
}
@@ -1097,6 +1123,8 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
{
DBUG_ENTER("_ma_change_bitmap_page");
+ _ma_check_bitmap(bitmap);
+
/*
We have to mark the file changed here, as otherwise the following
read/write to pagecache may force a page out from this file, which would
@@ -1228,6 +1256,9 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
This is defined as the first page of the set of pages
with the smallest free space that can hold 'size'.
+ NOTES
+ Updates bitmap->full_head_size while scanning data
+
RETURN
0 ok (block is updated)
1 error (no space in bitmap; block is not touched)
@@ -1238,10 +1269,11 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
MARIA_BITMAP_BLOCK *block)
{
uint min_bits= size_to_head_pattern(bitmap, size);
- uchar *data= bitmap->map, *end= data + bitmap->used_size;
+ uchar *data, *end;
uchar *best_data= 0;
uint best_bits= (uint) -1, UNINIT_VAR(best_pos);
- uint first_pattern= 0; /* if doing insert_order */
+ my_bool first_pattern= 0; /* if doing insert_order */
+ my_bool first_found= 1;
MARIA_SHARE *share= bitmap->share;
my_bool insert_order=
MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_INSERT_ORDER);
@@ -1249,16 +1281,19 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
DBUG_ASSERT(size <= FULL_PAGE_SIZE(share));
+ end= bitmap->map + bitmap->used_size;
if (insert_order && bitmap->page == share->last_insert_bitmap)
{
uint last_insert_page= share->last_insert_page;
uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16;
- DBUG_ASSERT(data + byte < end);
- data+= byte;
+ data= bitmap->map+byte;
+ DBUG_ASSERT(data <= end);
}
+ else
+ data= bitmap->map + (bitmap->full_head_size/6)*6;
- for (; data < end; data+= 6)
+ for (; data < end; data+= 6, first_pattern= 0)
{
ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
uint i;
@@ -1271,17 +1306,24 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
*/
if ((!bits && best_data) ||
((bits & 04444444444444444LL) == 04444444444444444LL))
- {
- first_pattern= 0; // always restart from 0 when moving to new 6-byte
continue;
- }
+
for (i= first_pattern, bits >>= (3 * first_pattern); i < 16 ;
i++, bits >>= 3)
{
uint pattern= (uint) (bits & 7);
+
+ if (pattern <= 3) /* Room for more data */
+ {
+ if (first_found)
+ {
+ first_found= 0;
+ bitmap->full_head_size= (uint)(data - bitmap->map);
+ }
+ }
if (pattern <= min_bits)
{
- /* There is enough space here */
+ /* There is enough space here, check if we have found better */
if ((int) pattern > (int) best_bits)
{
/*
@@ -1292,23 +1334,32 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
best_bits= pattern;
best_data= data;
best_pos= i;
- if (pattern == min_bits)
+ if (pattern == min_bits || bitmap->return_first_match)
goto found; /* Best possible match */
}
}
}
- first_pattern= 0; // always restart from 0 when moving to new 6-byte
}
if (!best_data) /* Found no place */
{
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1); /* No space in bitmap */
+ DBUG_ASSERT(uint6korr(data) == 0);
/* Allocate data at end of bitmap */
- bitmap->used_size+= 6;
- set_if_smaller(bitmap->used_size, bitmap->total_size);
+ bitmap->used_size= (uint) (data - bitmap->map) + 6;
best_data= data;
best_pos= best_bits= 0;
}
+ else
+ {
+ /*
+ This is not stricly needed as used_size should be alligned on 6,
+ but for easier debugging lets try to keep it more accurate
+ */
+ uint position= (uint) (best_data - bitmap->map) + 6;
+ set_if_bigger(bitmap->used_size, position);
+ }
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
found:
if (insert_order)
@@ -1341,12 +1392,15 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
MARIA_BITMAP_BLOCK *block)
{
uint min_bits= size_to_tail_pattern(bitmap, size);
- uchar *data= bitmap->map, *end= data + bitmap->used_size;
- uchar *best_data= 0;
+ uchar *data, *end, *best_data= 0;
+ my_bool first_found= 1;
uint best_bits= (uint) -1, UNINIT_VAR(best_pos);
DBUG_ENTER("allocate_tail");
DBUG_PRINT("enter", ("size: %u", size));
+ data= bitmap->map + (bitmap->full_tail_size/6)*6;
+ end= bitmap->map + bitmap->used_size;
+
/*
We have to add DIR_ENTRY_SIZE here as this is not part of the data size
See call to allocate_tail() in find_tail().
@@ -1375,7 +1429,19 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
for (i= 0; i < 16; i++, bits >>= 3)
{
uint pattern= (uint) (bits & 7);
- if (pattern <= min_bits && (!pattern || pattern >= 5))
+
+ if (pattern == 0 ||
+ (pattern > FULL_HEAD_PAGE && pattern < FULL_TAIL_PAGE))
+ {
+ /* There is room for tail data */
+ if (first_found)
+ {
+ first_found= 0;
+ bitmap->full_tail_size= (uint)(data - bitmap->map);
+ }
+ }
+
+ if (pattern <= min_bits && (!pattern || pattern > FULL_HEAD_PAGE))
{
if ((int) pattern > (int) best_bits)
{
@@ -1392,10 +1458,11 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
{
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1);
+ DBUG_ASSERT(uint6korr(data) == 0);
/* Allocate data at end of bitmap */
best_data= data;
- bitmap->used_size+= 6;
- set_if_smaller(bitmap->used_size, bitmap->total_size);
+ bitmap->used_size= (uint) (data - bitmap->map) + 6;
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
best_pos= best_bits= 0;
}
@@ -1434,8 +1501,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
ulong pages_needed,
MARIA_BITMAP_BLOCK *block, my_bool full_page)
{
- uchar *data= bitmap->map, *data_end= data + bitmap->used_size;
- uchar *page_end= data + bitmap->total_size;
+ uchar *data, *data_end, *page_end;
uchar *best_data= 0;
uint min_size;
uint best_area_size, UNINIT_VAR(best_prefix_area_size);
@@ -1449,6 +1515,10 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
min_size= BLOB_SEGMENT_MIN_SIZE;
best_area_size= ~(uint) 0;
+ data= bitmap->map + (bitmap->full_head_size/6)*6;
+ data_end= bitmap->map + bitmap->used_size;
+ page_end= bitmap->map + bitmap->total_size;
+
for (; data < page_end; data+= 6)
{
ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
@@ -1466,6 +1536,12 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
if ((bits= uint6korr(data)))
break;
}
+ /*
+ Check if we are end of bitmap. In this case we know that
+ the rest of the bitmap is usable
+ */
+ if (data >= data_end)
+ data= page_end;
area_size= (uint) (data - data_start) / 6 * 16;
if (area_size >= best_area_size)
continue;
@@ -1823,7 +1899,7 @@ static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
/*
- Store in the bitmap the new size for a head page
+ Reserve the current head page
SYNOPSIS
use_head()
@@ -2225,7 +2301,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
pgcache_page_no_t page, uint fill_pattern)
{
pgcache_page_no_t bitmap_page;
- uint offset_page, offset, tmp, org_tmp;
+ uint offset_page, offset, tmp, org_tmp, used_offset;
uchar *data;
DBUG_ENTER("set_page_bits");
DBUG_ASSERT(fill_pattern <= 7);
@@ -2237,6 +2313,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
/* Find page number from start of bitmap */
offset_page= (uint) (page - bitmap->page - 1);
+
/*
Mark place used by reading/writing 2 bytes at a time to handle
bitmaps in overlapping bytes
@@ -2248,11 +2325,37 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
if (tmp == org_tmp)
DBUG_RETURN(0); /* No changes */
- int2store(data, tmp);
+ /*
+ Take care to not write bytes outside of bitmap.
+ fill_pattern is 3 bits, so we need to write two bytes
+ if bit position we write to is > (8-3)
+ */
+ if (offset > 5)
+ int2store(data, tmp);
+ else
+ data[0]= tmp;
+
+ /*
+ Reset full_head_size or full_tail_size if we are releasing data before
+ it. Increase used_size if we are allocating data.
+ */
+ used_offset= (uint) (data - bitmap->map);
+ if (fill_pattern < 4)
+ set_if_smaller(bitmap->full_head_size, used_offset);
+ if (fill_pattern == 0 || (fill_pattern > 4 && fill_pattern < 7))
+ set_if_smaller(bitmap->full_tail_size, used_offset);
+ if (fill_pattern != 0)
+ {
+ /* Calulcate which was the last changed byte */
+ used_offset+= offset > 5 ? 2 : 1;
+ set_if_bigger(bitmap->used_size, used_offset);
+ }
+
+ _ma_check_bitmap(bitmap);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
- if (fill_pattern != 3 && fill_pattern != 7)
+ if (fill_pattern != FULL_HEAD_PAGE && fill_pattern != FULL_TAIL_PAGE)
set_if_smaller(info->s->state.first_bitmap_with_space, bitmap_page);
/*
Note that if the condition above is false (page is full), and all pages of
@@ -2345,7 +2448,7 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
uint page_count)
{
ulonglong bitmap_page;
- uint offset, bit_start, bit_count, tmp;
+ uint offset, bit_start, bit_count, tmp, byte_offset;
uchar *data;
DBUG_ENTER("_ma_bitmap_reset_full_page_bits");
DBUG_PRINT("enter", ("page: %lu page_count: %u", (ulong) page, page_count));
@@ -2365,7 +2468,8 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
bit_start= offset * 3;
bit_count= page_count * 3;
- data= bitmap->map + bit_start / 8;
+ byte_offset= bit_start/8;
+ data= bitmap->map + byte_offset;
offset= bit_start & 7;
tmp= (255 << offset); /* Bits to keep */
@@ -2376,6 +2480,9 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
}
*data&= ~tmp;
+ set_if_smaller(bitmap->full_head_size, byte_offset);
+ set_if_smaller(bitmap->full_tail_size, byte_offset);
+
if ((int) (bit_count-= (8 - offset)) > 0)
{
uint fill;
@@ -2477,6 +2584,8 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
tmp= (1 << bit_count) - 1;
*data|= tmp;
}
+ set_if_bigger(bitmap->used_size, (uint) (data - bitmap->map) + 1);
+ _ma_check_bitmap(bitmap);
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(0);
@@ -2835,6 +2944,72 @@ my_bool _ma_check_bitmap_data(MARIA_HA *info, enum en_page_type page_type,
return (bitmap_pattern != bits);
}
+/**
+ Check that bitmap looks correct
+
+ - All data before full_head_size and full_tail_size are allocated
+ - There is no allocated data after used_size
+ All of the above need to be correct only according to 6 byte
+ alignment as all loops reads 6 bytes at a time and we check both
+ start and end position according to the current 6 byte position.
+*/
+
+#ifndef DBUG_OFF
+static void _ma_check_bitmap(MARIA_FILE_BITMAP *bitmap)
+{
+ uchar *data= bitmap->map;
+ uchar *end= bitmap->map + bitmap->total_size;
+ uchar *full_head_end=0, *full_tail_end=0, *first_empty= bitmap->map;
+
+ for (; data < end; data+= 6)
+ {
+ ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
+ uint i;
+
+ if (bits == 04444444444444444LL || bits == 0xffffffffffffLL)
+ {
+ first_empty= data + 6;
+ continue; /* block fully used */
+ }
+ if (bits == 0)
+ {
+ if (!full_head_end)
+ full_head_end= data;
+ if (!full_tail_end)
+ full_tail_end= data;
+ continue;
+ }
+
+ first_empty= data + 6;
+ if (!full_head_end || !full_tail_end)
+ {
+ for (i= 0, bits >>= 0; i < 16 ; i++, bits >>= 3)
+ {
+ uint pattern= (uint) (bits & 7);
+ if (pattern == FULL_HEAD_PAGE || pattern == FULL_TAIL_PAGE)
+ continue;
+
+ if (pattern < 4 && !full_head_end)
+ full_head_end= data;
+ if ((pattern == 0 || (pattern > 4 && pattern < 7)) && !full_tail_end)
+ full_tail_end= data;
+ }
+ }
+ }
+ if (!full_head_end)
+ full_head_end= data;
+ if (!full_tail_end)
+ full_tail_end= data;
+
+ /* used_size must point after the last byte that had some data) */
+ DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
+ DBUG_ASSERT((bitmap->map + (bitmap->used_size+5)/6*6) >= first_empty);
+ /* full_xxxx_size can't point after the first block that has free data */
+ DBUG_ASSERT((bitmap->map + (bitmap->full_head_size/6*6)) <= full_head_end);
+ DBUG_ASSERT((bitmap->map + (bitmap->full_tail_size/6*6)) <= full_tail_end);
+}
+#endif
+
/*
Check if the page type matches the one that we have in the bitmap
@@ -3072,6 +3247,7 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
pgcache_page_no_t from, to;
my_off_t data_file_length= share->state.state.data_file_length;
DBUG_ENTER("_ma_bitmap_create_missing");
+ DBUG_PRINT("enter", ("page: %lld", (longlong) page));
/* First (in offset order) bitmap page to create */
if (data_file_length < block_size)
@@ -3124,7 +3300,8 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
only later as we are going to modify it very soon.
*/
bzero(bitmap->map, bitmap->block_size);
- bitmap->used_size= 0;
+ bitmap->used_size= bitmap->full_head_size= bitmap->full_tail_size= 0;
+ bitmap->changed=1;
#ifndef DBUG_OFF
/*
Make a copy of the page to be able to print out bitmap changes during
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 5909a0175d9..6779516d557 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -275,7 +275,7 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
{
uchar *rec_buff;
int error;
- ulong reclength,extra;
+ ulong reclength,reclength2,extra;
extra= (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+
MARIA_DYN_DELETE_BLOCK_HEADER);
@@ -293,11 +293,12 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
return(1);
}
- reclength= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
+ reclength2= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
record);
+ DBUG_ASSERT(reclength2 <= reclength);
error=update_dynamic_record(info,pos,
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
- reclength);
+ reclength2);
my_safe_afree(rec_buff, reclength);
return(error != 0);
}
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 23dbf4431c5..51cb9574af2 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -332,7 +332,10 @@ typedef struct st_maria_file_bitmap
pgcache_page_no_t last_bitmap_page; /* Last possible bitmap page */
my_bool changed; /* 1 if page needs to be written */
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
+ my_bool return_first_match; /* Shortcut find_head() */
uint used_size; /* Size of bitmap head that is not 0 */
+ uint full_head_size; /* Where to start search for head */
+ uint full_tail_size; /* Where to start search for tail */
uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint waiting_for_flush_all_requested; /* If someone is waiting for above */
uint non_flushable; /**< 0 if bitmap and log are in sync */
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 58aba677c36..44cec1c2550 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -2240,7 +2240,8 @@ public:
}
void set_sync(bool sync) override {
- m_rocksdb_tx->GetWriteOptions()->sync = sync;
+ if (m_rocksdb_tx)
+ m_rocksdb_tx->GetWriteOptions()->sync = sync;
}
void release_lock(rocksdb::ColumnFamilyHandle *const column_family,
@@ -3154,10 +3155,20 @@ static int rocksdb_commit(handlerton* hton, THD* thd, bool commit_tx)
- For a COMMIT statement that finishes a multi-statement transaction
- For a statement that has its own transaction
*/
+
+ // First, commit without syncing. This establishes the commit order
+ tx->set_sync(false);
if (tx->commit()) {
DBUG_RETURN(HA_ERR_ROCKSDB_COMMIT_FAILED);
}
thd_wakeup_subsequent_commits(thd, 0);
+
+ if (rocksdb_flush_log_at_trx_commit == FLUSH_LOG_SYNC)
+ {
+ rocksdb::Status s= rdb->FlushWAL(true);
+ if (!s.ok())
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ }
} else {
/*
We get here when committing a statement within a transaction.
@@ -6145,7 +6156,7 @@ int ha_rocksdb::create_cfs(
// Internal consistency check to make sure that data in TABLE and
// Rdb_tbl_def structures matches. Either both are missing or both are
// specified. Yes, this is critical enough to make it into SHIP_ASSERT.
- SHIP_ASSERT(!table_arg->part_info == tbl_def_arg->base_partition().empty());
+ SHIP_ASSERT(IF_PARTITIONING(!table_arg->part_info,true) == tbl_def_arg->base_partition().empty());
// Generate the name for the column family to use.
bool per_part_match_found = false;
@@ -8384,7 +8395,7 @@ const std::string ha_rocksdb::generate_cf_name(const uint index,
key_comment, table_arg, tbl_def_arg, per_part_match_found,
RDB_CF_NAME_QUALIFIER);
- if (table_arg->part_info != nullptr && !*per_part_match_found) {
+ if (IF_PARTITIONING(table_arg->part_info,nullptr) != nullptr && !*per_part_match_found) {
// At this point we tried to search for a custom CF name for a partition,
// but none was specified. Therefore default one will be used.
return "";
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index ff715423f71..d28cb7552ed 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -1412,6 +1412,6 @@ private:
Rdb_inplace_alter_ctx &operator=(const Rdb_inplace_alter_ctx &);
};
-const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_BETA;
+const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA;
} // namespace myrocks
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
index 021373be02a..27b1fd1e9af 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -69,15 +69,15 @@ set global rocksdb_strict_collation_check=@tmp_rscc;
#
select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
plugin_name plugin_maturity
-ROCKSDB Beta
-ROCKSDB_CFSTATS Beta
-ROCKSDB_DBSTATS Beta
-ROCKSDB_PERF_CONTEXT Beta
-ROCKSDB_PERF_CONTEXT_GLOBAL Beta
-ROCKSDB_CF_OPTIONS Beta
-ROCKSDB_COMPACTION_STATS Beta
-ROCKSDB_GLOBAL_INFO Beta
-ROCKSDB_DDL Beta
-ROCKSDB_INDEX_FILE_MAP Beta
-ROCKSDB_LOCKS Beta
-ROCKSDB_TRX Beta
+ROCKSDB Gamma
+ROCKSDB_CFSTATS Gamma
+ROCKSDB_DBSTATS Gamma
+ROCKSDB_PERF_CONTEXT Gamma
+ROCKSDB_PERF_CONTEXT_GLOBAL Gamma
+ROCKSDB_CF_OPTIONS Gamma
+ROCKSDB_COMPACTION_STATS Gamma
+ROCKSDB_GLOBAL_INFO Gamma
+ROCKSDB_DDL Gamma
+ROCKSDB_INDEX_FILE_MAP Gamma
+ROCKSDB_LOCKS Gamma
+ROCKSDB_TRX Gamma
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index a6d9a358b35..deba2d50ccc 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -538,7 +538,7 @@ const std::string Rdb_key_def::parse_comment_for_qualifier(
// NOTE: this means if you specify a qualifier for a specific partition it
// will take precedence the 'table level' qualifier if one exists.
std::string search_str_part;
- if (table_arg->part_info != nullptr) {
+ if (IF_PARTITIONING(table_arg->part_info,nullptr) != nullptr) {
std::string partition_name = tbl_def_arg->base_partition();
DBUG_ASSERT(!partition_name.empty());
search_str_part = gen_qualifier_for_table(qualifier, partition_name);
diff --git a/storage/spider/CMakeLists.txt b/storage/spider/CMakeLists.txt
index d267a6ba3f9..21278dde3b3 100644
--- a/storage/spider/CMakeLists.txt
+++ b/storage/spider/CMakeLists.txt
@@ -45,6 +45,8 @@ IF(EXISTS ${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake)
${CMAKE_SOURCE_DIR}/regex)
MYSQL_STORAGE_ENGINE(SPIDER)
+ELSEIF(PLUGIN_PARTITION MATCHES "^NO$")
+ MESSAGE(STATUS "Spider is skipped because partitioning is disabled")
ELSE()
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/spider/hs_client)
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index 702b2eaa2dd..aa5949b4860 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -4,6 +4,8 @@ IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
ELSEIF(NOT HAVE_DLOPEN)
MESSAGE(STATUS "dlopen is required by TokuDB")
+ELSEIF(NOT TARGET perfschema)
+ MESSAGE(STATUS "Performance Schema is required by TokuDB")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR
CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
# tokudb requires F_NOCACHE or O_DIRECT, and designated initializers
diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt
index 1285a5f41b7..2186a79f732 100644
--- a/win/upgrade_wizard/CMakeLists.txt
+++ b/win/upgrade_wizard/CMakeLists.txt
@@ -28,7 +28,7 @@ ELSE()
SET(CMAKE_MFC_FLAG 1)
ENDIF()
# Enable exception handling (avoids warnings)
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNO_WARN_MBCS_MFC_DEPRECATION")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
MYSQL_ADD_EXECUTABLE(mysql_upgrade_wizard