Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
89e0944d
Commit
89e0944d
authored
Feb 28, 2024
by
StefanoPetrilli
Committed by
Sergei Golubchik
Sep 16, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-32637 Implement native UUID7 function
parent
8ea4590a
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
549 additions
and
4 deletions
+549
-4
mysql-test/suite/rpl/r/rpl_row_UUIDv7.result
mysql-test/suite/rpl/r/rpl_row_UUIDv7.result
+42
-0
mysql-test/suite/rpl/t/rpl_row_UUIDv7.test
mysql-test/suite/rpl/t/rpl_row_UUIDv7.test
+71
-0
mysys/my_init.c
mysys/my_init.c
+4
-2
mysys/mysys_priv.h
mysys/mysys_priv.h
+2
-1
plugin/type_uuid/item_uuidfunc.h
plugin/type_uuid/item_uuidfunc.h
+13
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.result
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.result
+10
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.test
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.test
+7
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.result
...n/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.result
+44
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.test
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.test
+32
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.result
.../type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.result
+35
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.test
...in/type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.test
+30
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_random.result
.../type_uuid/mysql-test/type_uuid/func_uuidv7_random.result
+15
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_random.test
...in/type_uuid/mysql-test/type_uuid/func_uuidv7_random.test
+18
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_version_revision.result
.../mysql-test/type_uuid/func_uuidv7_version_revision.result
+12
-0
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_version_revision.test
...id/mysql-test/type_uuid/func_uuidv7_version_revision.test
+13
-0
plugin/type_uuid/mysql-test/type_uuid/order.result
plugin/type_uuid/mysql-test/type_uuid/order.result
+18
-0
plugin/type_uuid/mysql-test/type_uuid/order.test
plugin/type_uuid/mysql-test/type_uuid/order.test
+11
-0
plugin/type_uuid/plugin.cc
plugin/type_uuid/plugin.cc
+50
-1
plugin/type_uuid/sql_type_uuid_v7.h
plugin/type_uuid/sql_type_uuid_v7.h
+122
-0
No files found.
mysql-test/suite/rpl/r/rpl_row_UUIDv7.result
0 → 100644
View file @
89e0944d
include/master-slave.inc
[connection master]
#
# MDEV-32637 Implement native UUID7 function
#
connection master;
CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, vchar_column VARCHAR(100), PRIMARY KEY(a)) engine=myisam;
INSERT INTO test.t1 VALUES(1,UUIDv7(),UUIDv7());
create procedure test.p1()
begin
INSERT INTO test.t1 VALUES(2,UUIDv7(),UUIDv7());
INSERT INTO test.t1 VALUES(3,UUIDv7(),UUIDv7());
end|
CALL test.p1();
create function test.fn1(x int)
returns int
begin
insert into t1 values (4+x,UUIDv7(),UUIDv7());
insert into t1 values (5+x,UUIDv7(),UUIDv7());
return 0;
end|
select fn1(0);
fn1(0)
0
create table t2 (a int) engine=myisam;
insert into t2 values(fn1(2));
connection slave;
SHOW CREATE TABLE test.t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`blob_column` longblob DEFAULT NULL,
`vchar_column` varchar(100) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
connection master;
DROP PROCEDURE test.p1;
DROP FUNCTION test.fn1;
DROP TABLE test.t1;
DROP TABLE test.t2;
# End of 11.7 tests
include/rpl_end.inc
mysql-test/suite/rpl/t/rpl_row_UUIDv7.test
0 → 100644
View file @
89e0944d
--
source
include
/
have_binlog_format_row
.
inc
--
source
include
/
master
-
slave
.
inc
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
connection
master
;
# Start the actual test
CREATE
TABLE
test
.
t1
(
a
INT
,
blob_column
LONGBLOB
,
vchar_column
VARCHAR
(
100
),
PRIMARY
KEY
(
a
))
engine
=
myisam
;
INSERT
INTO
test
.
t1
VALUES
(
1
,
UUIDv7
(),
UUIDv7
());
delimiter
|
;
create
procedure
test
.
p1
()
begin
INSERT
INTO
test
.
t1
VALUES
(
2
,
UUIDv7
(),
UUIDv7
());
INSERT
INTO
test
.
t1
VALUES
(
3
,
UUIDv7
(),
UUIDv7
());
end
|
delimiter
;
|
CALL
test
.
p1
();
delimiter
|
;
create
function
test
.
fn1
(
x
int
)
returns
int
begin
insert
into
t1
values
(
4
+
x
,
UUIDv7
(),
UUIDv7
());
insert
into
t1
values
(
5
+
x
,
UUIDv7
(),
UUIDv7
());
return
0
;
end
|
delimiter
;
|
# test both in SELECT and in INSERT
--
disable_ps2_protocol
select
fn1
(
0
);
--
enable_ps2_protocol
create
table
t2
(
a
int
)
engine
=
myisam
;
insert
into
t2
values
(
fn1
(
2
));
sync_slave_with_master
;
SHOW
CREATE
TABLE
test
.
t1
;
# Dump the databases and so we can see if they match
# Another method would be to use SELECT INTO OUTFILE on master,
# then LOAD DATA INFILE in slave, and use a query to compare.
# This would have the advantage that it would not assume
# the system has a 'diff'
--
exec
$MYSQL_DUMP
--
compact
--
order
-
by
-
primary
--
skip
-
extended
-
insert
--
no
-
create
-
info
test
>
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_master
.
sql
--
exec
$MYSQL_DUMP_SLAVE
--
compact
--
order
-
by
-
primary
--
skip
-
extended
-
insert
--
no
-
create
-
info
test
>
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_slave
.
sql
connection
master
;
DROP
PROCEDURE
test
.
p1
;
DROP
FUNCTION
test
.
fn1
;
DROP
TABLE
test
.
t1
;
DROP
TABLE
test
.
t2
;
# Let's compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file
# will be created. You will need to go to the mysql-test dir and diff
# the files your self to see what is not matching :-)
diff_files
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_master
.
sql
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_slave
.
sql
;
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_master
.
sql
;
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
rpl_row_UUIDv7_slave
.
sql
;
--
echo
# End of 11.7 tests
--
source
include
/
rpl_end
.
inc
mysys/my_init.c
View file @
89e0944d
...
...
@@ -471,7 +471,8 @@ PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
key_THR_LOCK_lock
,
key_THR_LOCK_malloc
,
key_THR_LOCK_mutex
,
key_THR_LOCK_myisam
,
key_THR_LOCK_net
,
key_THR_LOCK_open
,
key_THR_LOCK_threads
,
key_TMPDIR_mutex
,
key_THR_LOCK_myisam_mmap
,
key_LOCK_uuid_generator
;
key_TMPDIR_mutex
,
key_THR_LOCK_myisam_mmap
,
key_LOCK_uuid_generator
,
key_LOCK_uuid_v7_generator
;
static
PSI_mutex_info
all_mysys_mutexes
[]
=
{
...
...
@@ -498,7 +499,8 @@ static PSI_mutex_info all_mysys_mutexes[]=
{
&
key_THR_LOCK_threads
,
"THR_LOCK_threads"
,
PSI_FLAG_GLOBAL
},
{
&
key_TMPDIR_mutex
,
"TMPDIR_mutex"
,
PSI_FLAG_GLOBAL
},
{
&
key_THR_LOCK_myisam_mmap
,
"THR_LOCK_myisam_mmap"
,
PSI_FLAG_GLOBAL
},
{
&
key_LOCK_uuid_generator
,
"LOCK_uuid_generator"
,
PSI_FLAG_GLOBAL
}
{
&
key_LOCK_uuid_generator
,
"LOCK_uuid_generator"
,
PSI_FLAG_GLOBAL
},
{
&
key_LOCK_uuid_v7_generator
,
"LOCK_uuid_v7_generator"
,
PSI_FLAG_GLOBAL
}
};
PSI_cond_key
key_COND_timer
,
key_IO_CACHE_SHARE_cond
,
...
...
mysys/mysys_priv.h
View file @
89e0944d
...
...
@@ -48,7 +48,8 @@ extern PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
key_THR_LOCK_lock
,
key_THR_LOCK_malloc
,
key_THR_LOCK_mutex
,
key_THR_LOCK_myisam
,
key_THR_LOCK_net
,
key_THR_LOCK_open
,
key_THR_LOCK_threads
,
key_LOCK_uuid_generator
,
key_TMPDIR_mutex
,
key_THR_LOCK_myisam_mmap
,
key_LOCK_timer
;
key_LOCK_uuid_v7_generator
,
key_TMPDIR_mutex
,
key_THR_LOCK_myisam_mmap
,
key_LOCK_timer
;
extern
PSI_cond_key
key_COND_timer
,
key_IO_CACHE_SHARE_cond
,
key_IO_CACHE_SHARE_cond_writer
,
key_my_thread_var_suspend
,
...
...
plugin/type_uuid/item_uuidfunc.h
View file @
89e0944d
...
...
@@ -20,6 +20,7 @@
#include "item.h"
#include "sql_type_uuid_v1.h"
#include "sql_type_uuid_v4.h"
#include "sql_type_uuid_v7.h"
class
Item_func_sys_guid
:
public
Item_str_func
{
...
...
@@ -102,4 +103,16 @@ class Item_func_uuid_v4: public Item_func_uuid_vx<UUIDv4>
{
return
get_item_copy
<
Item_func_uuid_v4
>
(
thd
,
this
);
}
};
class
Item_func_uuid_v7
:
public
Item_func_uuid_vx
<
UUIDv7
>
{
public:
using
Item_func_uuid_vx
::
Item_func_uuid_vx
;
LEX_CSTRING
func_name_cstring
()
const
override
{
static
LEX_CSTRING
name
=
{
STRING_WITH_LEN
(
"uuidv7"
)
};
return
name
;
}
Item
*
do_get_copy
(
THD
*
thd
)
const
override
{
return
get_item_copy
<
Item_func_uuid_v7
>
(
thd
,
this
);
}
};
#endif // ITEM_UUIDFUNC_INCLUDED
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.result
0 → 100644
View file @
89e0944d
#
# MDEV-33827 UUID() returns a NULL-able result
#
CREATE TABLE t1 AS SELECT UUIDv7();
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`UUIDv7()` uuid NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
plugin/type_uuid/mysql-test/type_uuid/func_uuid_v7.test
0 → 100644
View file @
89e0944d
--
echo
#
--
echo
# MDEV-33827 UUID() returns a NULL-able result
--
echo
#
CREATE
TABLE
t1
AS
SELECT
UUIDv7
();
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.result
0 → 100644
View file @
89e0944d
SET debug_dbug="+d,simulate_uuidv7_my_random_bytes_failure";
#
# Start of 11.7 tests
#
#
# MDEV-32637 Implement native UUID7 function
#
CREATE TABLE t1 (
a int primary key not null,
u UUID DEFAULT UUIDv7(),
unique key(u)
);
INSERT INTO t1(a) SELECT seq FROM seq_1_to_16;
Warnings:
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
Note 1105 UUIDv7 generation failed; using a my_rnd fallback
SELECT COUNT(DISTINCT u) AS distinct_uuid_count FROM t1;
distinct_uuid_count
16
SELECT
u REGEXP '[a-f0-9]{8}-[a-f0-9]{4}-7[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}' AS is_correct_version_and_revision,
COUNT(*)
FROM t1 GROUP BY is_correct_version_and_revision;
is_correct_version_and_revision COUNT(*)
1 16
DROP TABLE t1;
#
# End of 11.7 tests
#
SET debug_dbug="";
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_debug.test
0 → 100644
View file @
89e0944d
--
source
include
/
have_debug
.
inc
SET
debug_dbug
=
"+d,simulate_uuidv7_my_random_bytes_failure"
;
source
include
/
have_sequence
.
inc
;
--
echo
#
--
echo
# Start of 11.7 tests
--
echo
#
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
CREATE
TABLE
t1
(
a
int
primary
key
not
null
,
u
UUID
DEFAULT
UUIDv7
(),
unique
key
(
u
)
);
INSERT
INTO
t1
(
a
)
SELECT
seq
FROM
seq_1_to_16
;
SELECT
COUNT
(
DISTINCT
u
)
AS
distinct_uuid_count
FROM
t1
;
SELECT
u
REGEXP
'[a-f0-9]{8}-[a-f0-9]{4}-7[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}'
AS
is_correct_version_and_revision
,
COUNT
(
*
)
FROM
t1
GROUP
BY
is_correct_version_and_revision
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# End of 11.7 tests
--
echo
#
SET
debug_dbug
=
""
;
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.result
0 → 100644
View file @
89e0944d
#
# Start of 11.7 tests
#
#
# MDEV-32637 Implement native UUID7 function
#
SELECT
'----' AS `----`,
PLUGIN_NAME,
PLUGIN_VERSION,
PLUGIN_STATUS,
PLUGIN_TYPE,
PLUGIN_AUTHOR,
PLUGIN_DESCRIPTION,
PLUGIN_LICENSE,
PLUGIN_MATURITY,
PLUGIN_AUTH_VERSION
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_TYPE='FUNCTION'
AND PLUGIN_NAME IN
('uuidv7')
ORDER BY PLUGIN_NAME;
---- ----
PLUGIN_NAME uuidv7
PLUGIN_VERSION 1.0
PLUGIN_STATUS ACTIVE
PLUGIN_TYPE FUNCTION
PLUGIN_AUTHOR Stefano Petrilli
PLUGIN_DESCRIPTION Function UUIDv7()
PLUGIN_LICENSE GPL
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 1.0
#
# End of 11.7 tests
#
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_plugin.test
0 → 100644
View file @
89e0944d
--
echo
#
--
echo
# Start of 11.7 tests
--
echo
#
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
--
vertical_results
SELECT
'----'
AS
`----`
,
PLUGIN_NAME
,
PLUGIN_VERSION
,
PLUGIN_STATUS
,
PLUGIN_TYPE
,
PLUGIN_AUTHOR
,
PLUGIN_DESCRIPTION
,
PLUGIN_LICENSE
,
PLUGIN_MATURITY
,
PLUGIN_AUTH_VERSION
FROM
INFORMATION_SCHEMA
.
PLUGINS
WHERE
PLUGIN_TYPE
=
'FUNCTION'
AND
PLUGIN_NAME
IN
(
'uuidv7'
)
ORDER
BY
PLUGIN_NAME
;
--
horizontal_results
--
echo
#
--
echo
# End of 11.7 tests
--
echo
#
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_random.result
0 → 100644
View file @
89e0944d
#
# Start of 11.7 tests
#
#
# MDEV-32637 Implement native UUID7 function
#
CREATE TABLE t1 (a int primary key not null, u UUID DEFAULT UUIDv7(), unique key(u));
insert into t1(a) select seq from seq_1_to_100;
select count(distinct u) AS distinct_uuid_count from t1;
distinct_uuid_count
100
drop table t1;
#
# End of 11.7 tests
#
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_random.test
0 → 100644
View file @
89e0944d
source
include
/
have_sequence
.
inc
;
--
echo
#
--
echo
# Start of 11.7 tests
--
echo
#
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
CREATE
TABLE
t1
(
a
int
primary
key
not
null
,
u
UUID
DEFAULT
UUIDv7
(),
unique
key
(
u
));
insert
into
t1
(
a
)
select
seq
from
seq_1_to_100
;
select
count
(
distinct
u
)
AS
distinct_uuid_count
from
t1
;
drop
table
t1
;
--
echo
#
--
echo
# End of 11.7 tests
--
echo
#
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_version_revision.result
0 → 100644
View file @
89e0944d
#
# Start of 11.7 tests
#
#
# MDEV-32637 Implement native UUID7 function
#
SELECT UUIDv7() REGEXP '[a-f0-9]{8}-[a-f0-9]{4}-7[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}' AS is_correct_version_and_revision;
is_correct_version_and_revision
1
#
# End of 11.7 tests
#
plugin/type_uuid/mysql-test/type_uuid/func_uuidv7_version_revision.test
0 → 100644
View file @
89e0944d
--
echo
#
--
echo
# Start of 11.7 tests
--
echo
#
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
SELECT
UUIDv7
()
REGEXP
'[a-f0-9]{8}-[a-f0-9]{4}-7[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}'
AS
is_correct_version_and_revision
;
--
echo
#
--
echo
# End of 11.7 tests
--
echo
#
plugin/type_uuid/mysql-test/type_uuid/order.result
View file @
89e0944d
...
...
@@ -831,3 +831,21 @@ a b a b
13101234-5566-7777-e888-99aabbccddee 31 12701234-5566-6777-e888-99aabbccddee 27
13101234-5566-7777-e888-99aabbccddee 31 12901234-5566-7777-8888-99aabbccddee 29
drop table t1;
#
# MDEV-32637 Implement native UUID7 function
#
CREATE TABLE t1 (a int primary key not null, u UUID DEFAULT UUIDv7(), unique key(u));
insert into t1(a) select seq from seq_1_to_10;
select a from t1 order by u asc;
a
1
2
3
4
5
6
7
8
9
10
drop table t1;
plugin/type_uuid/mysql-test/type_uuid/order.test
View file @
89e0944d
...
...
@@ -60,3 +60,14 @@ drop table t2;
select
*
from
t1
,
t1
t
where
t1
.
b
div
4
in
(
6
,
7
)
and
t
.
b
div
4
in
(
6
,
7
)
and
concat
(
t1
.
a
)
>
concat
(
t
.
a
);
drop
table
t1
;
--
echo
#
--
echo
# MDEV-32637 Implement native UUID7 function
--
echo
#
# Verify that UUIDv7 are time-ordered and unique
CREATE
TABLE
t1
(
a
int
primary
key
not
null
,
u
UUID
DEFAULT
UUIDv7
(),
unique
key
(
u
));
insert
into
t1
(
a
)
select
seq
from
seq_1_to_10
;
select
a
from
t1
order
by
u
asc
;
drop
table
t1
;
plugin/type_uuid/plugin.cc
View file @
89e0944d
...
...
@@ -160,14 +160,36 @@ class Create_func_uuid_v4 : public Create_func_arg0
virtual
~
Create_func_uuid_v4
()
{}
};
uint64
last_uuidv7_timestamp
=
0
;
mysql_mutex_t
LOCK_uuid_v7_generator
;
class
Create_func_uuid_v7
:
public
Create_func_arg0
{
public:
Item
*
create_builder
(
THD
*
thd
)
override
{
DBUG_ENTER
(
"Create_func_uuid_v7::create"
);
thd
->
lex
->
set_stmt_unsafe
(
LEX
::
BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION
);
thd
->
lex
->
uncacheable
(
UNCACHEABLE_RAND
);
DBUG_RETURN
(
new
(
thd
->
mem_root
)
Item_func_uuid_v7
(
thd
));
}
static
Create_func_uuid_v7
s_singleton
;
protected:
Create_func_uuid_v7
()
{}
virtual
~
Create_func_uuid_v7
()
{}
};
Create_func_uuid
Create_func_uuid
::
s_singleton
;
Create_func_sys_guid
Create_func_sys_guid
::
s_singleton
;
Create_func_uuid_v4
Create_func_uuid_v4
::
s_singleton
;
Create_func_uuid_v7
Create_func_uuid_v7
::
s_singleton
;
static
Plugin_function
plugin_descriptor_function_uuid
(
&
Create_func_uuid
::
s_singleton
),
plugin_descriptor_function_sys_guid
(
&
Create_func_sys_guid
::
s_singleton
),
plugin_descriptor_function_uuid_v4
(
&
Create_func_uuid_v4
::
s_singleton
);
plugin_descriptor_function_uuid_v4
(
&
Create_func_uuid_v4
::
s_singleton
),
plugin_descriptor_function_uuid_v7
(
&
Create_func_uuid_v7
::
s_singleton
);
static
constexpr
Name
type_name
=
{
STRING_WITH_LEN
(
"uuid"
)};
...
...
@@ -178,6 +200,18 @@ int uuid_init(void*)
return
0
;
}
int
uuidv7_init
(
void
*
)
{
mysql_mutex_init
(
0
,
&
LOCK_uuid_v7_generator
,
MY_MUTEX_INIT_FAST
);
return
0
;
}
int
uuidv7_terminate
(
void
*
)
{
mysql_mutex_destroy
(
&
LOCK_uuid_v7_generator
);
return
0
;
}
/*************************************************************************/
maria_declare_plugin
(
type_uuid
)
...
...
@@ -240,5 +274,20 @@ maria_declare_plugin(type_uuid)
NULL
,
// System variables
"1.0"
,
// String version representation
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
// Maturity(see include/mysql/plugin.h)*/
},
{
MariaDB_FUNCTION_PLUGIN
,
// the plugin type (see include/mysql/plugin.h)
&
plugin_descriptor_function_uuid_v7
,
// pointer to type-specific plugin descriptor
"uuidv7"
,
// plugin name
"Stefano Petrilli"
,
// plugin author
"Function UUIDv7()"
,
// the plugin description
PLUGIN_LICENSE_GPL
,
// the plugin license (see include/mysql/plugin.h)
uuidv7_init
,
// Pointer to plugin initialization function
uuidv7_terminate
,
// Pointer to plugin deinitialization function
0x0100
,
// Numeric version 0xAABB means AA.BB version
NULL
,
// Status variables
NULL
,
// System variables
"1.0"
,
// String version representation
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
// Maturity(see include/mysql/plugin.h)*/
}
maria_declare_plugin_end
;
plugin/type_uuid/sql_type_uuid_v7.h
0 → 100644
View file @
89e0944d
#ifndef SQL_TYPE_UUID_V7_INCLUDED
#define SQL_TYPE_UUID_V7_INCLUDED
/* Copyright (c) 2024, Stefano Petrilli
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 Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/*
implements Universal Universally Unique Identifier version 7, as described in
RFC 9562.
A UUIDv7 has the following structure:
Field Octet # Note
unix_ts_ms 0-5 Big-endian unsigned number of
Unix epoch timestamp in
milliseconds.
ver 6 The 4 bit version field, set to
0b0100. Occupies bits 48 through 51 of
octet 6.
sub_ms_precision 6-7 Sub millisecond clock precision
encoded to fill all the possible
values in 12 bits.
var 8 The 2 bit variant field, set to 0b10.
Occupies bits 64 and 65 of octet 8.
rand 8-15 CSPRNG 62 bits multiplexed
with the version number.
The structure of an UUIDv7 is: mmmmmmmm-mmmm-Vsss-vrrr-rrrrrrrrrrrr
*/
#include "sql_type_uuid.h"
#include <my_rnd.h>
#include <m_string.h>
#include <myisampack.h>
/* mi_int2store, mi_int6store */
#include <errmsg.h>
extern
uint64
last_uuidv7_timestamp
;
extern
mysql_mutex_t
LOCK_uuid_v7_generator
;
class
UUIDv7
:
public
Type_handler_uuid_new
::
Fbt
{
static
constexpr
uchar
UUID_VERSION
()
{
return
0x70
;
}
static
constexpr
uchar
UUID_VERSION_MASK
()
{
return
0x0F
;
}
static
constexpr
uchar
UUID_VARIANT
()
{
return
0x80
;
}
static
constexpr
uchar
UUID_VARIANT_MASK
()
{
return
0x3F
;
}
static
constexpr
double
MICROSECONDS_TO_12BIT_MAPPING_FACTOR
()
{
return
4.096
;
}
static
void
inject_version_and_variant
(
uchar
*
to
)
{
to
[
6
]
=
((
to
[
6
]
&
UUID_VERSION_MASK
())
|
UUID_VERSION
());
to
[
8
]
=
((
to
[
8
]
&
UUID_VARIANT_MASK
())
|
UUID_VARIANT
());
}
// Construct using a my_rnd()-based fallback method
static
void
construct_fallback
(
char
*
to
)
{
for
(
uint
i
=
0
;
i
<
4
;
i
++
)
int4store
(
&
to
[
i
*
4
],
(
uint32
)
(
my_rnd
(
&
sql_rand
)
*
0xFFFFFFFF
));
}
static
void
construct
(
char
*
to
)
{
bool
error
=
my_random_bytes
((
uchar
*
)
to
+
8
,
8
)
!=
MY_AES_OK
;
DBUG_EXECUTE_IF
(
"simulate_uuidv7_my_random_bytes_failure"
,
error
=
true
;
);
if
(
error
)
// A very unlikely failure happened.
{
push_warning_printf
(
current_thd
,
Sql_condition
::
WARN_LEVEL_NOTE
,
ER_UNKNOWN_ERROR
,
"UUIDv7 generation failed; using a my_rnd fallback"
);
construct_fallback
(
to
);
}
uint64
tv
=
my_hrtime
().
val
;
mysql_mutex_lock
(
&
LOCK_uuid_v7_generator
);
last_uuidv7_timestamp
=
tv
=
MY_MAX
(
last_uuidv7_timestamp
+
1
,
tv
);
mysql_mutex_unlock
(
&
LOCK_uuid_v7_generator
);
mi_int6store
(
to
,
tv
/
1000
);
/**
Map all the possible microseconds values (from 0 to 999) to all the
values that can be represented in 12 bits (from 0 to 4095) as
described in section 6.2, Method 3 of RFC 9562.
*/
mi_int2store
(
to
+
6
,
MICROSECONDS_TO_12BIT_MAPPING_FACTOR
()
*
(
tv
%
1000
));
/*
Let's inject proper version and variant to make it good UUIDv7.
*/
inject_version_and_variant
((
uchar
*
)
to
);
}
public:
UUIDv7
()
{
construct
(
m_buffer
);
}
static
bool
construct_native
(
Native
*
to
)
{
to
->
alloc
(
MY_UUID_SIZE
);
to
->
length
(
MY_UUID_SIZE
);
construct
((
char
*
)
to
->
ptr
());
return
0
;
}
};
#endif // SQL_TYPE_UUID_V7_INCLUDED
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment