mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
730f53f0d2
offset for time part in UUIDs was 1/1000 of what it should be. In other words, offset was off. Also handle the case where we count into the future when several UUIDs are generated in one "tick", and then the next call is late enough for us to unwind some but not all of those borrowed ticks. Lastly, handle the case where we keep borrowing and borrowing until the tick-counter overflows by also changing into a new "numberspace" by creating a new random suffix. mysql-test/r/func_misc.result: Show that time-part of UUIDs is correct now. mysql-test/t/func_misc.test: Show that time-part of UUIDs is correct now by replicating the C-code's resultin SQL. Results also decode to expect date-data on command-line (external validation). No test for unwinding of borrowed ticks as this a) is a race and b) depends on what timer we get. sql/item_strfunc.cc: correct offset for date/time-part of UUID. also make sure that when we counted into the future earlier (several UUIDs generated in same tick), we only give back as many "borrowed" ticks as we can without duplicating past timestamps. If our tick-counter overflows before we can give back, or if the system-clock is set back (by user or Daylight Saving Time), we create a new random suffix to avoid collisions and clear the tick-counter.
456 lines
14 KiB
Text
456 lines
14 KiB
Text
#
|
|
# Testing of misc functions
|
|
#
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1, t2;
|
|
--enable_warnings
|
|
|
|
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
|
|
|
|
select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"));
|
|
select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255");
|
|
select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511);
|
|
|
|
select hex(inet_aton('127'));
|
|
select hex(inet_aton('127.1'));
|
|
select hex(inet_aton('127.1.1'));
|
|
|
|
select length(uuid()), charset(uuid()), length(unhex(replace(uuid(),_utf8'-',_utf8'')));
|
|
|
|
# As we can assume we are the only user for the mysqld server, the difference
|
|
# between two calls should be -1
|
|
set @a= uuid_short();
|
|
set @b= uuid_short();
|
|
select cast(@a - @b as signed);
|
|
|
|
#
|
|
# Test for core dump with nan
|
|
#
|
|
select length(format('nan', 2)) > 0;
|
|
|
|
#
|
|
# Test for bug #628
|
|
#
|
|
select concat("$",format(2500,2));
|
|
|
|
# Test for BUG#7716
|
|
create table t1 ( a timestamp );
|
|
insert into t1 values ( '2004-01-06 12:34' );
|
|
select a from t1 where left(a+0,6) in ( left(20040106,6) );
|
|
select a from t1 where left(a+0,6) = ( left(20040106,6) );
|
|
|
|
select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
|
|
select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
|
|
|
|
select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
|
|
select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
|
|
|
|
drop table t1;
|
|
|
|
|
|
#
|
|
# Bug#16501: IS_USED_LOCK does not appear to work
|
|
#
|
|
|
|
CREATE TABLE t1 (conn CHAR(7), connection_id INT);
|
|
INSERT INTO t1 VALUES ('default', CONNECTION_ID());
|
|
|
|
SELECT GET_LOCK('bug16501',600);
|
|
|
|
connect (con1,localhost,root,,);
|
|
INSERT INTO t1 VALUES ('con1', CONNECTION_ID());
|
|
SELECT IS_USED_LOCK('bug16501') = connection_id
|
|
FROM t1
|
|
WHERE conn = 'default';
|
|
send SELECT GET_LOCK('bug16501',600);
|
|
|
|
connection default;
|
|
SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID();
|
|
SELECT RELEASE_LOCK('bug16501');
|
|
connection con1;
|
|
reap;
|
|
connection default;
|
|
SELECT IS_USED_LOCK('bug16501') = connection_id
|
|
FROM t1
|
|
WHERE conn = 'con1';
|
|
|
|
connection con1;
|
|
SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID();
|
|
SELECT RELEASE_LOCK('bug16501');
|
|
SELECT IS_USED_LOCK('bug16501');
|
|
|
|
disconnect con1;
|
|
connection default;
|
|
|
|
DROP TABLE t1;
|
|
|
|
#
|
|
# Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets
|
|
#
|
|
select export_set(3, _latin1'foo', _utf8'bar', ',', 4);
|
|
|
|
--echo End of 4.1 tests
|
|
|
|
|
|
#
|
|
# Test for BUG#9535
|
|
#
|
|
--disable_warnings
|
|
create table t1 as select uuid(), length(uuid());
|
|
--enable_warnings
|
|
show create table t1;
|
|
drop table t1;
|
|
|
|
#
|
|
# Bug#6760: Add SLEEP() function (feature request)
|
|
#
|
|
# Logics of original test:
|
|
# Reveal that a query with SLEEP does not need less time than estimated.
|
|
#
|
|
# Bug#12689: SLEEP() gets incorrectly cached/optimized-away
|
|
#
|
|
# Description from bug report (slightly modified)
|
|
#
|
|
# Bug 1 (happened all time):
|
|
# SELECT * FROM t1 WHERE SLEEP(1) will only result in a sleep of 1
|
|
# second, regardless of the number of rows in t1.
|
|
# Bug 2 (happened all time):
|
|
# Such a query will also get cached by the query cache, but should not.
|
|
#
|
|
# Notes (mleich, 2008-05)
|
|
# =======================
|
|
#
|
|
# Experiments around
|
|
# Bug#36345 Test 'func_misc' fails on RHAS3 x86_64
|
|
# showed that the tests for both bugs could produce in case of parallel
|
|
# artificial system time (like via ntpd)
|
|
# - decreases false alarm
|
|
# - increases false success
|
|
#
|
|
# We try here to circumvent these issues by reimplementation of the tests
|
|
# and sophisticated scripting, although the cause of the problems is a massive
|
|
# error within the setup of the testing environment.
|
|
# Tests relying on or checking derivates of the system time must never meet
|
|
# parallel manipulations of system time.
|
|
#
|
|
# Results of experiments with/without manipulation of system time,
|
|
# information_schema.processlist content, high load on testing box
|
|
# ----------------------------------------------------------------
|
|
# Definition: Predicted_cumulative_sleep_time =
|
|
# #_of_result_rows * sleep_time_per_result_row
|
|
#
|
|
# 1. Total (real sleep time) ~= predicted_cumulative_sleep_time !!
|
|
# 2. The state of a session within the PROCESSLIST changes to 'User sleep'
|
|
# if the sessions runs a statement containing the sleep function and the
|
|
# processing of the statement is just within the phase where the sleep
|
|
# is done. (*)
|
|
# 3. NOW() and processlist.time behave "synchronous" to system time and
|
|
# show also the "jumps" caused by system time manipulations. (*)
|
|
# 4. processlist.time is unsigned, the "next" value below 0 is ~ 4G (*)
|
|
# 5. Current processlist.time ~= current real sleep time if the system time
|
|
# was not manipulated. (*)
|
|
# 6. High system load can cause delays of <= 2 seconds.
|
|
# 7. Thanks to Davi for excellent hints and ideas.
|
|
#
|
|
# (*)
|
|
# - information_schema.processlist is not available before MySQL 5.1.
|
|
# - Observation of processlist content requires a
|
|
# - "worker" session sending the query with "send" and pulling results
|
|
# with "reap"
|
|
# - session observing the processlist parallel to the worker session
|
|
# "send" and "reap" do not work in case of an embedded server.
|
|
# Conclusion: Tests based on processlist have too many restrictions.
|
|
#
|
|
# Solutions for subtests based on TIMEDIFF of values filled via NOW()
|
|
# -------------------------------------------------------------------
|
|
# Run the following sequence three times
|
|
# 1. SELECT <start_time>
|
|
# 2. Query with SLEEP
|
|
# 3. SELECT <end_time>
|
|
# If TIMEDIFF(<end_time>,<start_time>) is at least two times within a
|
|
# reasonable range assume that we did not met errors we were looking for.
|
|
#
|
|
# It is extreme unlikely that we have two system time changes within the
|
|
# < 30 seconds runtime. Even if the unlikely happens, there are so
|
|
# frequent runs of this test on this or another testing box which will
|
|
# catch the problem.
|
|
#
|
|
|
|
--echo #------------------------------------------------------------------------
|
|
--echo # Tests for Bug#6760 and Bug#12689
|
|
# Number of rows within the intended result set.
|
|
SET @row_count = 4;
|
|
# Parameter within SLEEP function
|
|
SET @sleep_time_per_result_row = 1;
|
|
# Maximum acceptable delay caused by high load on testing box
|
|
SET @max_acceptable_delay = 2;
|
|
# TIMEDIFF = time for query with sleep (mostly the time caused by SLEEP)
|
|
# + time for delays caused by high load on testing box
|
|
# Ensure that at least a reasonable fraction of TIMEDIFF belongs to the SLEEP
|
|
# by appropriate setting of variables.
|
|
# Ensure that any "judging" has a base of minimum three attempts.
|
|
# (Test 2 uses all attempts except the first one.)
|
|
if (!` SELECT (@sleep_time_per_result_row * @row_count - @max_acceptable_delay >
|
|
@sleep_time_per_result_row) AND (@row_count - 1 >= 3)`)
|
|
{
|
|
--echo # Have to abort because of error in plausibility check
|
|
--echo ######################################################
|
|
--vertical_results
|
|
SELECT @sleep_time_per_result_row * @row_count - @max_acceptable_delay >
|
|
@sleep_time_per_result_row AS must_be_1,
|
|
@row_count - 1 >= 3 AS must_be_also_1,
|
|
@sleep_time_per_result_row, @row_count, @max_acceptable_delay;
|
|
exit;
|
|
}
|
|
SET @@global.query_cache_size = 1024 * 64;
|
|
--disable_warnings
|
|
DROP TEMPORARY TABLE IF EXISTS t_history;
|
|
DROP TABLE IF EXISTS t1;
|
|
--enable_warnings
|
|
CREATE TEMPORARY TABLE t_history (attempt SMALLINT,
|
|
start_ts DATETIME, end_ts DATETIME,
|
|
start_cached INTEGER, end_cached INTEGER);
|
|
CREATE TABLE t1 (f1 BIGINT);
|
|
let $num = `SELECT @row_count`;
|
|
while ($num)
|
|
{
|
|
INSERT INTO t1 VALUES (1);
|
|
dec $num;
|
|
}
|
|
|
|
let $loops = 4;
|
|
let $num = $loops;
|
|
while ($num)
|
|
{
|
|
let $Qcache_queries_in_cache =
|
|
query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
|
|
eval
|
|
INSERT INTO t_history
|
|
SET attempt = $loops - $num + 1, start_ts = NOW(),
|
|
start_cached = $Qcache_queries_in_cache;
|
|
SELECT *, SLEEP(@sleep_time_per_result_row) FROM t1;
|
|
#
|
|
# Do not determine Qcache_queries_in_cache before updating end_ts. The SHOW
|
|
# might cost too much time on an overloaded box.
|
|
eval
|
|
UPDATE t_history SET end_ts = NOW()
|
|
WHERE attempt = $loops - $num + 1;
|
|
let $Qcache_queries_in_cache =
|
|
query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
|
|
eval
|
|
UPDATE t_history SET end_cached = $Qcache_queries_in_cache
|
|
WHERE attempt = $loops - $num + 1;
|
|
# DEBUG eval SELECT * FROM t_history WHERE attempt = $loops - $num + 1;
|
|
dec $num;
|
|
}
|
|
|
|
# 1. The majority of queries with SLEEP must need a reasonable time
|
|
# -> SLEEP has an impact on runtime
|
|
# = Replacement for original Bug#6760 test
|
|
# -> total runtime is clear more needed than for one result row needed
|
|
# = Replacement for one of the original Bug#12689 tests
|
|
--echo # Test 1: Does the query with SLEEP need a reasonable time?
|
|
eval SELECT COUNT(*) >= $loops - 1 INTO @aux1 FROM t_history
|
|
WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
|
|
BETWEEN 0 AND @max_acceptable_delay;
|
|
SELECT @aux1 AS "Expect 1";
|
|
#
|
|
# 2. The majority of queries (the first one must be ignored) with SLEEP must
|
|
# need a reasonable time
|
|
# -> If we assume that the result of a cached query will be sent back
|
|
# immediate, without any sleep, than the query with SLEEP cannot be cached
|
|
# (current and intended behaviour for queries with SLEEP).
|
|
# -> It could be also not excluded that the query was cached but the server
|
|
# honoured somehow the SLEEP. Such a behaviour would be also acceptable.
|
|
# = Replacement for one of the original Bug#12689 tests
|
|
--echo # Test 2: Does the query with SLEEP need a reasonable time even in case
|
|
--echo # of the non first execution?
|
|
eval SELECT COUNT(*) >= $loops - 1 - 1 INTO @aux2 FROM t_history
|
|
WHERE TIMEDIFF(end_ts,start_ts) - @sleep_time_per_result_row * @row_count
|
|
BETWEEN 0 AND @max_acceptable_delay
|
|
AND attempt > 1;
|
|
SELECT @aux2 AS "Expect 1";
|
|
#
|
|
# 3. The query with SLEEP should be not cached.
|
|
# -> SHOW STATUS Qcache_queries_in_cache must be not incremented after
|
|
# the execution of the query with SLEEP
|
|
--echo # Test 3: The query with SLEEP must be not cached.
|
|
eval SELECT COUNT(*) = $loops INTO @aux3 FROM t_history
|
|
WHERE end_cached = start_cached;
|
|
SELECT @aux3 AS "Expect 1";
|
|
#
|
|
# Dump the content of t_history if one of the tests failed.
|
|
if (`SELECT @aux1 + @aux2 + @aux3 <> 3`)
|
|
{
|
|
--echo # Some tests failed, dumping the content of t_history
|
|
SELECT * FROM t_history;
|
|
}
|
|
DROP TABLE t1;
|
|
DROP TEMPORARY TABLE t_history;
|
|
SET @@global.query_cache_size = default;
|
|
|
|
#
|
|
# Bug #21466: INET_ATON() returns signed, not unsigned
|
|
#
|
|
|
|
create table t1 select INET_ATON('255.255.0.1') as `a`;
|
|
show create table t1;
|
|
drop table t1;
|
|
|
|
#
|
|
# Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce
|
|
# valid results)
|
|
#
|
|
|
|
--disable_warnings
|
|
drop table if exists table_26093;
|
|
drop function if exists func_26093_a;
|
|
drop function if exists func_26093_b;
|
|
--enable_warnings
|
|
|
|
create table table_26093(a int);
|
|
insert into table_26093 values
|
|
(1), (2), (3), (4), (5),
|
|
(6), (7), (8), (9), (10);
|
|
|
|
delimiter //;
|
|
|
|
create function func_26093_a(x int) returns int
|
|
begin
|
|
set @invoked := @invoked + 1;
|
|
return x;
|
|
end//
|
|
|
|
create function func_26093_b(x int, y int) returns int
|
|
begin
|
|
set @invoked := @invoked + 1;
|
|
return x;
|
|
end//
|
|
|
|
delimiter ;//
|
|
|
|
select avg(a) from table_26093;
|
|
|
|
select benchmark(100, (select avg(a) from table_26093));
|
|
|
|
set @invoked := 0;
|
|
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
|
|
# Returns only 10, since intermediate results are cached.
|
|
select @invoked;
|
|
|
|
set @invoked := 0;
|
|
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
|
|
# Returns 1000, due to rand() preventing caching.
|
|
select @invoked;
|
|
|
|
--error ER_SUBQUERY_NO_1_ROW
|
|
select benchmark(100, (select (a) from table_26093));
|
|
|
|
--error ER_OPERAND_COLUMNS
|
|
select benchmark(100, (select 1, 1));
|
|
|
|
drop table table_26093;
|
|
drop function func_26093_a;
|
|
drop function func_26093_b;
|
|
|
|
#
|
|
# Bug #30832: Assertion + crash with select name_const('test',now());
|
|
#
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST('test', NOW());
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST('test', UPPER('test'));
|
|
|
|
SELECT NAME_CONST('test', NULL);
|
|
SELECT NAME_CONST('test', 1);
|
|
SELECT NAME_CONST('test', -1);
|
|
SELECT NAME_CONST('test', 1.0);
|
|
SELECT NAME_CONST('test', -1.0);
|
|
SELECT NAME_CONST('test', 'test');
|
|
|
|
#
|
|
# Bug #34749: Server crash when using NAME_CONST() with an aggregate function
|
|
#
|
|
|
|
CREATE TABLE t1 (a INT);
|
|
INSERT INTO t1 VALUES (1),(2),(3);
|
|
# NAME_CONST() + aggregate.
|
|
SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
|
|
SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
|
|
# Now, wrap the INT_ITEM in Item_func_neg and watch the pretty explosions
|
|
SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
|
|
SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
|
|
DROP TABLE t1;
|
|
|
|
#
|
|
# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter
|
|
# resolved against a column name of a derived table hangs the client
|
|
#
|
|
|
|
CREATE TABLE t1 (a int);
|
|
INSERT INTO t1 VALUES (5), (2);
|
|
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
|
|
|
|
DROP TABLE t1;
|
|
|
|
|
|
#
|
|
# Bug #32559: connection hangs on query with name_const
|
|
#
|
|
CREATE TABLE t1(a INT);
|
|
INSERT INTO t1 VALUES (), (), ();
|
|
--error ER_WRONG_ARGUMENTS
|
|
SELECT NAME_CONST(a, '1') FROM t1;
|
|
--error ER_WRONG_ARGUMENTS
|
|
SET INSERT_ID= NAME_CONST(a, a);
|
|
DROP TABLE t1;
|
|
|
|
#
|
|
# Bug #31349: ERROR 1062 (23000): Duplicate entry '' for key 'group_key'
|
|
#
|
|
create table t1 (a int not null);
|
|
insert into t1 values (-1), (-2);
|
|
select min(a) from t1 group by inet_ntoa(a);
|
|
drop table t1;
|
|
|
|
#
|
|
# BUG#34289 - Incorrect NAME_CONST substitution in stored procedures breaks
|
|
# replication
|
|
#
|
|
SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs;
|
|
|
|
#
|
|
# Bug #35848: UUID() returns UUIDs with the wrong time
|
|
#
|
|
select @@session.time_zone into @save_tz;
|
|
|
|
# make sure all times are UTC so the DayNr won't differ
|
|
set @@session.time_zone='UTC';
|
|
select uuid() into @my_uuid;
|
|
# if version nibble isn't 1, the following calculations will be rubbish
|
|
select mid(@my_uuid,15,1);
|
|
select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day;
|
|
select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate;
|
|
select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date;
|
|
select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic;
|
|
# these should be identical; date part of UUID should be current date
|
|
select @my_uuid_date - @my_uuid_synthetic;
|
|
|
|
set @@session.time_zone=@save_tz;
|
|
|
|
--echo End of 5.0 tests
|
|
|
|
#
|
|
# Bug #30389: connection_id() always return 0 in embedded server
|
|
#
|
|
|
|
select connection_id() > 0;
|
|
|
|
--echo End of tests
|