mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-25704 Add RANDOM_BYTES function
MySQL 5.6 added the RANDOM_BYTES function. https://dev.mysql.com/doc/refman/5.6/en/encryption-functions.html#function_random-bytes This is needed for compatibility purposes.
This commit is contained in:
committed by
Sergei Golubchik
parent
0fbbf2ee78
commit
3c2b0cac52
@ -5265,3 +5265,59 @@ f
|
|||||||
#
|
#
|
||||||
# End of 10.4 tests
|
# End of 10.4 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# MDEV-25704 Function random_bytes
|
||||||
|
#
|
||||||
|
create table t1 as select random_bytes(100);
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`random_bytes(100)` varbinary(100) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
# The sequence starts at 17 so that the probability of test failure is small enough (about 2^(-136))
|
||||||
|
select count(*) from seq_17_to_1024 where random_bytes(seq) <=> random_bytes(seq);
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select (count(*) = 1024) from seq_1_to_1024 where length(random_bytes(seq)) = seq;
|
||||||
|
(count(*) = 1024)
|
||||||
|
1
|
||||||
|
#
|
||||||
|
# Test NULL output for NULL input
|
||||||
|
#
|
||||||
|
SELECT random_bytes(NULL);
|
||||||
|
random_bytes(NULL)
|
||||||
|
NULL
|
||||||
|
#
|
||||||
|
# Test For values outside range from 1 to 1024, an error occurs
|
||||||
|
#
|
||||||
|
SELECT random_bytes(0);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(0)'
|
||||||
|
SELECT random_bytes(-1);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(-1)'
|
||||||
|
SELECT random_bytes(-100);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(-100)'
|
||||||
|
SELECT random_bytes(-26);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(-26)'
|
||||||
|
SELECT random_bytes(-132);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(-132)'
|
||||||
|
SELECT random_bytes(1025);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(1025)'
|
||||||
|
SELECT random_bytes(11111);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(11111)'
|
||||||
|
SELECT random_bytes(2056);
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes(2056)'
|
||||||
|
#
|
||||||
|
# Test For invalid argument, an error occurs
|
||||||
|
#
|
||||||
|
SELECT random_bytes('s');
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes('s')'
|
||||||
|
SELECT random_bytes('r');
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes('r')'
|
||||||
|
SELECT random_bytes('res');
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes('res')'
|
||||||
|
SELECT random_bytes('test');
|
||||||
|
ERROR 22003: length value is out of range in 'random_bytes('test')'
|
||||||
|
#
|
||||||
|
# End of 10.10 tests
|
||||||
|
#
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Description
|
# Description
|
||||||
# -----------
|
# -----------
|
||||||
# Testing string functions
|
# Testing string functions
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1,t2;
|
drop table if exists t1,t2;
|
||||||
@ -2193,3 +2194,59 @@ SELECT GROUP_CONCAT( UpdateXML( '<a>new year</a>', '/a', '2019-01-01 00:00:00' )
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25704 Function random_bytes
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1 as select random_bytes(100);
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo # The sequence starts at 17 so that the probability of test failure is small enough (about 2^(-136))
|
||||||
|
select count(*) from seq_17_to_1024 where random_bytes(seq) <=> random_bytes(seq);
|
||||||
|
|
||||||
|
select (count(*) = 1024) from seq_1_to_1024 where length(random_bytes(seq)) = seq;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test NULL output for NULL input
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT random_bytes(NULL);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test For values outside range from 1 to 1024, an error occurs
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(0);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(-1);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(-100);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(-26);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(-132);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(1025);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(11111);
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes(2056);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test For invalid argument, an error occurs
|
||||||
|
--echo #
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes('s');
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes('r');
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes('res');
|
||||||
|
--error 1690
|
||||||
|
SELECT random_bytes('test');
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.10 tests
|
||||||
|
--echo #
|
||||||
|
@ -2609,6 +2609,9 @@ INSERT INTO t1 VALUES (VERSION());
|
|||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave
|
||||||
INSERT INTO t1 VALUES (RAND());
|
INSERT INTO t1 VALUES (RAND());
|
||||||
|
INSERT INTO t1 VALUES (RANDOM_BYTES(1000));
|
||||||
|
Warnings:
|
||||||
|
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave
|
||||||
DELETE FROM t1;
|
DELETE FROM t1;
|
||||||
SET TIME_ZONE= '+03:00';
|
SET TIME_ZONE= '+03:00';
|
||||||
SET TIMESTAMP=1000000;
|
SET TIMESTAMP=1000000;
|
||||||
|
@ -651,7 +651,7 @@ DROP TABLE t1,t2,t3;
|
|||||||
|
|
||||||
#
|
#
|
||||||
# BUG#47995: Mark user functions as unsafe
|
# BUG#47995: Mark user functions as unsafe
|
||||||
# BUG#49222: Mare RAND() unsafe
|
# BUG#49222: Mark RAND() unsafe
|
||||||
#
|
#
|
||||||
# Test that the system functions that are supposed to be marked unsafe
|
# Test that the system functions that are supposed to be marked unsafe
|
||||||
# generate a warning. Each INSERT statement below should generate a
|
# generate a warning. Each INSERT statement below should generate a
|
||||||
@ -678,6 +678,7 @@ INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
|
|||||||
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
|
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
|
||||||
INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995
|
INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995
|
||||||
INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222
|
INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222
|
||||||
|
INSERT INTO t1 VALUES (RANDOM_BYTES(1000)); #marked unsafe in MDEV-25704
|
||||||
DELETE FROM t1;
|
DELETE FROM t1;
|
||||||
|
|
||||||
# Since we replicate the TIMESTAMP variable, functions affected by the
|
# Since we replicate the TIMESTAMP variable, functions affected by the
|
||||||
|
@ -1873,6 +1873,19 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Create_func_random_bytes : public Create_func_arg1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Item *create_1_arg(THD *thd, Item *arg1);
|
||||||
|
|
||||||
|
static Create_func_random_bytes s_singleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Create_func_random_bytes() {}
|
||||||
|
virtual ~Create_func_random_bytes() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Create_func_release_all_locks : public Create_func_arg0
|
class Create_func_release_all_locks : public Create_func_arg0
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -4985,6 +4998,15 @@ Create_func_rand::create_native(THD *thd, const LEX_CSTRING *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Create_func_random_bytes Create_func_random_bytes::s_singleton;
|
||||||
|
|
||||||
|
Item *Create_func_random_bytes::create_1_arg(THD *thd, Item *arg1)
|
||||||
|
{
|
||||||
|
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
|
||||||
|
return new (thd->mem_root) Item_func_random_bytes(thd, arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_func_release_all_locks Create_func_release_all_locks::s_singleton;
|
Create_func_release_all_locks Create_func_release_all_locks::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
@ -5804,6 +5826,7 @@ Native_func_registry func_array[] =
|
|||||||
{ { STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)},
|
{ { STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)},
|
||||||
{ { STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)},
|
{ { STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)},
|
||||||
{ { STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)},
|
{ { STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)},
|
||||||
|
{ { STRING_WITH_LEN("RANDOM_BYTES")}, BUILDER(Create_func_random_bytes)},
|
||||||
{ { STRING_WITH_LEN("REGEXP_INSTR") }, BUILDER(Create_func_regexp_instr)},
|
{ { STRING_WITH_LEN("REGEXP_INSTR") }, BUILDER(Create_func_regexp_instr)},
|
||||||
{ { STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace)},
|
{ { STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace)},
|
||||||
{ { STRING_WITH_LEN("REGEXP_SUBSTR") }, BUILDER(Create_func_regexp_substr)},
|
{ { STRING_WITH_LEN("REGEXP_SUBSTR") }, BUILDER(Create_func_regexp_substr)},
|
||||||
|
@ -1474,6 +1474,72 @@ String *Item_func_sformat::val_str(String *res)
|
|||||||
return null_value ? NULL : res;
|
return null_value ? NULL : res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include"my_global.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
bool Item_func_random_bytes::fix_length_and_dec(THD *thd)
|
||||||
|
{
|
||||||
|
used_tables_cache|= RAND_TABLE_BIT;
|
||||||
|
if (args[0]->can_eval_in_optimize())
|
||||||
|
{
|
||||||
|
max_length= MY_MIN((int32) args[0]->val_int(), MAX_BLOB_WIDTH);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
max_length= MAX_BLOB_WIDTH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_random_bytes::update_used_tables()
|
||||||
|
{
|
||||||
|
Item_str_func::update_used_tables();
|
||||||
|
used_tables_cache|= RAND_TABLE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String *Item_func_random_bytes::val_str(String *str)
|
||||||
|
{
|
||||||
|
longlong count= args[0]->val_int();
|
||||||
|
|
||||||
|
if (args[0]->null_value)
|
||||||
|
goto err;
|
||||||
|
null_value= 0;
|
||||||
|
|
||||||
|
if (count < 1 || count > 1024)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
String msg(buf, sizeof(buf), system_charset_info);
|
||||||
|
msg.length(0);
|
||||||
|
print(&msg, QT_NO_DATA_EXPANSION);
|
||||||
|
my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "length", msg.c_ptr_safe());
|
||||||
|
return make_empty_result(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str->alloc((uint) count))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
str->length(count);
|
||||||
|
if (!RAND_bytes((unsigned char *) str->ptr(), (int32) count))
|
||||||
|
{
|
||||||
|
ulong ssl_err;
|
||||||
|
while ((ssl_err= ERR_get_error()))
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
ERR_error_string_n(ssl_err, buf, sizeof(buf));
|
||||||
|
sql_print_warning("SSL error: %s", buf);
|
||||||
|
}
|
||||||
|
return make_empty_result(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
|
||||||
|
err:
|
||||||
|
null_value= 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
bool Item_func_regexp_replace::fix_length_and_dec(THD *thd)
|
bool Item_func_regexp_replace::fix_length_and_dec(THD *thd)
|
||||||
{
|
{
|
||||||
|
@ -384,6 +384,26 @@ public:
|
|||||||
{ return get_item_copy<Item_func_concat_ws>(thd, this); }
|
{ return get_item_copy<Item_func_concat_ws>(thd, this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Item_func_random_bytes : public Item_str_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_func_random_bytes(THD *thd, Item *arg1) : Item_str_func(thd, arg1) {}
|
||||||
|
bool fix_length_and_dec(THD *thd) override;
|
||||||
|
void update_used_tables() override;
|
||||||
|
String *val_str(String *) override;
|
||||||
|
LEX_CSTRING func_name_cstring() const override
|
||||||
|
{
|
||||||
|
static LEX_CSTRING name= {STRING_WITH_LEN("random_bytes")};
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
Item *get_copy(THD *thd) override
|
||||||
|
{
|
||||||
|
return get_item_copy<Item_func_random_bytes>(thd, this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item_func_reverse :public Item_str_func
|
class Item_func_reverse :public Item_str_func
|
||||||
{
|
{
|
||||||
String tmp_value;
|
String tmp_value;
|
||||||
|
Reference in New Issue
Block a user