Merge branch 'bb-10.2-ext' into 10.3

This commit is contained in:
Sergei Golubchik 2018-02-23 08:43:34 +01:00
commit 2732fcc608
63 changed files with 1137 additions and 517 deletions

View file

@ -162,6 +162,7 @@ INCLUDE(plugin)
INCLUDE(install_macros)
INCLUDE(systemd)
INCLUDE(mysql_add_executable)
INCLUDE(compile_flags)
INCLUDE(crc32-vpmsum)
# Handle options

View file

@ -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 */

View file

@ -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;

View file

@ -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': $!";
}
}

23
mysql-test/lib/My/Tee.pm Normal file
View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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: ''

View file

@ -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;

View file

@ -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.
# -----------------------------------------------------------------

View file

@ -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

View file

@ -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';

View file

@ -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

View file

@ -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

View file

@ -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';

View file

@ -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;

View file

@ -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;

View file

@ -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
#

View file

@ -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

View file

@ -1,4 +1,5 @@
--source include/have_partition.inc
--source include/have_symlink.inc
--let $engine=MyISAM
--source inc/part_alter_values.inc

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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 # -----------------------------------------------------------------

View file

@ -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.

View file

@ -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

View file

@ -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;
}

View file

@ -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:

View file

@ -128,38 +128,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.

View file

@ -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);
}

View file

@ -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);

View file

@ -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"; }

View file

@ -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);
}

View file

@ -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;
}
};

View file

@ -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;
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))
null_value= 0;
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;

View file

@ -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();

View file

@ -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;
}

View file

@ -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);

View file

@ -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,

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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++;

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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)
{

View file

@ -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;

View file

@ -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 */

View file

@ -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()

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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 */

View file

@ -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 "";

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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